Changeset 123:f8fbc6efbe8c

Show
Ignore:
Timestamp:
04/26/08 01:24:06 (2 years ago)
Author:
mdoison@…
Parents:
122:4a3bae9504ee (diff), 119:0fc9a5919e03 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Branch:
mergetrem
Message:

merge head with tremulous r1040

Files:
1 removed
51 modified

Legend:

Unmodified
Added
Removed
  • Makefile

    r119 r123  
    199199  endif 
    200200 
    201   OPTIMIZE = -O3 -ffast-math -funroll-loops -fomit-frame-pointer 
     201  OPTIMIZE = -O2 -funroll-loops -fomit-frame-pointer 
    202202 
    203203  ifeq ($(ARCH),x86_64) 
    204     OPTIMIZE = -O3 -fomit-frame-pointer -ffast-math -funroll-loops \ 
     204    OPTIMIZE = -O2 -fomit-frame-pointer -funroll-loops \ 
    205205      -falign-loops=2 -falign-jumps=2 -falign-functions=2 \ 
    206206      -fstrength-reduce 
     
    209209  else 
    210210  ifeq ($(ARCH),x86) 
    211     OPTIMIZE = -O3 -march=i586 -fomit-frame-pointer -ffast-math \ 
     211    OPTIMIZE = -O2 -march=i586 -fomit-frame-pointer \ 
    212212      -funroll-loops -falign-loops=2 -falign-jumps=2 \ 
    213213      -falign-functions=2 -fstrength-reduce 
     
    325325 
    326326  ifeq ($(ARCH),ppc) 
    327     OPTIMIZE += -faltivec -O3 
     327    OPTIMIZE += -faltivec -O2 
    328328  endif 
    329329  ifeq ($(ARCH),x86) 
     
    375375    $(LIBSDIR)/macosx/libSDL-1.2.0.dylib 
    376376 
    377   OPTIMIZE += -ffast-math -falign-loops=16 
     377  OPTIMIZE += -falign-loops=16 
    378378 
    379379  ifneq ($(HAVE_VM_COMPILED),true) 
     
    430430  endif 
    431431 
    432   OPTIMIZE = -O3 -march=i586 -fno-omit-frame-pointer -ffast-math \ 
     432  OPTIMIZE = -O2 -march=i586 -fno-omit-frame-pointer \ 
    433433    -falign-loops=2 -funroll-loops -falign-jumps=2 -falign-functions=2 \ 
    434434    -fstrength-reduce 
     
    502502  ifeq ($(ARCH),axp) 
    503503    BASE_CFLAGS += -DNO_VM_COMPILED 
    504     RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O3 -ffast-math -funroll-loops \ 
     504    RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O2 -funroll-loops \ 
    505505      -fomit-frame-pointer -fexpensive-optimizations 
    506506  else 
    507507  ifeq ($(ARCH),x86) 
    508     RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O3 -mtune=pentiumpro \ 
    509       -march=pentium -fomit-frame-pointer -pipe -ffast-math \ 
     508    RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O2 -mtune=pentiumpro \ 
     509      -march=pentium -fomit-frame-pointer -pipe \ 
    510510      -falign-loops=2 -falign-jumps=2 -falign-functions=2 \ 
    511511      -funroll-loops -fstrength-reduce 
     
    639639  BASE_CFLAGS=-Dstricmp=strcasecmp -Xcpluscomm -woff 1185 -mips3 \ 
    640640    -nostdinc -I. -I$(ROOT)/usr/include -DNO_VM_COMPILED 
    641   RELEASE_CFLAGS=$(BASE_CFLAGS) -O3 
     641  RELEASE_CFLAGS=$(BASE_CFLAGS) -O2 
    642642  DEBUG_CFLAGS=$(BASE_CFLAGS) -g 
    643643 
     
    678678    -pipe -DUSE_ICON $(shell sdl-config --cflags) 
    679679 
    680   OPTIMIZE = -O3 -ffast-math -funroll-loops 
     680  OPTIMIZE = -O2 -funroll-loops 
    681681 
    682682  ifeq ($(ARCH),sparc) 
    683     OPTIMIZE = -O3 -ffast-math -falign-loops=2 \ 
     683    OPTIMIZE = -O2 -falign-loops=2 \ 
    684684      -falign-jumps=2 -falign-functions=2 -fstrength-reduce \ 
    685685      -mtune=ultrasparc -mv8plus -mno-faster-structs \ 
     
    687687  else 
    688688  ifeq ($(ARCH),x86) 
    689     OPTIMIZE = -O3 -march=i586 -fomit-frame-pointer -ffast-math \ 
     689    OPTIMIZE = -O2 -march=i586 -fomit-frame-pointer \ 
    690690      -funroll-loops -falign-loops=2 -falign-jumps=2 \ 
    691691      -falign-functions=2 -fstrength-reduce 
     
    723723  BASE_CFLAGS=-DNO_VM_COMPILED 
    724724  DEBUG_CFLAGS=$(BASE_CFLAGS) -g 
    725   RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O3 
     725  RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O2 
    726726 
    727727  SHLIBEXT=so 
  • Makefile

    r122 r123  
    3939export PLATFORM 
    4040 
     41ifeq ($(COMPILE_ARCH),powerpc) 
     42  COMPILE_ARCH=ppc 
     43endif 
     44 
    4145ifndef ARCH 
    4246ARCH=$(COMPILE_ARCH) 
    43 endif 
    44  
    45 ifeq ($(ARCH),powerpc) 
    46   ARCH=ppc 
    4747endif 
    4848export ARCH 
     
    254254    BASE_CFLAGS += -m32 
    255255    LDFLAGS+=-m32 
     256  else 
     257  ifeq ($(ARCH),ppc64) 
     258    BASE_CFLAGS += -m64 
     259    LDFLAGS += -m64 
     260  endif 
    256261  endif 
    257262 
     
    357362  endif 
    358363 
    359   BASE_CFLAGS += -D_THREAD_SAFE=1 -I$(SDLHDIR)/include 
     364  BASE_CFLAGS += -D_THREAD_SAFE=1 
     365 
     366  ifeq ($(USE_LOCAL_HEADERS),1) 
     367    BASE_CFLAGS += -I$(SDLHDIR)/include 
     368  endif 
     369 
    360370  # We copy sdlmain before ranlib'ing it so that subversion doesn't think 
    361371  #  the file has been modified by each build. 
     
    399409 
    400410  BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \ 
    401     -DUSE_ICON -I$(SDLHDIR)/include 
     411    -DUSE_ICON 
     412 
     413  ifeq ($(USE_LOCAL_HEADERS),1) 
     414    BASE_CFLAGS += -I$(SDLHDIR)/include 
     415  endif 
    402416 
    403417  ifeq ($(USE_OPENAL),1) 
     
    528542 
    529543else # ifeq freebsd 
     544 
     545############################################################################# 
     546# SETUP AND BUILD -- OPENBSD 
     547############################################################################# 
     548 
     549ifeq ($(PLATFORM),openbsd) 
     550 
     551  #default to i386, no tests done on anything else 
     552  ARCH=i386 
     553 
     554 
     555  BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \ 
     556    -DUSE_ICON $(shell sdl-config --cflags) 
     557 
     558  ifeq ($(USE_OPENAL),1) 
     559    BASE_CFLAGS += -DUSE_OPENAL 
     560    ifeq ($(USE_OPENAL_DLOPEN),1) 
     561      BASE_CFLAGS += -DUSE_OPENAL_DLOPEN 
     562    endif 
     563  endif 
     564 
     565  ifeq ($(USE_CODEC_VORBIS),1) 
     566    BASE_CFLAGS += -DUSE_CODEC_VORBIS 
     567  endif 
     568 
     569  BASE_CFLAGS += -DNO_VM_COMPILED -I/usr/X11R6/include -I/usr/local/include 
     570  RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O3 \ 
     571    -march=pentium -fomit-frame-pointer -pipe -ffast-math \ 
     572    -falign-loops=2 -falign-jumps=2 -falign-functions=2 \ 
     573    -funroll-loops -fstrength-reduce 
     574  HAVE_VM_COMPILED=false 
     575 
     576  DEBUG_CFLAGS=$(BASE_CFLAGS) -g 
     577 
     578  SHLIBEXT=so 
     579  SHLIBCFLAGS=-fPIC 
     580  SHLIBLDFLAGS=-shared $(LDFLAGS) 
     581 
     582  THREAD_LDFLAGS=-lpthread 
     583  LDFLAGS=-lm 
     584 
     585  CLIENT_LDFLAGS = 
     586 
     587  CLIENT_LDFLAGS += $(shell sdl-config --libs) -lGL 
     588 
     589  ifeq ($(USE_OPENAL),1) 
     590    ifneq ($(USE_OPENAL_DLOPEN),1) 
     591      CLIENT_LDFLAGS += $(THREAD_LDFLAGS) -lopenal 
     592    endif 
     593  endif 
     594 
     595  ifeq ($(USE_CODEC_VORBIS),1) 
     596    CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg 
     597  endif 
     598 
     599 
     600else # ifeq openbsd 
    530601 
    531602############################################################################# 
     
    662733endif #mingw32 
    663734endif #FreeBSD 
     735endif #OpenBSD 
    664736endif #NetBSD 
    665737endif #IRIX 
     
    831903############################################################################# 
    832904 
    833 TOOLS_CFLAGS = -O2 -Wall -fno-strict-aliasing -MMD \ 
     905TOOLS_OPTIMIZE = -g -O2 -Wall -fno-strict-aliasing 
     906TOOLS_CFLAGS = $(TOOLS_OPTIMIZE) \ 
    834907               -DTEMPDIR=\"$(TEMPDIR)\" -DSYSTEM=\"\" \ 
    835908               -I$(Q3LCCSRCDIR) \ 
    836909               -I$(LBURGDIR) 
    837910TOOLS_LDFLAGS = 
     911 
     912ifeq ($(GENERATE_DEPENDENCIES),1) 
     913        TOOLS_CFLAGS += -MMD 
     914endif 
    838915 
    839916define DO_TOOLS_CC 
     
    13541431  $(B)/base/ui/ui_main.o \ 
    13551432  $(B)/base/ui/ui_atoms.o \ 
    1356   $(B)/base/ui/ui_players.o \ 
    13571433  $(B)/base/ui/ui_shared.o \ 
    13581434  $(B)/base/ui/ui_gameinfo.o \ 
  • src/cgame/cg_draw.c

    r119 r123  
    628628  int           iconsize, numBarbs, i; 
    629629 
    630   numBarbs = ps->ammo; 
     630  BG_UnpackAmmoArray( ps->weapon, ps->ammo, ps->powerups, &numBarbs, NULL ); 
    631631 
    632632  if( height > width ) 
     
    703703 
    704704      default: 
    705         value = ps->ammo; 
     705                BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, &value, NULL ); 
    706706        break; 
    707707    } 
     
    862862 
    863863      default: 
    864         value = ps->clips; 
     864                BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, NULL, &value ); 
    865865 
    866866        if( value > -1 ) 
     
    11071107    case CG_PLAYER_AMMO_VALUE: 
    11081108      if( cent->currentState.weapon ) 
    1109         return ps->ammo; 
     1109      { 
     1110        int value; 
     1111 
     1112        BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, 
     1113          &value, NULL ); 
     1114 
     1115        return value; 
     1116      } 
    11101117      break; 
    11111118    case CG_PLAYER_CLIPS_VALUE: 
    11121119      if( cent->currentState.weapon ) 
    1113         return ps->clips; 
     1120      if( cent->currentState.weapon ) 
     1121      { 
     1122        int value; 
     1123 
     1124        BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, 
     1125          NULL, &value ); 
     1126 
     1127        return value; 
     1128      } 
    11141129      break; 
    11151130    case CG_PLAYER_HEALTH: 
     
    19021917void CG_DrawWeaponIcon( rectDef_t *rect, vec4_t color ) 
    19031918{ 
    1904   int           maxAmmo; 
     1919  int           ammo, clips, maxAmmo; 
    19051920  centity_t     *cent; 
    19061921  playerState_t *ps; 
     
    19091924  ps = &cg.snap->ps; 
    19101925 
     1926  BG_UnpackAmmoArray( cent->currentState.weapon, ps->ammo, ps->powerups, &ammo, &clips ); 
    19111927  BG_FindAmmoForWeapon( cent->currentState.weapon, &maxAmmo, NULL ); 
    19121928 
     
    19201936  CG_RegisterWeapon( cent->currentState.weapon ); 
    19211937 
    1922   if( ps->clips == 0 && !BG_FindInfinteAmmoForWeapon( cent->currentState.weapon ) ) 
    1923   { 
    1924     float ammoPercent = (float)ps->ammo / (float)maxAmmo; 
     1938  if( clips == 0 && !BG_FindInfinteAmmoForWeapon( cent->currentState.weapon ) ) 
     1939  { 
     1940    float ammoPercent = (float)ammo / (float)maxAmmo; 
    19251941 
    19261942    if( ammoPercent < 0.33f ) 
  • src/cgame/cg_draw.c

    r122 r123  
    2929#include "../ui/ui_shared.h" 
    3030 
    31 // used for scoreboard 
    32 extern    displayContextDef_t cgDC; 
    3331menuDef_t *menuScoreboard = NULL; 
    3432 
     
    3836int   numSortedTeamPlayers; 
    3937 
    40 //TA UI 
    41 int CG_Text_Width( const char *text, float scale, int limit ) 
    42 { 
    43   int         count,len; 
    44   float       out; 
    45   glyphInfo_t *glyph; 
    46   float       useScale; 
    47 // FIXME: see ui_main.c, same problem 
    48 //  const unsigned char *s = text; 
    49   const char  *s = text; 
    50   fontInfo_t  *font = &cgDC.Assets.textFont; 
    51  
    52   if( scale <= cg_smallFont.value ) 
    53     font = &cgDC.Assets.smallFont; 
    54   else if( scale > cg_bigFont.value ) 
    55     font = &cgDC.Assets.bigFont; 
    56  
    57   useScale = scale * font->glyphScale; 
    58   out = 0; 
    59  
    60   if( text ) 
    61   { 
    62     len = strlen( text ); 
    63     if( limit > 0 && len > limit ) 
    64       len = limit; 
    65  
    66     count = 0; 
    67     while( s && *s && count < len ) 
    68     { 
    69       if( Q_IsColorString( s ) ) 
    70       { 
    71         s += 2; 
    72         continue; 
    73       } 
    74       else 
    75       { 
    76         glyph = &font->glyphs[ (int)*s ]; 
    77         out += glyph->xSkip; 
    78         s++; 
    79         count++; 
    80       } 
    81     } 
    82   } 
    83  
    84   return out * useScale; 
    85 } 
    86  
    87 int CG_Text_Height( const char *text, float scale, int limit ) 
    88 { 
    89   int         len, count; 
    90   float       max; 
    91   glyphInfo_t *glyph; 
    92   float       useScale; 
    93   const char  *s = text; 
    94   fontInfo_t  *font = &cgDC.Assets.textFont; 
    95  
    96   if( scale <= cg_smallFont.value ) 
    97     font = &cgDC.Assets.smallFont; 
    98   else if( scale > cg_bigFont.value ) 
    99     font = &cgDC.Assets.bigFont; 
    100  
    101   useScale = scale * font->glyphScale; 
    102   max = 0; 
    103  
    104   if( text ) 
    105   { 
    106     len = strlen( text ); 
    107     if( limit > 0 && len > limit ) 
    108       len = limit; 
    109  
    110     count = 0; 
    111     while( s && *s && count < len ) 
    112     { 
    113       if( Q_IsColorString( s ) ) 
    114       { 
    115         s += 2; 
    116         continue; 
    117       } 
    118       else 
    119       { 
    120         glyph = &font->glyphs[ (int)*s ]; 
    121         if( max < glyph->height ) 
    122           max = glyph->height; 
    123  
    124         s++; 
    125         count++; 
    126       } 
    127     } 
    128   } 
    129  
    130   return max * useScale; 
    131 } 
    132  
    133 void CG_Text_PaintChar( float x, float y, float width, float height, float scale, 
    134                         float s, float t, float s2, float t2, qhandle_t hShader ) 
    135 { 
    136   float w, h; 
    137   w = width * scale; 
    138   h = height * scale; 
    139   CG_AdjustFrom640( &x, &y, &w, &h ); 
    140   trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader ); 
    141 } 
    142  
    143 void CG_Text_Paint( float x, float y, float scale, vec4_t color, const char *text, 
    144                     float adjust, int limit, int style ) 
    145 { 
    146   int         len, count; 
    147   vec4_t      newColor; 
    148   glyphInfo_t *glyph; 
    149   float       useScale; 
    150   fontInfo_t  *font = &cgDC.Assets.textFont; 
    151  
    152   if( scale <= cg_smallFont.value ) 
    153     font = &cgDC.Assets.smallFont; 
    154   else if( scale > cg_bigFont.value ) 
    155     font = &cgDC.Assets.bigFont; 
    156  
    157   useScale = scale * font->glyphScale; 
    158   if( text ) 
    159   { 
    160  
    161     const char *s = text; 
    162  
    163     trap_R_SetColor( color ); 
    164     memcpy( &newColor[ 0 ], &color[ 0 ], sizeof( vec4_t ) ); 
    165     len = strlen( text ); 
    166  
    167     if( limit > 0 && len > limit ) 
    168       len = limit; 
    169  
    170     count = 0; 
    171     while( s && *s && count < len ) 
    172     { 
    173       glyph = &font->glyphs[ (int)*s ]; 
    174  
    175       if( Q_IsColorString( s ) ) 
    176       { 
    177         memcpy( newColor, g_color_table[ ColorIndex( *( s + 1 ) ) ], sizeof( newColor ) ); 
    178         newColor[ 3 ] = color[ 3 ]; 
    179         trap_R_SetColor( newColor ); 
    180         s += 2; 
    181         continue; 
    182       } 
    183       else 
    184       { 
    185         float yadj = useScale * glyph->top; 
    186         if( style == ITEM_TEXTSTYLE_SHADOWED || 
    187             style == ITEM_TEXTSTYLE_SHADOWEDMORE ) 
    188         { 
    189           int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2; 
    190           colorBlack[ 3 ] = newColor[ 3 ]; 
    191           trap_R_SetColor( colorBlack ); 
    192           CG_Text_PaintChar( x + ofs, y - yadj + ofs, 
    193                              glyph->imageWidth, 
    194                              glyph->imageHeight, 
    195                              useScale, 
    196                              glyph->s, 
    197                              glyph->t, 
    198                              glyph->s2, 
    199                              glyph->t2, 
    200                              glyph->glyph ); 
    201  
    202           colorBlack[ 3 ] = 1.0; 
    203           trap_R_SetColor( newColor ); 
    204         } 
    205         else if( style == ITEM_TEXTSTYLE_NEON ) 
    206         { 
    207           vec4_t glow, outer, inner, white; 
    208  
    209           glow[ 0 ] = newColor[ 0 ] * 0.5; 
    210           glow[ 1 ] = newColor[ 1 ] * 0.5; 
    211           glow[ 2 ] = newColor[ 2 ] * 0.5; 
    212           glow[ 3 ] = newColor[ 3 ] * 0.2; 
    213  
    214           outer[ 0 ] = newColor[ 0 ]; 
    215           outer[ 1 ] = newColor[ 1 ]; 
    216           outer[ 2 ] = newColor[ 2 ]; 
    217           outer[ 3 ] = newColor[ 3 ]; 
    218  
    219           inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5; 
    220           inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5; 
    221           inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5; 
    222           inner[ 3 ] = newColor[ 3 ]; 
    223  
    224           white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f; 
    225  
    226           trap_R_SetColor( glow ); 
    227           CG_Text_PaintChar(  x - 3, y - yadj - 3, 
    228                               glyph->imageWidth + 6, 
    229                               glyph->imageHeight + 6, 
    230                               useScale, 
    231                               glyph->s, 
    232                               glyph->t, 
    233                               glyph->s2, 
    234                               glyph->t2, 
    235                               glyph->glyph ); 
    236  
    237           trap_R_SetColor( outer ); 
    238           CG_Text_PaintChar(  x - 1, y - yadj - 1, 
    239                               glyph->imageWidth + 2, 
    240                               glyph->imageHeight + 2, 
    241                               useScale, 
    242                               glyph->s, 
    243                               glyph->t, 
    244                               glyph->s2, 
    245                               glyph->t2, 
    246                               glyph->glyph ); 
    247  
    248           trap_R_SetColor( inner ); 
    249           CG_Text_PaintChar(  x - 0.5, y - yadj - 0.5, 
    250                               glyph->imageWidth + 1, 
    251                               glyph->imageHeight + 1, 
    252                               useScale, 
    253                               glyph->s, 
    254                               glyph->t, 
    255                               glyph->s2, 
    256                               glyph->t2, 
    257                               glyph->glyph ); 
    258  
    259           trap_R_SetColor( white ); 
    260         } 
    261  
    262  
    263         CG_Text_PaintChar( x, y - yadj, 
    264                            glyph->imageWidth, 
    265                            glyph->imageHeight, 
    266                            useScale, 
    267                            glyph->s, 
    268                            glyph->t, 
    269                            glyph->s2, 
    270                            glyph->t2, 
    271                            glyph->glyph ); 
    272  
    273         x += ( glyph->xSkip * useScale ) + adjust; 
    274         s++; 
    275         count++; 
    276       } 
    277     } 
    278  
    279     trap_R_SetColor( NULL ); 
    280   } 
     38static void CG_AlignText( rectDef_t *rect, const char *text, float scale, 
     39                          float w, float h, 
     40                          int align, int valign, 
     41                          float *x, float *y ) 
     42{ 
     43  float tx, ty; 
     44 
     45  if( scale > 0.0f ) 
     46  { 
     47    w = UI_Text_Width( text, scale, 0 ); 
     48    h = UI_Text_Height( text, scale, 0 ); 
     49  } 
     50 
     51  switch( align ) 
     52  { 
     53    default: 
     54    case ALIGN_LEFT: 
     55      tx = 0.0f; 
     56      break; 
     57 
     58    case ALIGN_RIGHT: 
     59      tx = rect->w - w; 
     60      break; 
     61 
     62    case ALIGN_CENTER: 
     63      tx = ( rect->w - w ) / 2.0f; 
     64      break; 
     65  } 
     66 
     67  switch( valign ) 
     68  { 
     69    default: 
     70    case VALIGN_BOTTOM: 
     71      ty = rect->h; 
     72      break; 
     73 
     74    case VALIGN_TOP: 
     75      ty = h; 
     76      break; 
     77 
     78    case VALIGN_CENTER: 
     79      ty = h + ( ( rect->h - h ) / 2.0f ); 
     80      break; 
     81  } 
     82 
     83  if( x ) 
     84    *x = rect->x + tx; 
     85 
     86  if( y ) 
     87    *y = rect->y + ty; 
    28188} 
    28289 
     
    299106 
    300107  if( !( charHeight = ch ) ) 
    301     charWidth = CHAR_HEIGHT; 
     108    charHeight = CHAR_HEIGHT; 
    302109 
    303110  if( width < 1 ) 
     
    336143  orgL = l; 
    337144 
    338   x += 2; 
     145  x += ( 2.0f * cgDC.aspectScale ); 
    339146 
    340147  ptr = num; 
     
    379186 
    380187  if( !( charHeight = ch ) ) 
    381     charWidth = CHAR_HEIGHT; 
     188    charHeight = CHAR_HEIGHT; 
    382189 
    383190  if( width < 1 ) 
     
    414221    l = width; 
    415222 
    416   x += 2 + charWidth * ( width - l ); 
     223  x += ( 2.0f * cgDC.aspectScale ) + charWidth * ( width - l ); 
    417224 
    418225  ptr = num; 
     
    432239 
    433240static void CG_DrawProgressBar( rectDef_t *rect, vec4_t color, float scale, 
    434                                 int align, int textStyle, int special, float progress ) 
     241                                int align, int textalign, int textStyle, 
     242                                int special, float progress ) 
    435243{ 
    436244  float   rimWidth = rect->h / 20.0f; 
    437245  float   doneWidth, leftWidth; 
    438   float   tx, ty, tw, th; 
     246  float   tx, ty; 
    439247  char    textBuffer[ 8 ]; 
    440248 
     
    456264 
    457265  //draw rim and bar 
    458   if( align == ITEM_ALIGN_RIGHT ) 
     266  if( align == ALIGN_RIGHT ) 
    459267  { 
    460268    CG_DrawPic( rect->x, rect->y, rimWidth, rect->h, cgs.media.whiteShader ); 
     
    482290  { 
    483291    Com_sprintf( textBuffer, sizeof( textBuffer ), "%d%%", (int)( progress * 100 ) ); 
    484     tw = CG_Text_Width( textBuffer, scale, 0 ); 
    485     th = scale * 40.0f; 
    486  
    487     switch( align ) 
    488     { 
    489       case ITEM_ALIGN_LEFT: 
    490         tx = rect->x + ( rect->w / 10.0f ); 
    491         ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f ); 
    492         break; 
    493  
    494       case ITEM_ALIGN_RIGHT: 
    495         tx = rect->x + rect->w - ( rect->w / 10.0f ) - tw; 
    496         ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f ); 
    497         break; 
    498  
    499       case ITEM_ALIGN_CENTER: 
    500         tx = rect->x + ( rect->w / 2.0f ) - ( tw / 2.0f ); 
    501         ty = rect->y + ( rect->h / 2.0f ) + ( th / 2.0f ); 
    502         break; 
    503  
    504       default: 
    505         tx = ty = 0.0f; 
    506     } 
    507  
    508     CG_Text_Paint( tx, ty, scale, color, textBuffer, 0, 0, textStyle ); 
     292    CG_AlignText( rect, textBuffer, scale, 0.0f, 0.0f, textalign, VALIGN_CENTER, &tx, &ty ); 
     293 
     294    UI_Text_Paint( tx, ty, scale, color, textBuffer, 0, 0, textStyle ); 
    509295  } 
    510296} 
     
    891677} 
    892678 
    893 static void CG_DrawPlayerStamina( rectDef_t *rect, vec4_t color, float scale, 
    894                                   int align, int textStyle, int special ) 
    895 { 
    896   playerState_t *ps = &cg.snap->ps; 
    897   int           stamina = ps->stats[ STAT_STAMINA ]; 
    898   float         progress = ( (float)stamina + (float)MAX_STAMINA ) / ( (float)MAX_STAMINA * 2.0f ); 
    899  
    900   CG_DrawProgressBar( rect, color, scale, align, textStyle, special, progress ); 
    901 } 
    902  
    903679static void CG_DrawPlayerAmmoValue( rectDef_t *rect, vec4_t color ) 
    904680{ 
     
    1113889} 
    1114890 
    1115 static void CG_DrawPlayerHealthBar( rectDef_t *rect, vec4_t color, float scale, 
    1116                                     int align, int textStyle, int special ) 
    1117 { 
    1118   playerState_t *ps; 
    1119   float total; 
    1120  
    1121   ps = &cg.snap->ps; 
    1122  
    1123   total = ( (float)ps->stats[ STAT_HEALTH ] / (float)ps->stats[ STAT_MAX_HEALTH ] ); 
    1124   CG_DrawProgressBar( rect, color, scale, align, textStyle, special, total ); 
    1125 } 
    1126  
    1127891/* 
    1128892============== 
     
    1147911 
    1148912static void CG_DrawProgressLabel( rectDef_t *rect, float text_x, float text_y, vec4_t color, 
    1149                                   float scale, int align, const char *s, float fraction ) 
     913                                  float scale, int textalign, int textvalign, 
     914                                  const char *s, float fraction ) 
    1150915{ 
    1151916  vec4_t white = { 1.0f, 1.0f, 1.0f, 1.0f }; 
    1152   float tx, tw = CG_Text_Width( s, scale, 0 ); 
    1153  
    1154   switch( align ) 
    1155   { 
    1156     case ITEM_ALIGN_LEFT: 
    1157       tx = 0.0f; 
    1158       break; 
    1159  
    1160     case ITEM_ALIGN_RIGHT: 
    1161       tx = rect->w - tw; 
    1162       break; 
    1163  
    1164     case ITEM_ALIGN_CENTER: 
    1165       tx = ( rect->w / 2.0f ) - ( tw / 2.0f ); 
    1166       break; 
    1167  
    1168     default: 
    1169       tx = 0.0f; 
    1170   } 
     917  float tx, ty; 
     918 
     919  CG_AlignText( rect, s, scale, 0.0f, 0.0f, textalign, textvalign, &tx, &ty ); 
    1171920 
    1172921  if( fraction < 1.0f ) 
    1173     CG_Text_Paint( rect->x + text_x + tx, rect->y + text_y, scale, white, 
     922    UI_Text_Paint( text_x + tx, text_y + ty, scale, white, 
    1174923      s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
    1175924  else 
    1176     CG_Text_Paint( rect->x + text_x + tx, rect->y + text_y, scale, color, 
     925    UI_Text_Paint( text_x + tx, text_y + ty, scale, color, 
    1177926      s, 0, 0, ITEM_TEXTSTYLE_NEON ); 
    1178927} 
    1179928 
    1180929static void CG_DrawMediaProgress( rectDef_t *rect, vec4_t color, float scale, 
    1181                                   int align, int textStyle, int special ) 
    1182 { 
    1183   CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.mediaFraction ); 
     930                                  int align, int textalign, int textStyle, int special ) 
     931{ 
     932  CG_DrawProgressBar( rect, color, scale, align, textalign, textStyle, special, cg.mediaFraction ); 
    1184933} 
    1185934 
    1186935static void CG_DrawMediaProgressLabel( rectDef_t *rect, float text_x, float text_y, 
    1187                                        vec4_t color, float scale, int align ) 
    1188 { 
    1189   CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Map and Textures", cg.mediaFraction ); 
     936                                       vec4_t color, float scale, int textalign, int textvalign ) 
     937{ 
     938  CG_DrawProgressLabel( rect, text_x, text_y, color, scale, textalign, textvalign, 
     939                        "Map and Textures", cg.mediaFraction ); 
    1190940} 
    1191941 
    1192942static void CG_DrawBuildablesProgress( rectDef_t *rect, vec4_t color, float scale, 
    1193                                        int align, int textStyle, int special ) 
    1194 { 
    1195   CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.buildablesFraction ); 
     943                                       int align, int textalign, int textStyle, int special ) 
     944{ 
     945  CG_DrawProgressBar( rect, color, scale, align, textalign, textStyle, special, cg.buildablesFraction ); 
    1196946} 
    1197947 
    1198948static void CG_DrawBuildablesProgressLabel( rectDef_t *rect, float text_x, float text_y, 
    1199                                             vec4_t color, float scale, int align ) 
    1200 { 
    1201   CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Buildable Models", cg.buildablesFraction ); 
     949                                            vec4_t color, float scale, int textalign, int textvalign ) 
     950{ 
     951  CG_DrawProgressLabel( rect, text_x, text_y, color, scale, textalign, textvalign, 
     952                        "Buildable Models", cg.buildablesFraction ); 
    1202953} 
    1203954 
    1204955static void CG_DrawCharModelProgress( rectDef_t *rect, vec4_t color, float scale, 
    1205                                       int align, int textStyle, int special ) 
    1206 { 
    1207   CG_DrawProgressBar( rect, color, scale, align, textStyle, special, cg.charModelFraction ); 
     956                                      int align, int textalign, int textStyle, int special ) 
     957{ 
     958  CG_DrawProgressBar( rect, color, scale, align, textalign, textStyle, special, cg.charModelFraction ); 
    1208959} 
    1209960 
    1210961static void CG_DrawCharModelProgressLabel( rectDef_t *rect, float text_x, float text_y, 
    1211                                            vec4_t color, float scale, int align ) 
    1212 { 
    1213   CG_DrawProgressLabel( rect, text_x, text_y, color, scale, align, "Character Models", cg.charModelFraction ); 
     962                                           vec4_t color, float scale, int textalign, int textvalign ) 
     963{ 
     964  CG_DrawProgressLabel( rect, text_x, text_y, color, scale, textalign, textvalign, 
     965                        "Character Models", cg.charModelFraction ); 
    1214966} 
    1215967 
    1216968static void CG_DrawOverallProgress( rectDef_t *rect, vec4_t color, float scale, 
    1217                                     int align, int textStyle, int special ) 
     969                                    int align, int textalign, int textStyle, int special ) 
    1218970{ 
    1219971  float total; 
    1220972 
    1221973  total = ( cg.charModelFraction + cg.buildablesFraction + cg.mediaFraction ) / 3.0f; 
    1222   CG_DrawProgressBar( rect, color, scale, align, textStyle, special, total ); 
     974  CG_DrawProgressBar( rect, color, scale, align, textalign, textStyle, special, total ); 
    1223975} 
    1224976 
     
    1245997} 
    1246998 
    1247 static void CG_DrawLoadingString( rectDef_t *rect, float text_x, float text_y, vec4_t color, 
    1248                                   float scale, int align, int textStyle, const char *s ) 
    1249 { 
    1250   float tw, th, tx; 
    1251   int   pos, i; 
    1252   char  buffer[ 1024 ]; 
    1253   char  *end; 
    1254  
    1255   if( !s[ 0 ] ) 
    1256     return; 
    1257  
    1258   strcpy( buffer, s ); 
    1259   tw = CG_Text_Width( s, scale, 0 ); 
    1260   th = scale * 40.0f; 
    1261  
    1262   pos = i = 0; 
    1263  
    1264   while( pos < strlen( s ) ) 
    1265   { 
    1266     strcpy( buffer, &s[ pos ] ); 
    1267     tw = CG_Text_Width( buffer, scale, 0 ); 
    1268  
    1269     while( tw > rect->w ) 
    1270     { 
    1271       end = strrchr( buffer, ' ' ); 
    1272  
    1273       if( end == NULL ) 
    1274         break; 
    1275  
    1276       *end = '\0'; 
    1277       tw = CG_Text_Width( buffer, scale, 0 ); 
    1278     } 
    1279  
    1280     switch( align ) 
    1281     { 
    1282       case ITEM_ALIGN_LEFT: 
    1283         tx = rect->x; 
    1284         break; 
    1285  
    1286       case ITEM_ALIGN_RIGHT: 
    1287         tx = rect->x + rect->w - tw; 
    1288         break; 
    1289  
    1290       case ITEM_ALIGN_CENTER: 
    1291         tx = rect->x + ( rect->w / 2.0f ) - ( tw / 2.0f ); 
    1292         break; 
    1293  
    1294       default: 
    1295         tx = 0.0f; 
    1296     } 
    1297  
    1298     CG_Text_Paint( tx + text_x, rect->y + text_y + i * ( th + 3 ), scale, color, 
    1299       buffer, 0, 0, textStyle ); 
    1300  
    1301     pos += strlen( buffer ) + 1; 
    1302     i++; 
    1303   } 
    1304 } 
    1305  
    1306999static void CG_DrawLevelName( rectDef_t *rect, float text_x, float text_y, 
    1307                               vec4_t color, float scale, int align, int textStyle ) 
     1000                              vec4_t color, float scale, 
     1001                              int textalign, int textvalign, int textStyle ) 
    13081002{ 
    13091003  const char  *s; 
     
    13111005  s = CG_ConfigString( CS_MESSAGE ); 
    13121006 
    1313   CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, s ); 
     1007  UI_DrawTextBlock( rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, s ); 
    13141008} 
    13151009 
    13161010static void CG_DrawMOTD( rectDef_t *rect, float text_x, float text_y, 
    1317                          vec4_t color, float scale, int align, int textStyle ) 
     1011                         vec4_t color, float scale, 
     1012                         int textalign, int textvalign, int textStyle ) 
    13181013{ 
    13191014  const char  *s; 
     
    13211016  s = CG_ConfigString( CS_MOTD ); 
    13221017 
    1323   CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, s ); 
     1018  UI_DrawTextBlock( rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, s ); 
    13241019} 
    13251020 
    13261021static void CG_DrawHostname( rectDef_t *rect, float text_x, float text_y, 
    1327                              vec4_t color, float scale, int align, int textStyle ) 
     1022                             vec4_t color, float scale, 
     1023                             int textalign, int textvalign, int textStyle ) 
    13281024{ 
    13291025  char buffer[ 1024 ]; 
     
    13351031  Q_CleanStr( buffer ); 
    13361032 
    1337   CG_DrawLoadingString( rect, text_x, text_y, color, scale, align, textStyle, buffer ); 
     1033  UI_DrawTextBlock( rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, buffer ); 
    13381034} 
    13391035 
     
    14591155 { 
    14601156   int x = rect->x + rect->w / 2; 
    1461    CG_Text_Paint( x - CG_Text_Width( CG_GetKillerText( ), scale, 0 ) / 2, 
     1157   UI_Text_Paint( x - UI_Text_Width( CG_GetKillerText( ), scale, 0 ) / 2, 
    14621158     rect->y + rect->h, scale, color, CG_GetKillerText( ), 0, 0, textStyle ); 
    14631159  } 
     
    14651161 
    14661162 
    1467 static void CG_Text_Paint_Limit( float *maxX, float x, float y, float scale, 
    1468                                  vec4_t color, const char* text, float adjust, int limit ) 
    1469 { 
    1470   int         len, count; 
    1471   vec4_t      newColor; 
    1472   glyphInfo_t *glyph; 
    1473  
    1474   if( text ) 
    1475   { 
    1476     const char *s = text; 
    1477     float max = *maxX; 
    1478     float useScale; 
    1479     fontInfo_t *font = &cgDC.Assets.textFont; 
    1480  
    1481     if( scale <= cg_smallFont.value ) 
    1482       font = &cgDC.Assets.smallFont; 
    1483     else if( scale > cg_bigFont.value ) 
    1484       font = &cgDC.Assets.bigFont; 
    1485  
    1486     useScale = scale * font->glyphScale; 
    1487     trap_R_SetColor( color ); 
    1488     len = strlen( text ); 
    1489  
    1490     if( limit > 0 && len > limit ) 
    1491       len = limit; 
    1492  
    1493     count = 0; 
    1494  
    1495     while( s && *s && count < len ) 
    1496     { 
    1497       glyph = &font->glyphs[ (int)*s ]; 
    1498  
    1499       if( Q_IsColorString( s ) ) 
    1500       { 
    1501         memcpy( newColor, g_color_table[ ColorIndex( *(s+1) ) ], sizeof( newColor ) ); 
    1502         newColor[ 3 ] = color[ 3 ]; 
    1503         trap_R_SetColor( newColor ); 
    1504         s += 2; 
    1505         continue; 
    1506       } 
    1507       else 
    1508       { 
    1509         float yadj = useScale * glyph->top; 
    1510  
    1511         if( CG_Text_Width( s, useScale, 1 ) + x > max ) 
    1512         { 
    1513           *maxX = 0; 
    1514           break; 
    1515         } 
    1516  
    1517         CG_Text_PaintChar( x, y - yadj, 
    1518                            glyph->imageWidth, 
    1519                            glyph->imageHeight, 
    1520                            useScale, 
    1521                            glyph->s, 
    1522                            glyph->t, 
    1523                            glyph->s2, 
    1524                            glyph->t2, 
    1525                            glyph->glyph ); 
    1526         x += ( glyph->xSkip * useScale ) + adjust; 
    1527         *maxX = x; 
    1528         count++; 
    1529         s++; 
    1530       } 
    1531     } 
    1532  
    1533     trap_R_SetColor( NULL ); 
    1534   } 
    1535 } 
    1536  
    1537 static void CG_DrawTeamSpectators( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader ) 
    1538 { 
     1163static void CG_DrawTeamSpectators( rectDef_t *rect, float scale, int textvalign, vec4_t color, qhandle_t shader ) 
     1164{ 
     1165  float y; 
     1166 
    15391167  if( cg.spectatorLen ) 
    15401168  { 
     
    15681196          else 
    15691197          { 
    1570             cg.spectatorPaintX += CG_Text_Width( &cg.spectatorList[ cg.spectatorOffset ], scale, 1 ) - 1; 
     1198            cg.spectatorPaintX += UI_Text_Width( &cg.spectatorList[ cg.spectatorOffset ], scale, 1 ) - 1; 
    15711199            cg.spectatorOffset++; 
    15721200          } 
     
    15941222 
    15951223    maxX = rect->x + rect->w - 2; 
    1596  
    1597     CG_Text_Paint_Limit( &maxX, cg.spectatorPaintX, rect->y + rect->h - 3, scale, color, 
     1224    CG_AlignText( rect, NULL, 0.0f, 0.0f, UI_Text_EmHeight( scale ), 
     1225                  ALIGN_LEFT, textvalign, NULL, &y ); 
     1226 
     1227    UI_Text_Paint_Limit( &maxX, cg.spectatorPaintX, y, scale, color, 
    15981228                         &cg.spectatorList[ cg.spectatorOffset ], 0, 0 ); 
    15991229 
     
    16011231    { 
    16021232      float maxX2 = rect->x + rect->w - 2; 
    1603       CG_Text_Paint_Limit( &maxX2, cg.spectatorPaintX2, rect->y + rect->h - 3, scale, 
     1233      UI_Text_Paint_Limit( &maxX2, cg.spectatorPaintX2, y, scale, 
    16041234                           color, cg.spectatorList, 0, cg.spectatorOffset ); 
    16051235    } 
     
    16181248/* 
    16191249================== 
     1250CG_DrawTeamLabel 
     1251================== 
     1252*/ 
     1253static void CG_DrawTeamLabel( rectDef_t *rect, pTeam_t team, float text_x, float text_y, 
     1254    vec4_t color, float scale, int textalign, int textvalign, int textStyle ) 
     1255{ 
     1256  char  *t; 
     1257  char  stage[ MAX_TOKEN_CHARS ]; 
     1258  char  *s; 
     1259  float tx, ty; 
     1260 
     1261  stage[ 0 ] = '\0'; 
     1262 
     1263  switch( team ) 
     1264  { 
     1265    case PTE_ALIENS: 
     1266      t = "Aliens"; 
     1267      if( cg.intermissionStarted ) 
     1268        Com_sprintf( stage, MAX_TOKEN_CHARS, "(Stage %d)", cgs.alienStage + 1 ); 
     1269      break; 
     1270 
     1271    case PTE_HUMANS: 
     1272      t = "Humans"; 
     1273      if( cg.intermissionStarted ) 
     1274        Com_sprintf( stage, MAX_TOKEN_CHARS, "(Stage %d)", cgs.humanStage + 1 ); 
     1275      break; 
     1276 
     1277    default: 
     1278      t = ""; 
     1279      break; 
     1280  } 
     1281 
     1282  switch( textalign ) 
     1283  { 
     1284    default: 
     1285    case ALIGN_LEFT: 
     1286      s = va( "%s %s", t, stage ); 
     1287      break; 
     1288 
     1289    case ALIGN_RIGHT: 
     1290      s = va( "%s %s", stage, t ); 
     1291      break; 
     1292  } 
     1293 
     1294  CG_AlignText( rect, s, scale, 0.0f, 0.0f, textalign, textvalign, &tx, &ty ); 
     1295  UI_Text_Paint( text_x + tx, text_y + ty, scale, color, s, 0, 0, textStyle ); 
     1296} 
     1297 
     1298/* 
     1299================== 
    16201300CG_DrawStageReport 
    16211301================== 
    16221302*/ 
    16231303static void CG_DrawStageReport( rectDef_t *rect, float text_x, float text_y, 
    1624     vec4_t color, float scale, int align, int textStyle ) 
     1304    vec4_t color, float scale, int textalign, int textvalign, int textStyle ) 
    16251305{ 
    16261306  char  s[ MAX_TOKEN_CHARS ]; 
    1627   int   tx, w, kills; 
    1628  
    1629   if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_NONE && !cg.intermissionStarted ) 
    1630     return; 
     1307  float tx, ty; 
     1308  int kills; 
    16311309 
    16321310  if( cg.intermissionStarted ) 
    1633   { 
    1634     Com_sprintf( s, MAX_TOKEN_CHARS, 
    1635         "Stage %d" //PH34R MY MAD-LEET CODING SKILLZ 
    1636         "                                                       " 
    1637         "Stage %d", 
    1638         cgs.alienStage + 1, cgs.humanStage + 1 ); 
    1639   } 
    1640   else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) 
     1311    return; 
     1312 
     1313  if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_NONE ) 
     1314    return; 
     1315 
     1316  if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) 
    16411317  { 
    16421318    kills = cgs.alienNextStageThreshold - cgs.alienKills; 
     
    16651341  } 
    16661342 
    1667   w = CG_Text_Width( s, scale, 0 ); 
    1668  
    1669   switch( align ) 
    1670   { 
    1671     case ITEM_ALIGN_LEFT: 
    1672       tx = rect->x; 
    1673       break; 
    1674  
    1675     case ITEM_ALIGN_RIGHT: 
    1676       tx = rect->x + rect->w - w; 
    1677       break; 
    1678  
    1679     case ITEM_ALIGN_CENTER: 
    1680       tx = rect->x + ( rect->w / 2.0f ) - ( w / 2.0f ); 
    1681       break; 
    1682  
    1683     default: 
    1684       tx = 0.0f; 
    1685   } 
    1686  
    1687   CG_Text_Paint( text_x + tx, rect->y + text_y, scale, color, s, 0, 0, textStyle ); 
     1343  CG_AlignText( rect, s, scale, 0.0f, 0.0f, textalign, textvalign, &tx, &ty ); 
     1344 
     1345  UI_Text_Paint( text_x + tx, text_y + ty, scale, color, s, 0, 0, textStyle ); 
    16881346} 
    16891347 
     
    16961354#define FPS_STRING  "fps" 
    16971355static void CG_DrawFPS( rectDef_t *rect, float text_x, float text_y, 
    1698                         float scale, vec4_t color, int align, int textStyle, 
     1356                        float scale, vec4_t color, 
     1357                        int textalign, int textvalign, int textStyle, 
    16991358                        qboolean scalableText ) 
    17001359{ 
    17011360  char        *s; 
    1702   int         tx, w, totalWidth, strLength; 
     1361  float       tx, ty; 
     1362  float       w, h, totalWidth; 
     1363  int         strLength; 
    17031364  static int  previousTimes[ FPS_FRAMES ]; 
    17041365  static int  index; 
     
    17341395 
    17351396    s = va( "%d", fps ); 
    1736     w = CG_Text_Width( "0", scale, 0 ); 
     1397    w = UI_Text_Width( "0", scale, 0 ); 
     1398    h = UI_Text_Height( "0", scale, 0 ); 
    17371399    strLength = CG_DrawStrlen( s ); 
    1738     totalWidth = CG_Text_Width( FPS_STRING, scale, 0 ) + w * strLength; 
    1739  
    1740     switch( align ) 
    1741     { 
    1742       case ITEM_ALIGN_LEFT: 
    1743         tx = rect->x; 
    1744         break; 
    1745  
    1746       case ITEM_ALIGN_RIGHT: 
    1747         tx = rect->x + rect->w - totalWidth; 
    1748         break; 
    1749  
    1750       case ITEM_ALIGN_CENTER: 
    1751         tx = rect->x + ( rect->w / 2.0f ) - ( totalWidth / 2.0f ); 
    1752         break; 
    1753  
    1754       default: 
    1755         tx = 0.0f; 
    1756     } 
     1400    totalWidth = UI_Text_Width( FPS_STRING, scale, 0 ) + w * strLength; 
     1401 
     1402    CG_AlignText( rect, s, 0.0f, totalWidth, h, textalign, textvalign, &tx, &ty ); 
    17571403 
    17581404    if( scalableText ) 
     
    17651411        c[ 1 ] = '\0'; 
    17661412 
    1767         CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, c, 0, 0, textStyle ); 
     1413        UI_Text_Paint( text_x + tx + i * w, text_y + ty, scale, color, c, 0, 0, textStyle ); 
    17681414      } 
     1415 
     1416      UI_Text_Paint( text_x + tx + i * w, text_y + ty, scale, color, FPS_STRING, 0, 0, textStyle ); 
    17691417    } 
    17701418    else 
     
    17741422      trap_R_SetColor( NULL ); 
    17751423    } 
    1776  
    1777     if( scalableText ) 
    1778       CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, FPS_STRING, 0, 0, textStyle ); 
    17791424  } 
    17801425} 
     
    18371482*/ 
    18381483static void CG_DrawTimer( rectDef_t *rect, float text_x, float text_y, 
    1839                           float scale, vec4_t color, int align, int textStyle ) 
     1484                          float scale, vec4_t color, 
     1485                          int textalign, int textvalign, int textStyle ) 
    18401486{ 
    18411487  char    *s; 
    1842   int     i, tx, w, totalWidth, strLength; 
     1488  float   tx, ty; 
     1489  int     i, strLength; 
     1490  float   w, h, totalWidth; 
    18431491  int     mins, seconds, tens; 
    18441492  int     msec; 
     
    18561504 
    18571505  s = va( "%d:%d%d", mins, tens, seconds ); 
    1858   w = CG_Text_Width( "0", scale, 0 ); 
     1506  w = UI_Text_Width( "0", scale, 0 ); 
     1507  h = UI_Text_Height( "0", scale, 0 ); 
    18591508  strLength = CG_DrawStrlen( s ); 
    18601509  totalWidth = w * strLength; 
    18611510 
    1862   switch( align ) 
    1863   { 
    1864     case ITEM_ALIGN_LEFT: 
    1865       tx = rect->x; 
    1866       break; 
    1867  
    1868     case ITEM_ALIGN_RIGHT: 
    1869       tx = rect->x + rect->w - totalWidth; 
    1870       break; 
    1871  
    1872     case ITEM_ALIGN_CENTER: 
    1873       tx = rect->x + ( rect->w / 2.0f ) - ( totalWidth / 2.0f ); 
    1874       break; 
    1875  
    1876     default: 
    1877       tx = 0.0f; 
    1878   } 
     1511  CG_AlignText( rect, s, 0.0f, totalWidth, h, textalign, textvalign, &tx, &ty ); 
    18791512 
    18801513  for( i = 0; i < strLength; i++ ) 
     
    18851518    c[ 1 ] = '\0'; 
    18861519 
    1887     CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, c, 0, 0, textStyle ); 
     1520    UI_Text_Paint( text_x + tx + i * w, text_y + ty, scale, color, c, 0, 0, textStyle ); 
    18881521  } 
    18891522} 
     
    18951528*/ 
    18961529static void CG_DrawClock( rectDef_t *rect, float text_x, float text_y, 
    1897                           float scale, vec4_t color, int align, int textStyle ) 
     1530                          float scale, vec4_t color, 
     1531                          int textalign, int textvalign, int textStyle ) 
    18981532{ 
    18991533  char    *s; 
    1900   int     i, tx, w, totalWidth, strLength; 
     1534  float   tx, ty; 
     1535  int     i, strLength; 
     1536  float   w, h, totalWidth; 
    19011537  qtime_t qt; 
    19021538  int     t; 
     
    19291565    s = va( "%d%s%02d%s", h, ( qt.tm_sec % 2 ) ? ":" : " ", qt.tm_min, pm ); 
    19301566  } 
    1931   w = CG_Text_Width( "0", scale, 0 ); 
     1567  w = UI_Text_Width( "0", scale, 0 ); 
     1568  h = UI_Text_Height( "0", scale, 0 ); 
    19321569  strLength = CG_DrawStrlen( s ); 
    19331570  totalWidth = w * strLength; 
    19341571 
    1935   switch( align ) 
    1936   { 
    1937     case ITEM_ALIGN_LEFT: 
    1938       tx = rect->x; 
    1939       break; 
    1940  
    1941     case ITEM_ALIGN_RIGHT: 
    1942       tx = rect->x + rect->w - totalWidth; 
    1943       break; 
    1944  
    1945     case ITEM_ALIGN_CENTER: 
    1946       tx = rect->x + ( rect->w / 2.0f ) - ( totalWidth / 2.0f ); 
    1947       break; 
    1948  
    1949     default: 
    1950       tx = 0.0f; 
    1951   } 
     1572  CG_AlignText( rect, s, 0.0f, totalWidth, h, textalign, textvalign, &tx, &ty ); 
    19521573 
    19531574  for( i = 0; i < strLength; i++ ) 
     
    19581579    c[ 1 ] = '\0'; 
    19591580 
    1960     CG_Text_Paint( text_x + tx + i * w, rect->y + text_y, scale, color, c, 0, 0, textStyle ); 
     1581    UI_Text_Paint( text_x + tx + i * w, text_y + ty, scale, color, c, 0, 0, textStyle ); 
    19611582  } 
    19621583} 
     
    19681589*/ 
    19691590static void CG_DrawSnapshot( rectDef_t *rect, float text_x, float text_y, 
    1970                              float scale, vec4_t color, int align, int textStyle ) 
     1591                             float scale, vec4_t color, 
     1592                             int textalign, int textvalign, int textStyle ) 
    19711593{ 
    19721594  char    *s; 
    1973   int     w, tx; 
     1595  float   tx, ty; 
    19741596 
    19751597  if( !cg_drawSnapshot.integer ) 
     
    19781600  s = va( "time:%d snap:%d cmd:%d", cg.snap->serverTime, 
    19791601    cg.latestSnapshotNum, cgs.serverCommandSequence ); 
    1980   w = CG_Text_Width( s, scale, 0 ); 
    1981  
    1982   switch( align ) 
    1983   { 
    1984     case ITEM_ALIGN_LEFT: 
    1985       tx = rect->x; 
    1986       break; 
    1987  
    1988     case ITEM_ALIGN_RIGHT: 
    1989       tx = rect->x + rect->w - w; 
    1990       break; 
    1991  
    1992     case ITEM_ALIGN_CENTER: 
    1993       tx = rect->x + ( rect->w / 2.0f ) - ( w / 2.0f ); 
    1994       break; 
    1995  
    1996     default: 
    1997       tx = 0.0f; 
    1998   } 
    1999  
    2000   CG_Text_Paint( text_x + tx, rect->y + text_y, scale, color, s, 0, 0, textStyle ); 
     1602 
     1603  CG_AlignText( rect, s, scale, 0.0f, 0.0f, textalign, textvalign, &tx, &ty ); 
     1604 
     1605  UI_Text_Paint( text_x + tx, text_y + ty, scale, color, s, 0, 0, textStyle ); 
    20011606} 
    20021607 
     
    21091714  // also add text in center of screen 
    21101715  s = "Connection Interrupted"; 
    2111   w = CG_Text_Width( s, 0.7f, 0 ); 
    2112   CG_Text_Paint( 320 - w / 2, 100, 0.7f, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
     1716  w = UI_Text_Width( s, 0.7f, 0 ); 
     1717  UI_Text_Paint( 320 - w / 2, 100, 0.7f, color, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
    21131718 
    21141719  // blink the icon 
     
    22631868 
    22641869  if( cg_nopredict.integer || cg_synchronousClients.integer ) 
    2265     CG_Text_Paint( ax, ay, 0.5, white, "snc", 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
     1870    UI_Text_Paint( ax, ay, 0.5, white, "snc", 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
    22661871  else 
    22671872  { 
     
    22691874 
    22701875    s = va( "%d", cg.ping ); 
    2271     ax = rect->x + ( rect->w / 2.0f ) - ( CG_Text_Width( s, scale, 0 ) / 2.0f ) + text_x; 
    2272     ay = rect->y + ( rect->h / 2.0f ) + ( CG_Text_Height( s, scale, 0 ) / 2.0f ) + text_y; 
     1876    ax = rect->x + ( rect->w / 2.0f ) - ( UI_Text_Width( s, scale, 0 ) / 2.0f ) + text_x; 
     1877    ay = rect->y + ( rect->h / 2.0f ) + ( UI_Text_Height( s, scale, 0 ) / 2.0f ) + text_y; 
    22731878 
    22741879    Vector4Copy( textColor, adjustedColor ); 
    22751880    adjustedColor[ 3 ] = 0.5f; 
    2276     CG_Text_Paint( ax, ay, scale, adjustedColor, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
     1881    UI_Text_Paint( ax, ay, scale, adjustedColor, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
    22771882  } 
    22781883 
    22791884  CG_DrawDisconnect( ); 
    2280 } 
    2281  
    2282 /* 
    2283 ============== 
    2284 CG_DrawTextBlock 
    2285 ============== 
    2286 */ 
    2287 static void CG_DrawTextBlock( rectDef_t *rect, float text_x, float text_y, vec4_t color, 
    2288                             float scale, int align, int textStyle, const char *text, 
    2289                             menuDef_t *parent, itemDef_t *textItem ) 
    2290 { 
    2291   float     x, y, w, h; 
    2292  
    2293   //offset the text 
    2294   x = rect->x; 
    2295   y = rect->y; 
    2296   w = rect->w - ( 16 + ( 2 * text_x ) ); //16 to ensure text within frame 
    2297   h = rect->h; 
    2298  
    2299   textItem->text = text; 
    2300  
    2301   textItem->parent = parent; 
    2302   memcpy( textItem->window.foreColor, color, sizeof( vec4_t ) ); 
    2303   textItem->window.flags = 0; 
    2304  
    2305   switch( align ) 
    2306   { 
    2307     case ITEM_ALIGN_LEFT: 
    2308       textItem->window.rect.x = x; 
    2309       break; 
    2310  
    2311     case ITEM_ALIGN_RIGHT: 
    2312       textItem->window.rect.x = x + w; 
    2313       break; 
    2314  
    2315     case ITEM_ALIGN_CENTER: 
    2316       textItem->window.rect.x = x + ( w / 2 ); 
    2317       break; 
    2318  
    2319     default: 
    2320       textItem->window.rect.x = x; 
    2321       break; 
    2322   } 
    2323  
    2324   textItem->window.rect.y = y; 
    2325   textItem->window.rect.w = w; 
    2326   textItem->window.rect.h = h; 
    2327   textItem->window.borderSize = 0; 
    2328   textItem->textRect.x = 0; 
    2329   textItem->textRect.y = 0; 
    2330   textItem->textRect.w = 0; 
    2331   textItem->textRect.h = 0; 
    2332   textItem->textalignment = align; 
    2333   textItem->textalignx = text_x; 
    2334   textItem->textaligny = text_y; 
    2335   textItem->textscale = scale; 
    2336   textItem->textStyle = textStyle; 
    2337  
    2338   //hack to utilise existing autowrap code 
    2339   Item_Text_AutoWrapped_Paint( textItem ); 
    23401885} 
    23411886 
     
    23461891*/ 
    23471892static void CG_DrawConsole( rectDef_t *rect, float text_x, float text_y, vec4_t color, 
    2348                             float scale, int align, int textStyle ) 
    2349 { 
    2350   static menuDef_t dummyParent; 
    2351   static itemDef_t textItem; 
    2352  
    2353   CG_DrawTextBlock( rect, text_x, text_y, color, scale, align, textStyle, 
    2354       cg.consoleText, &dummyParent, &textItem ); 
     1893                            float scale, int textalign, int textvalign, int textStyle ) 
     1894{ 
     1895  UI_DrawTextBlock( rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, cg.consoleText ); 
    23551896} 
    23561897 
     
    23611902*/ 
    23621903static void CG_DrawTutorial( rectDef_t *rect, float text_x, float text_y, vec4_t color, 
    2363                             float scale, int align, int textStyle ) 
    2364 { 
    2365   static menuDef_t dummyParent; 
    2366   static itemDef_t textItem; 
    2367  
     1904                            float scale, int textalign, int textvalign, int textStyle ) 
     1905{ 
    23681906  if( !cg_tutorial.integer ) 
    23691907    return; 
    23701908 
    2371   CG_DrawTextBlock( rect, text_x, text_y, color, scale, align, textStyle, 
    2372       CG_TutorialText( ), &dummyParent, &textItem ); 
     1909  UI_DrawTextBlock( rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, CG_TutorialText( ) ); 
    23731910} 
    23741911 
     
    24682005  w = h = wi->crossHairSize; 
    24692006 
     2007  w *= cgDC.aspectScale; 
     2008 
    24702009  x = cg_crosshairX.integer; 
    24712010  y = cg_crosshairY.integer; 
     
    25542093 
    25552094  name = cgs.clientinfo[ cg.crosshairClientNum ].name; 
    2556   w = CG_Text_Width( name, scale, 0 ); 
     2095  w = UI_Text_Width( name, scale, 0 ); 
    25572096  x = rect->x + rect->w / 2; 
    2558   CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); 
     2097  UI_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); 
    25592098  trap_R_SetColor( NULL ); 
    25602099} 
     
    25702109void CG_OwnerDraw( float x, float y, float w, float h, float text_x, 
    25712110                   float text_y, int ownerDraw, int ownerDrawFlags, 
    2572                    int align, float special, float scale, vec4_t color, 
     2111                   int align, int textalign, int textvalign, float special, 
     2112                   float scale, vec4_t color, 
    25732113                   qhandle_t shader, int textStyle ) 
    25742114{ 
     
    25972137      CG_DrawPlayerBankValue( &rect, color, qfalse ); 
    25982138      break; 
    2599     case CG_PLAYER_STAMINA: 
    2600       CG_DrawPlayerStamina( &rect, color, scale, align, textStyle, special ); 
    2601       break; 
    26022139    case CG_PLAYER_STAMINA_1: 
    26032140      CG_DrawPlayerStamina1( &rect, color, shader ); 
     
    26272164      CG_DrawPlayerHealthValue( &rect, color ); 
    26282165      break; 
    2629     case CG_PLAYER_HEALTH_BAR: 
    2630       CG_DrawPlayerHealthBar( &rect, color, scale, align, textStyle, special ); 
    2631       break; 
    26322166    case CG_PLAYER_HEALTH_CROSS: 
    26332167      CG_DrawPlayerHealthCross( &rect, color, shader ); 
     
    26732207      break; 
    26742208    case CG_SPECTATORS: 
    2675       CG_DrawTeamSpectators( &rect, scale, color, shader ); 
     2209      CG_DrawTeamSpectators( &rect, scale, textvalign, color, shader ); 
    26762210      break; 
    26772211    case CG_PLAYER_CROSSHAIRNAMES: 
     
    26792213      break; 
    26802214    case CG_STAGE_REPORT_TEXT: 
    2681       CG_DrawStageReport( &rect, text_x, text_y, color, scale, align, textStyle ); 
     2215      CG_DrawStageReport( &rect, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
     2216      break; 
     2217    case CG_ALIENS_SCORE_LABEL: 
     2218      CG_DrawTeamLabel( &rect, PTE_ALIENS, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
     2219      break; 
     2220    case CG_HUMANS_SCORE_LABEL: 
     2221      CG_DrawTeamLabel( &rect, PTE_HUMANS, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
    26822222      break; 
    26832223 
     
    26872227      break; 
    26882228    case CG_LOAD_MEDIA: 
    2689       CG_DrawMediaProgress( &rect, color, scale, align, textStyle, special ); 
     2229      CG_DrawMediaProgress( &rect, color, scale, align, textalign, textStyle, special ); 
    26902230      break; 
    26912231    case CG_LOAD_MEDIA_LABEL: 
    2692       CG_DrawMediaProgressLabel( &rect, text_x, text_y, color, scale, align ); 
     2232      CG_DrawMediaProgressLabel( &rect, text_x, text_y, color, scale, textalign, textvalign ); 
    26932233      break; 
    26942234    case CG_LOAD_BUILDABLES: 
    2695       CG_DrawBuildablesProgress( &rect, color, scale, align, textStyle, special ); 
     2235      CG_DrawBuildablesProgress( &rect, color, scale, align, textalign, textStyle, special ); 
    26962236      break; 
    26972237    case CG_LOAD_BUILDABLES_LABEL: 
    2698       CG_DrawBuildablesProgressLabel( &rect, text_x, text_y, color, scale, align ); 
     2238      CG_DrawBuildablesProgressLabel( &rect, text_x, text_y, color, scale, textalign, textvalign ); 
    26992239      break; 
    27002240    case CG_LOAD_CHARMODEL: 
    2701       CG_DrawCharModelProgress( &rect, color, scale, align, textStyle, special ); 
     2241      CG_DrawCharModelProgress( &rect, color, scale, align, textalign, textStyle, special ); 
    27022242      break; 
    27032243    case CG_LOAD_CHARMODEL_LABEL: 
    2704       CG_DrawCharModelProgressLabel( &rect, text_x, text_y, color, scale, align ); 
     2244      CG_DrawCharModelProgressLabel( &rect, text_x, text_y, color, scale, textalign, textvalign ); 
    27052245      break; 
    27062246    case CG_LOAD_OVERALL: 
    2707       CG_DrawOverallProgress( &rect, color, scale, align, textStyle, special ); 
     2247      CG_DrawOverallProgress( &rect, color, scale, align, textalign, textStyle, special ); 
    27082248      break; 
    27092249    case CG_LOAD_LEVELNAME: 
    2710       CG_DrawLevelName( &rect, text_x, text_y, color, scale, align, textStyle ); 
     2250      CG_DrawLevelName( &rect, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
    27112251      break; 
    27122252    case CG_LOAD_MOTD: 
    2713       CG_DrawMOTD( &rect, text_x, text_y, color, scale, align, textStyle ); 
     2253      CG_DrawMOTD( &rect, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
    27142254      break; 
    27152255    case CG_LOAD_HOSTNAME: 
    2716       CG_DrawHostname( &rect, text_x, text_y, color, scale, align, textStyle ); 
     2256      CG_DrawHostname( &rect, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
    27172257      break; 
    27182258 
    27192259    case CG_FPS: 
    2720       CG_DrawFPS( &rect, text_x, text_y, scale, color, align, textStyle, qtrue ); 
     2260      CG_DrawFPS( &rect, text_x, text_y, scale, color, textalign, textvalign, textStyle, qtrue ); 
    27212261      break; 
    27222262    case CG_FPS_FIXED: 
    2723       CG_DrawFPS( &rect, text_x, text_y, scale, color, align, textStyle, qfalse ); 
     2263      CG_DrawFPS( &rect, text_x, text_y, scale, color, textalign, textvalign, textStyle, qfalse ); 
    27242264      break; 
    27252265    case CG_TIMER: 
    2726       CG_DrawTimer( &rect, text_x, text_y, scale, color, align, textStyle ); 
     2266      CG_DrawTimer( &rect, text_x, text_y, scale, color, textalign, textvalign, textStyle ); 
    27272267      break; 
    27282268    case CG_CLOCK: 
    2729       CG_DrawClock( &rect, text_x, text_y, scale, color, align, textStyle ); 
     2269      CG_DrawClock( &rect, text_x, text_y, scale, color, textalign, textvalign, textStyle ); 
    27302270      break; 
    27312271    case CG_TIMER_MINS: 
     
    27362276      break; 
    27372277    case CG_SNAPSHOT: 
    2738       CG_DrawSnapshot( &rect, text_x, text_y, scale, color, align, textStyle ); 
     2278      CG_DrawSnapshot( &rect, text_x, text_y, scale, color, textalign, textvalign, textStyle ); 
    27392279      break; 
    27402280    case CG_LAGOMETER: 
     
    27502290 
    27512291    case CG_CONSOLE: 
    2752       CG_DrawConsole( &rect, text_x, text_y, color, scale, align, textStyle ); 
     2292      CG_DrawConsole( &rect, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
    27532293      break; 
    27542294 
    27552295    case CG_TUTORIAL: 
    2756       CG_DrawTutorial( &rect, text_x, text_y, color, scale, align, textStyle ); 
     2296      CG_DrawTutorial( &rect, text_x, text_y, color, scale, textalign, textvalign, textStyle ); 
    27572297      break; 
    27582298 
     
    28192359void CG_ShowTeamMenu( void ) 
    28202360{ 
    2821   Menus_OpenByName( "teamMenu" ); 
     2361  Menus_ActivateByName( "teamMenu" ); 
    28222362} 
    28232363 
     
    28832423{ 
    28842424} 
    2885  
    2886  
    2887 void CG_GetTeamColor( vec4_t *color ) 
    2888 { 
    2889   (*color)[ 0 ] = (*color)[ 2 ] = 0.0f; 
    2890   (*color)[ 1 ] = 0.17f; 
    2891   (*color)[ 3 ] = 0.25f; 
    2892 } 
    28932425//END TA UI 
    28942426 
     
    29982530    linebuffer[ l ] = 0; 
    29992531 
    3000     w = CG_Text_Width( linebuffer, 0.5, 0 ); 
    3001     h = CG_Text_Height( linebuffer, 0.5, 0 ); 
     2532    w = UI_Text_Width( linebuffer, 0.5, 0 ); 
     2533    h = UI_Text_Height( linebuffer, 0.5, 0 ); 
    30022534    x = ( SCREEN_WIDTH - w ) / 2; 
    3003     CG_Text_Paint( x, y + h, 0.5, color, linebuffer, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE ); 
     2535    UI_Text_Paint( x, y + h, 0.5, color, linebuffer, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE ); 
    30042536    y += h + 6; 
    30052537 
     
    30542586  s = va( "VOTE(%i): \"%s\"  [%s]Yes:%i [%s]No:%i", sec, cgs.voteString, 
    30552587    yeskey, cgs.voteYes, nokey, cgs.voteNo ); 
    3056   CG_Text_Paint( 8, 340, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
     2588  UI_Text_Paint( 8, 340, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
    30572589} 
    30582590 
     
    30982630          nokey, cgs.teamVoteNo[ cs_offset ] ); 
    30992631 
    3100   CG_Text_Paint( 8, 360, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
     2632  UI_Text_Paint( 8, 360, 0.3f, white, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); 
    31012633} 
    31022634 
     
    31872719  strcat( buffer, cgs.clientinfo[ cg.snap->ps.clientNum ].name ); 
    31882720 
    3189   w = CG_Text_Width( buffer, 0.7f, 0 ); 
    3190   CG_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
     2721  w = UI_Text_Width( buffer, 0.7f, 0 ); 
     2722  UI_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
    31912723 
    31922724  return qtrue; 
     
    32152747               cg.snap->ps.persistant[ PERS_QUEUEPOS ] + 1 ); 
    32162748 
    3217   w = CG_Text_Width( buffer, 0.7f, 0 ); 
    3218   CG_Text_Paint( 320 - w / 2, 360, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
     2749  w = UI_Text_Width( buffer, 0.7f, 0 ); 
     2750  UI_Text_Paint( 320 - w / 2, 360, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
    32192751 
    32202752  if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) 
     
    32352767  } 
    32362768 
    3237   w = CG_Text_Width( buffer, 0.7f, 0 ); 
    3238   CG_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
     2769  w = UI_Text_Width( buffer, 0.7f, 0 ); 
     2770  UI_Text_Paint( 320 - w / 2, 400, 0.7f, color, buffer, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
    32392771 
    32402772  return qtrue; 
     
    32772809  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) 
    32782810  { 
    3279     w = CG_Text_Width( SPECTATOR_STRING, 0.7f, 0 ); 
    3280     CG_Text_Paint( 320 - w / 2, 440, 0.7f, color, SPECTATOR_STRING, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
     2811    w = UI_Text_Width( SPECTATOR_STRING, 0.7f, 0 ); 
     2812    UI_Text_Paint( 320 - w / 2, 440, 0.7f, color, SPECTATOR_STRING, 0, 0, ITEM_TEXTSTYLE_SHADOWED ); 
    32812813  } 
    32822814  else 
  • src/cgame/cg_local.h

    r119 r123  
    13851385extern  markPoly_t      cg_markPolys[ MAX_MARK_POLYS ]; 
    13861386 
     1387extern  vmCvar_t    cg_version; 
    13871388extern  vmCvar_t    cg_centertime; 
    13881389extern  vmCvar_t    cg_runpitch; 
  • src/cgame/cg_local.h

    r122 r123  
    8080#define TEAM_OVERLAY_MAXLOCATION_WIDTH  16 
    8181 
    82 #define DEFAULT_MODEL       "sarge" 
    83 #define DEFAULT_TEAM_MODEL  "sarge" 
    84 #define DEFAULT_TEAM_HEAD   "sarge" 
    85  
    8682typedef enum 
    8783{ 
     
    709705  pTeam_t     team; 
    710706 
    711   int         botSkill;                   // 0 = not bot, 1-5 = bot 
    712  
    713707  vec3_t      color1; 
    714708  vec3_t      color2; 
     
    721715 
    722716  int         handicap; 
    723   int         wins, losses;               // in tourney mode 
    724  
    725   int         teamTask;                   // task in teamplay (offence/defence) 
    726   qboolean    teamLeader;                 // true when this is a team leader 
    727717 
    728718  int         medkitUsageTime; 
     
    737727  char        modelName[ MAX_QPATH ]; 
    738728  char        skinName[ MAX_QPATH ]; 
    739   char        headModelName[ MAX_QPATH ]; 
    740   char        headSkinName[ MAX_QPATH ]; 
    741729 
    742730  qboolean    newAnims;                   // true if using the new mission pack animations 
     
    13881376extern  cg_t      cg; 
    13891377extern  centity_t cg_entities[ MAX_GENTITIES ]; 
     1378extern  displayContextDef_t  cgDC; 
    13901379 
    13911380extern  weaponInfo_t    cg_weapons[ 32 ]; 
     
    14631452extern  vmCvar_t    cg_paused; 
    14641453extern  vmCvar_t    cg_blood; 
    1465 extern  vmCvar_t    cg_predictItems; 
    14661454extern  vmCvar_t    cg_deferPlayers; 
    14671455extern  vmCvar_t    cg_drawFriend; 
     
    14731461extern  vmCvar_t    pmove_fixed; 
    14741462extern  vmCvar_t    pmove_msec; 
    1475 //extern  vmCvar_t    cg_pmove_fixed; 
    14761463extern  vmCvar_t    cg_cameraOrbit; 
    14771464extern  vmCvar_t    cg_cameraOrbitDelay; 
     
    14881475extern  vmCvar_t    cg_oldPlasma; 
    14891476extern  vmCvar_t    cg_trueLightning; 
    1490 extern  vmCvar_t    cg_creepRes; 
    14911477extern  vmCvar_t    cg_drawSurfNormal; 
    14921478extern  vmCvar_t    cg_drawBBOX; 
     
    15161502extern  vmCvar_t    ui_stages; 
    15171503extern  vmCvar_t    ui_dialog; 
    1518 extern  vmCvar_t    ui_loading; 
    15191504extern  vmCvar_t    ui_voteActive; 
    15201505extern  vmCvar_t    ui_alienTeamVoteActive; 
     
    16021587void        CG_CenterPrint( const char *str, int y, int charWidth ); 
    16031588void        CG_DrawActive( stereoFrame_t stereoView ); 
    1604 void        CG_OwnerDraw( float x, float y, float w, float h, float text_x, float text_y, 
    1605                           int ownerDraw, int ownerDrawFlags, int align, float special, 
    1606                           float scale, vec4_t color, qhandle_t shader, int textStyle); 
    1607 void        CG_Text_Paint( float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style ); 
    1608 int         CG_Text_Width( const char *text, float scale, int limit ); 
    1609 int         CG_Text_Height( const char *text, float scale, int limit ); 
     1589void        CG_OwnerDraw( float x, float y, float w, float h, float text_x, 
     1590                          float text_y, int ownerDraw, int ownerDrawFlags, 
     1591                          int align, int textalign, int textvalign, float special, 
     1592                          float scale, vec4_t color, 
     1593                          qhandle_t shader, int textStyle ); 
    16101594float       CG_GetValue(int ownerDraw); 
    16111595void        CG_RunMenuScript(char **args); 
     
    20372021void          trap_Key_GetBindingBuf( int keynum, char *buf, int buflen ); 
    20382022void          trap_Key_SetBinding( int keynum, const char *binding ); 
     2023void          trap_Key_SetOverstrikeMode( qboolean state ); 
     2024qboolean      trap_Key_GetOverstrikeMode( void ); 
    20392025 
    20402026int           trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits ); 
  • src/cgame/cg_main.c

    r119 r123  
    2424// cg_main.c -- initialization and primary entry point for cgame 
    2525 
    26  
    2726#include "cg_local.h" 
     27 
     28#include "../qcommon/q_shared.h" 
    2829 
    2930#include "../ui/ui_shared.h" 
     
    101102buildableInfo_t cg_buildables[ BA_NUM_BUILDABLES ]; 
    102103 
     104vmCvar_t  cg_version; 
    103105vmCvar_t  cg_teslaTrailTime; 
    104106vmCvar_t  cg_railTrailTime; 
     
    239241static cvarTable_t cvarTable[ ] = 
    240242{ 
     243  { &cg_version, "cg_version", FULL_VERSION, CVAR_ROM | CVAR_USERINFO }, 
    241244  { &cg_ignore, "cg_ignore", "0", 0 },  // used for debugging 
    242245  { &cg_autoswitch, "cg_autoswitch", "1", CVAR_ARCHIVE }, 
  • src/cgame/cg_main.c

    r122 r123  
    6969      CG_DrawActiveFrame( arg0, arg1, arg2 ); 
    7070      return 0; 
    71  
    72     case CG_CROSSHAIR_PLAYER: 
    73       return CG_CrosshairPlayer( ); 
    74  
    75     case CG_LAST_ATTACKER: 
    76       return CG_LastAttacker( ); 
    7771 
    7872    case CG_KEY_EVENT: 
     
    173167vmCvar_t  cg_paused; 
    174168vmCvar_t  cg_blood; 
    175 vmCvar_t  cg_predictItems; 
    176169vmCvar_t  cg_deferPlayers; 
    177170vmCvar_t  cg_drawTeamOverlay; 
     
    185178vmCvar_t  cg_smoothClients; 
    186179vmCvar_t  pmove_fixed; 
    187 //vmCvar_t  cg_pmove_fixed; 
    188180vmCvar_t  pmove_msec; 
    189181vmCvar_t  cg_pmove_msec; 
     
    202194vmCvar_t  cg_oldPlasma; 
    203195vmCvar_t  cg_trueLightning; 
    204 vmCvar_t  cg_creepRes; 
    205196vmCvar_t  cg_drawSurfNormal; 
    206197vmCvar_t  cg_drawBBOX; 
     
    230221vmCvar_t  ui_stages; 
    231222vmCvar_t  ui_dialog; 
    232 vmCvar_t  ui_loading; 
    233223vmCvar_t  ui_voteActive; 
    234224vmCvar_t  ui_alienTeamVoteActive; 
     
    310300  { &cg_thirdPerson, "cg_thirdPerson", "0", CVAR_CHEAT }, 
    311301  { &cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE  }, 
    312   { &cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE }, 
    313302  { &cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE }, 
    314303  { &cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE }, 
     
    319308  { &cg_noVoiceChats, "cg_noVoiceChats", "0", CVAR_ARCHIVE }, 
    320309  { &cg_noVoiceText, "cg_noVoiceText", "0", CVAR_ARCHIVE }, 
    321   { &cg_creepRes, "cg_creepRes", "16", CVAR_ARCHIVE }, 
    322310  { &cg_drawSurfNormal, "cg_drawSurfNormal", "0", CVAR_CHEAT }, 
    323311  { &cg_drawBBOX, "cg_drawBBOX", "0", CVAR_CHEAT }, 
     
    348336  { &ui_stages, "ui_stages", "0 0", 0 }, 
    349337  { &ui_dialog, "ui_dialog", "Text not set", 0 }, 
    350   { &ui_loading, "ui_loading", "0", 0 }, 
    351338  { &ui_voteActive, "ui_voteActive", "0", 0 }, 
    352339  { &ui_humanTeamVoteActive, "ui_humanTeamVoteActive", "0", 0 }, 
     
    370357  { &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0}, 
    371358  { &cg_timescale, "timescale", "1", 0}, 
    372   { &cg_scorePlum, "cg_scorePlums", "1", CVAR_USERINFO | CVAR_ARCHIVE}, 
    373359  { &cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE}, 
    374360  { &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT}, 
     
    384370  { &cg_oldPlasma, "cg_oldPlasma", "1", CVAR_ARCHIVE}, 
    385371  { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE} 
    386 //  { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE } 
    387372}; 
    388373 
     
    413398  cgs.localServer = atoi( var ); 
    414399  forceModelModificationCount = cg_forceModel.modificationCount; 
    415  
    416   trap_Cvar_Register( NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); 
    417   trap_Cvar_Register( NULL, "headmodel", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); 
    418   trap_Cvar_Register( NULL, "team_model", DEFAULT_TEAM_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); 
    419   trap_Cvar_Register( NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE ); 
    420400} 
    421401 
     
    443423} 
    444424 
     425/* 
     426=============== 
     427CG_SetUIVars 
     428 
     429Set some cvars used by the UI 
     430=============== 
     431*/ 
     432static void CG_SetUIVars( void ) 
     433{ 
     434  int   i; 
     435  char  carriageCvar[ MAX_TOKEN_CHARS ]; 
     436 
     437  if( !cg.snap ) 
     438    return; 
     439 
     440  *carriageCvar = 0; 
     441 
     442  //determine what the player is carrying 
     443  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
     444  { 
     445    if( BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) && 
     446        BG_FindPurchasableForWeapon( i ) ) 
     447      strcat( carriageCvar, va( "W%d ", i ) ); 
     448  } 
     449  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
     450  { 
     451    if( BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) && 
     452        BG_FindPurchasableForUpgrade( i ) ) 
     453      strcat( carriageCvar, va( "U%d ", i ) ); 
     454  } 
     455  strcat( carriageCvar, "$" ); 
     456 
     457  trap_Cvar_Set( "ui_carriage", carriageCvar ); 
     458 
     459  trap_Cvar_Set( "ui_stages", va( "%d %d", cgs.alienStage, cgs.humanStage ) ); 
     460} 
    445461 
    446462/* 
     
    465481    CG_ForceModelChange( ); 
    466482  } 
     483 
     484  CG_SetUIVars( ); 
    467485} 
    468486 
     
    484502  return cg.snap->ps.persistant[ PERS_ATTACKER ]; 
    485503} 
     504 
    486505 
    487506/* 
     
    15341553      case 6: 
    15351554        if( sp->ping == -1 ) 
    1536           return "connecting"; 
     1555          return ""; 
    15371556 
    15381557        return va( "%4d", sp->ping ); 
     
    15791598                              int cursorPos, char cursor, int limit, int style ) 
    15801599{ 
    1581   CG_Text_Paint( x, y, scale, color, text, 0, limit, style ); 
     1600  UI_Text_Paint( x, y, scale, color, text, 0, limit, style ); 
    15821601} 
    15831602 
     
    15871606  { 
    15881607    case CG_KILLER: 
    1589       return CG_Text_Width( CG_GetKillerText( ), scale, 0 ); 
     1608      return UI_Text_Width( CG_GetKillerText( ), scale, 0 ); 
    15901609      break; 
    15911610  } 
     
    16301649  char        buff[ 1024 ]; 
    16311650  const char  *hudSet; 
     1651 
     1652  cgDC.aspectScale = ( ( 640.0f * cgs.glconfig.vidHeight ) / 
     1653                       ( 480.0f * cgs.glconfig.vidWidth ) ); 
     1654  cgDC.xscale = cgs.glconfig.vidWidth / 640.0f; 
     1655  cgDC.yscale = cgs.glconfig.vidHeight / 480.0f; 
    16321656 
    16331657  cgDC.registerShaderNoMip  = &trap_R_RegisterShaderNoMip; 
     
    16351659  cgDC.drawHandlePic        = &CG_DrawPic; 
    16361660  cgDC.drawStretchPic       = &trap_R_DrawStretchPic; 
    1637   cgDC.drawText             = &CG_Text_Paint; 
    1638   cgDC.textWidth            = &CG_Text_Width; 
    1639   cgDC.textHeight           = &CG_Text_Height; 
    16401661  cgDC.registerModel        = &trap_R_RegisterModel; 
    16411662  cgDC.modelBounds          = &trap_R_ModelBounds; 
     
    16521673  cgDC.ownerDrawVisible     = &CG_OwnerDrawVisible; 
    16531674  cgDC.runScript            = &CG_RunMenuScript; 
    1654   cgDC.getTeamColor         = &CG_GetTeamColor; 
    16551675  cgDC.setCVar              = trap_Cvar_Set; 
    16561676  cgDC.getCVarString        = trap_Cvar_VariableStringBuffer; 
    16571677  cgDC.getCVarValue         = CG_Cvar_Get; 
    1658   cgDC.drawTextWithCursor   = &CG_Text_PaintWithCursor; 
    1659   //cgDC.setOverstrikeMode    = &trap_Key_SetOverstrikeMode; 
    1660   //cgDC.getOverstrikeMode    = &trap_Key_GetOverstrikeMode; 
     1678  cgDC.setOverstrikeMode    = &trap_Key_SetOverstrikeMode; 
     1679  cgDC.getOverstrikeMode    = &trap_Key_GetOverstrikeMode; 
    16611680  cgDC.startLocalSound      = &trap_S_StartLocalSound; 
    16621681  cgDC.ownerDrawHandleKey   = &CG_OwnerDrawHandleKey; 
     
    16721691  cgDC.Print                = &Com_Printf; 
    16731692  cgDC.ownerDrawWidth       = &CG_OwnerDrawWidth; 
     1693  //cgDC.ownerDrawText        = &CG_OwnerDrawText; 
    16741694  //cgDC.Pause                = &CG_Pause; 
    16751695  cgDC.registerSound        = &trap_S_RegisterSound; 
     
    17301750  cgs.serverCommandSequence = serverCommandSequence; 
    17311751 
     1752  // get the rendering configuration from the client system 
     1753  trap_GetGlconfig( &cgs.glconfig ); 
     1754  cgs.screenXScale = cgs.glconfig.vidWidth / 640.0f; 
     1755  cgs.screenYScale = cgs.glconfig.vidHeight / 480.0f; 
     1756 
    17321757  // load a few needed things before we do any screen updates 
    17331758  cgs.media.whiteShader     = trap_R_RegisterShader( "white" ); 
     
    17351760  cgs.media.outlineShader   = trap_R_RegisterShader( "outline" ); 
    17361761 
    1737   //inform UI to repress cursor whilst loading 
    1738   trap_Cvar_Set( "ui_loading", "1" ); 
    1739  
    17401762  // load overrides 
    17411763  BG_InitClassOverrides( ); 
     
    17601782  // old servers 
    17611783 
    1762   // get the rendering configuration from the client system 
    1763   trap_GetGlconfig( &cgs.glconfig ); 
    1764   cgs.screenXScale = cgs.glconfig.vidWidth / 640.0; 
    1765   cgs.screenYScale = cgs.glconfig.vidHeight / 480.0; 
    1766  
    17671784  // get the gamestate from the client system 
    17681785  trap_GetGameState( &cgs.gameState ); 
     
    18211838 
    18221839  trap_S_ClearLoopingSounds( qtrue ); 
    1823  
    1824   trap_Cvar_Set( "ui_loading", "0" ); 
    18251840} 
    18261841 
  • src/cgame/cg_players.c

    r119 r123  
    19451945  float         shadowPlane; 
    19461946  entityState_t *es = &cent->currentState; 
    1947   pClass_t      class = ( es->misc >> 8 ) & 0xFF; 
     1947  pClass_t      class = ( es->powerups >> 8 ) & 0xFF; 
    19481948  float         scale; 
    19491949  vec3_t        tempAxis[ 3 ], tempAxis2[ 3 ]; 
  • src/cgame/cg_players.c

    r122 r123  
    485485  } 
    486486 
    487   //FIXME: skins do not load without icon present. do we want icons anyway? 
    488 /*  Com_sprintf( filename, sizeof( filename ), "models/players/%s/icon_%s.tga", modelName, skinName ); 
    489   ci->modelIcon = trap_R_RegisterShaderNoMip( filename ); 
    490   if( !ci->modelIcon ) 
    491   { 
    492     Com_Printf( "Failed to load icon file: %s\n", filename ); 
    493     return qfalse; 
    494   }*/ 
    495  
    496487  return qtrue; 
    497488} 
     
    536527static void CG_LoadClientInfo( clientInfo_t *ci ) 
    537528{ 
    538   const char  *dir, *fallback; 
     529  const char  *dir; 
    539530  int         i; 
    540531  const char  *s; 
     
    542533 
    543534  if( !CG_RegisterClientModelname( ci, ci->modelName, ci->skinName ) ) 
    544   { 
    545     if( cg_buildScript.integer ) 
    546       CG_Error( "CG_RegisterClientModelname( %s, %s ) failed", ci->modelName, ci->skinName ); 
    547  
    548     // fall back 
    549     if( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default" ) ) 
    550       CG_Error( "DEFAULT_MODEL (%s) failed to register", DEFAULT_MODEL ); 
    551   } 
     535    CG_Error( "CG_RegisterClientModelname( %s, %s ) failed", ci->modelName, ci->skinName ); 
    552536 
    553537  // sounds 
    554538  dir = ci->modelName; 
    555   fallback = DEFAULT_MODEL; 
    556539 
    557540  for( i = 0; i < MAX_CUSTOM_SOUNDS; i++ ) 
     
    579562 
    580563        ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse ); 
    581         if( !ci->sounds[ i ] ) 
    582           ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse ); 
    583564      } 
    584565    } 
     
    586567    { 
    587568      ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", dir, s + 1 ), qfalse ); 
    588       if( !ci->sounds[ i ] ) 
    589         ci->sounds[ i ] = trap_S_RegisterSound( va( "sound/player/%s/%s", fallback, s + 1 ), qfalse ); 
    590569    } 
    591570  } 
     
    729708  // model 
    730709  Q_strncpyz( newInfo.modelName, model, sizeof( newInfo.modelName ) ); 
    731   Q_strncpyz( newInfo.headModelName, model, sizeof( newInfo.headModelName ) ); 
    732  
    733   // modelName didn not include a skin name 
     710 
     711  // modelName did not include a skin name 
    734712  if( !skin ) 
    735   { 
    736713    Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) ); 
    737     Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) ); 
    738   } 
    739   else 
    740   { 
     714  else 
    741715    Q_strncpyz( newInfo.skinName, skin, sizeof( newInfo.skinName ) ); 
    742     Q_strncpyz( newInfo.headSkinName, skin, sizeof( newInfo.headSkinName ) ); 
    743   } 
    744716 
    745717  newInfo.infoValid = qtrue; 
     
    787759  CG_ColorFromString( v, newInfo.color2 ); 
    788760 
    789   // bot skill 
    790   v = Info_ValueForKey( configstring, "skill" ); 
    791   newInfo.botSkill = atoi( v ); 
    792  
    793761  // handicap 
    794762  v = Info_ValueForKey( configstring, "hc" ); 
    795763  newInfo.handicap = atoi( v ); 
    796764 
    797   // wins 
    798   v = Info_ValueForKey( configstring, "w" ); 
    799   newInfo.wins = atoi( v ); 
    800  
    801   // losses 
    802   v = Info_ValueForKey( configstring, "l" ); 
    803   newInfo.losses = atoi( v ); 
    804  
    805765  // team 
    806766  v = Info_ValueForKey( configstring, "t" ); 
    807767  newInfo.team = atoi( v ); 
    808768 
    809   // team task 
    810   v = Info_ValueForKey( configstring, "tt" ); 
    811   newInfo.teamTask = atoi( v ); 
    812  
    813   // team leader 
    814   v = Info_ValueForKey( configstring, "tl" ); 
    815   newInfo.teamLeader = atoi( v ); 
    816  
    817769  // model 
    818770  v = Info_ValueForKey( configstring, "model" ); 
     
    829781  { 
    830782    Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) ); 
    831     // truncate modelName 
    832     *slash = 0; 
    833   } 
    834  
    835   //CG_Printf( "NCI: %s\n", v ); 
    836  
    837   // head model 
    838   v = Info_ValueForKey( configstring, "hmodel" ); 
    839   Q_strncpyz( newInfo.headModelName, v, sizeof( newInfo.headModelName ) ); 
    840  
    841   slash = strchr( newInfo.headModelName, '/' ); 
    842  
    843   if( !slash ) 
    844   { 
    845     // modelName didn not include a skin name 
    846     Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) ); 
    847   } 
    848   else 
    849   { 
    850     Q_strncpyz( newInfo.headSkinName, slash + 1, sizeof( newInfo.headSkinName ) ); 
    851783    // truncate modelName 
    852784    *slash = 0; 
  • src/cgame/cg_predict.c

    r119 r123  
    139139 
    140140      if( i == cg_numSolidEntities ) 
    141         BG_FindBBoxForClass( ( ent->misc >> 8 ) & 0xFF, bmins, bmaxs, NULL, NULL, NULL ); 
     141        BG_FindBBoxForClass( ( ent->powerups >> 8 ) & 0xFF, bmins, bmaxs, NULL, NULL, NULL ); 
    142142 
    143143      cmodel = trap_CM_TempBoxModel( bmins, bmaxs ); 
  • src/cgame/cg_predict.c

    r122 r123  
    584584 
    585585  if( cg_pmove.ps->pm_type == PM_DEAD ) 
    586     cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; 
     586    cg_pmove.tracemask = MASK_DEADSOLID; 
    587587  else 
    588588    cg_pmove.tracemask = MASK_PLAYERSOLID; 
    589589 
    590590  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) 
    591     cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies 
     591    cg_pmove.tracemask = MASK_DEADSOLID; // spectators can fly through bodies 
    592592 
    593593  cg_pmove.noFootsteps = 0; 
  • src/cgame/cg_public.h

    r119 r123  
    139139  CG_KEY_SETCATCHER, 
    140140  CG_KEY_GETKEY, 
     141  CG_PARSE_ADD_GLOBAL_DEFINE, 
     142  CG_PARSE_LOAD_SOURCE, 
     143  CG_PARSE_FREE_SOURCE, 
     144  CG_PARSE_READ_TOKEN, 
     145  CG_PARSE_SOURCE_FILE_AND_LINE, 
    141146  CG_S_STOPBACKGROUNDTRACK, 
    142147  CG_REAL_TIME, 
     
    173178  CG_KEY_SETBINDING, 
    174179 
    175   CG_PARSE_ADD_GLOBAL_DEFINE, 
    176   CG_PARSE_LOAD_SOURCE, 
    177   CG_PARSE_FREE_SOURCE, 
    178   CG_PARSE_READ_TOKEN, 
    179   CG_PARSE_SOURCE_FILE_AND_LINE, 
    180  
    181180  CG_KEY_SETOVERSTRIKEMODE, 
    182181  CG_KEY_GETOVERSTRIKEMODE, 
  • src/cgame/cg_public.h

    r1 r123  
    178178  CG_KEY_SETBINDING, 
    179179 
     180  CG_KEY_SETOVERSTRIKEMODE, 
     181  CG_KEY_GETOVERSTRIKEMODE, 
     182 
    180183  CG_MEMSET = 200, 
    181184  CG_MEMCPY, 
     
    229232  // If demoPlayback is set, local movement prediction will not be enabled 
    230233 
    231   CG_CROSSHAIR_PLAYER, 
    232   // int (*CG_CrosshairPlayer)( void ); 
    233  
    234   CG_LAST_ATTACKER, 
    235   // int (*CG_LastAttacker)( void ); 
    236  
    237234  CG_KEY_EVENT, 
    238235  // void  (*CG_KeyEvent)( int key, qboolean down ); 
  • src/cgame/cg_scanner.c

    r119 r123  
    8383    else if( cent->currentState.eType == ET_PLAYER ) 
    8484    { 
    85       int team = cent->currentState.misc & 0x00FF; 
     85      int team = cent->currentState.powerups & 0x00FF; 
    8686 
    8787      if( team == PTE_ALIENS ) 
  • src/cgame/cg_scanner.c

    r122 r123  
    2424#include "cg_local.h" 
    2525 
    26 static entityPos_t   entityPositions; 
     26static entityPos_t entityPositions; 
    2727 
    2828#define HUMAN_SCANNER_UPDATE_PERIOD 700 
     
    105105} 
    106106 
    107 #define STALKWIDTH  2.0f 
    108 #define BLIPX       16.0f 
     107#define STALKWIDTH  (2.0f * cgDC.aspectScale) 
     108#define BLIPX       (16.0f * cgDC.aspectScale) 
    109109#define BLIPY       8.0f 
    110110#define FAR_ALPHA   0.8f 
     
    163163} 
    164164 
    165 #define BLIPX2  24.0f 
     165#define BLIPX2  (24.0f * cgDC.aspectScale) 
    166166#define BLIPY2  24.0f 
    167167 
  • src/cgame/cg_servercmds.c

    r119 r123  
    501501      break; 
    502502 
    503     case MN_A_TEAMCHANGEBUILDTIMER: 
    504       longMsg   = "You cannot leave the Alien team until your build timer " 
    505                   "has expired."; 
    506       shortMsg  = "You cannot change teams until your build timer expires.\n"; 
    507       cmd       = "menu tremulous_alien_dialog\n"; 
    508       break; 
    509  
    510     case MN_H_TEAMCHANGEBUILDTIMER: 
    511       longMsg   = "You cannot leave the Human team until your build timer " 
    512                   "has expired."; 
    513       shortMsg  = "You cannot change teams until your build timer expires.\n"; 
    514       cmd       = "menu tremulous_human_dialog\n"; 
    515       break; 
    516503 
    517504    //=============================== 
     
    608595      break; 
    609596 
    610     case MN_H_NOARMOURYHERE: 
    611       longMsg   = "You must be near a powered Armoury in order to purchase " 
    612                   "weapons, upgrades or non-energy ammunition."; 
    613       shortMsg  = "You must be near a powered Armoury\n"; 
    614       cmd       = "menu tremulous_human_dialog\n"; 
    615       break; 
    616  
    617     case MN_H_NOENERGYAMMOHERE: 
    618       longMsg   = "You must be near an Armoury, Reactor or Repeater in order " 
    619                   "to purchase energy ammunition."; 
    620       shortMsg  = "You must be near an Armoury, Reactor or Repeater\n"; 
    621       cmd       = "menu tremulous_human_dialog\n"; 
    622       break; 
    623  
    624     case MN_H_NOROOMBSUITON: 
    625       longMsg   = "There is not enough room here to put on a Battle Suit. " 
    626                   "Make sure you have enough head room to climb in."; 
    627       shortMsg  = "Not enough room here to put on a Battle Suit\n"; 
    628       cmd       = "menu tremulous_human_dialog\n"; 
    629       break; 
    630  
    631     case MN_H_NOROOMBSUITOFF: 
    632       longMsg   = "There is not enough room here to take off your Battle Suit. " 
    633                   "Make sure you have enough head room to climb out."; 
    634       shortMsg  = "Not enough room here to take off your Battle Suit\n"; 
    635       cmd       = "menu tremulous_human_dialog\n"; 
    636       break; 
    637  
    638     case MN_H_ARMOURYBUILDTIMER: 
    639       longMsg   = "You are not allowed to buy or sell weapons until your " 
    640                   "build timer has expired."; 
    641       shortMsg  = "You can not buy or sell weapos until your build timer " 
    642                   "expires\n"; 
    643       cmd       = "menu tremulous_human_dialog\n"; 
    644       break; 
    645  
    646597 
    647598    //=============================== 
     
    723674                  "you to upgrade."; 
    724675      shortMsg  = "There is no Overmind\n"; 
    725       cmd       = "menu tremulous_alien_dialog\n"; 
    726       break; 
    727  
    728     case MN_A_EVOLVEBUILDTIMER: 
    729       longMsg   = "You cannot Evolve until your build timer has expired."; 
    730       shortMsg  = "You cannot Evolve until your build timer expires\n"; 
    731676      cmd       = "menu tremulous_alien_dialog\n"; 
    732677      break; 
     
    862807  } 
    863808 
    864   if( !strcmp( cmd, "map_restart" ) ) 
     809  if( !strcmp( cmd, "restartmap" ) ) 
    865810  { 
    866811    CG_MapRestart( ); 
  • src/cgame/cg_servercmds.c

    r122 r123  
    451451 
    452452/* 
    453 =============== 
    454 CG_SetUIVars 
    455  
    456 Set some cvars used by the UI 
    457 =============== 
    458 */ 
    459 static void CG_SetUIVars( void ) 
    460 { 
    461   int   i; 
    462   char  carriageCvar[ MAX_TOKEN_CHARS ]; 
    463  
    464   *carriageCvar = 0; 
    465  
    466   //determine what the player is carrying 
    467   for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
    468   { 
    469     if( BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) && 
    470         BG_FindPurchasableForWeapon( i ) ) 
    471       strcat( carriageCvar, va( "W%d ", i ) ); 
    472   } 
    473   for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
    474   { 
    475     if( BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) && 
    476         BG_FindPurchasableForUpgrade( i ) ) 
    477       strcat( carriageCvar, va( "U%d ", i ) ); 
    478   } 
    479   strcat( carriageCvar, "$" ); 
    480  
    481   trap_Cvar_Set( "ui_carriage", carriageCvar ); 
    482  
    483   trap_Cvar_Set( "ui_stages", va( "%d %d", cgs.alienStage, cgs.humanStage ) ); 
    484 } 
    485  
    486  
    487 /* 
    488453============== 
    489454CG_Menu 
     
    495460  const char *longMsg   = NULL; // command parameter 
    496461  const char *shortMsg  = NULL; // non-modal version of message 
    497   CG_SetUIVars( ); 
    498  
    499   // string literals have static storage duration, this is safe, 
    500   // cleaner and much more readable. 
     462 
    501463  switch( menu ) 
    502464  { 
  • src/cgame/cg_syscalls.asm

    r1 r123  
    6565equ trap_Key_SetCatcher               -63 
    6666equ trap_Key_GetKey                   -64 
    67 equ trap_Parse_AddGlobalDefine        -65 
    68 equ trap_Parse_LoadSource             -66 
    69 equ trap_Parse_FreeSource             -67 
    70 equ trap_Parse_ReadToken              -68 
    71 equ trap_Parse_SourceFileAndLine      -69 
    72 equ trap_S_StopBackgroundTrack        -70 
    73 equ trap_RealTime                     -71 
    74 equ trap_SnapVector                   -72 
    75 equ trap_RemoveCommand                -73 
    76 equ trap_R_LightForPoint              -74 
    77 equ trap_CIN_PlayCinematic            -75 
    78 equ trap_CIN_StopCinematic            -76 
    79 equ trap_CIN_RunCinematic             -77 
    80 equ trap_CIN_DrawCinematic            -78 
    81 equ trap_CIN_SetExtents               -79 
    82 equ trap_R_RemapShader                -80 
    83 equ trap_S_AddRealLoopingSound        -81 
    84 equ trap_S_StopLoopingSound           -82 
    85 equ trap_CM_TempCapsuleModel          -83 
    86 equ trap_CM_CapsuleTrace              -84 
    87 equ trap_CM_TransformedCapsuleTrace   -85 
    88 equ trap_R_AddAdditiveLightToScene    -86 
    89 equ trap_GetEntityToken               -87 
    90 equ trap_R_AddPolysToScene            -88 
    91 equ trap_R_inPVS                      -89 
    92 equ trap_FS_Seek                      -90 
    93 equ trap_FS_GetFileList               -91 
    94 equ trap_LiteralArgs                  -92 
    95 equ trap_CM_BiSphereTrace             -93 
    96 equ trap_CM_TransformedBiSphereTrace  -94 
    97 equ trap_GetDemoState                 -95 
    98 equ trap_GetDemoPos                   -96 
    99 equ trap_GetDemoName                  -97 
    100 equ trap_Key_KeynumToStringBuf        -98 
    101 equ trap_Key_GetBindingBuf            -99 
    102 equ trap_Key_SetBinding               -100 
     67equ trap_S_StopBackgroundTrack        -65 
     68equ trap_RealTime                     -66 
     69equ trap_SnapVector                   -67 
     70equ trap_RemoveCommand                -68 
     71equ trap_R_LightForPoint              -69 
     72equ trap_CIN_PlayCinematic            -70 
     73equ trap_CIN_StopCinematic            -71 
     74equ trap_CIN_RunCinematic             -72 
     75equ trap_CIN_DrawCinematic            -73 
     76equ trap_CIN_SetExtents               -74 
     77equ trap_R_RemapShader                -75 
     78equ trap_S_AddRealLoopingSound        -76 
     79equ trap_S_StopLoopingSound           -77 
     80equ trap_CM_TempCapsuleModel          -78 
     81equ trap_CM_CapsuleTrace              -79 
     82equ trap_CM_TransformedCapsuleTrace   -80 
     83equ trap_R_AddAdditiveLightToScene    -81 
     84equ trap_GetEntityToken               -82 
     85equ trap_R_AddPolysToScene            -83 
     86equ trap_R_inPVS                      -84 
     87equ trap_FS_Seek                      -85 
     88equ trap_FS_GetFileList               -86 
     89equ trap_LiteralArgs                  -87 
     90equ trap_CM_BiSphereTrace             -88 
     91equ trap_CM_TransformedBiSphereTrace  -89 
     92equ trap_GetDemoState                 -90 
     93equ trap_GetDemoPos                   -91 
     94equ trap_GetDemoName                  -92 
     95equ trap_Key_KeynumToStringBuf        -93 
     96equ trap_Key_GetBindingBuf            -94 
     97equ trap_Key_SetBinding               -95 
     98 
     99equ trap_Parse_AddGlobalDefine        -96 
     100equ trap_Parse_LoadSource             -97 
     101equ trap_Parse_FreeSource             -98 
     102equ trap_Parse_ReadToken              -99 
     103equ trap_Parse_SourceFileAndLine      -100 
     104equ trap_Key_SetOverstrikeMode        -101 
     105equ trap_Key_GetOverstrikeMode        -102 
    103106 
    104107equ memset                            -201 
  • src/cgame/cg_tutorial.c

    r119 r123  
    419419{ 
    420420  char      *name; 
     421  int       ammo, clips; 
    421422  upgrade_t upgrade = UP_NONE; 
    422423 
     
    429430  } 
    430431 
    431   if( !ps->ammo && !ps->clips && !BG_FindInfinteAmmoForWeapon( ps->weapon ) ) 
     432  BG_UnpackAmmoArray( ps->weapon, ps->ammo, ps->powerups, &ammo, &clips ); 
     433 
     434  if( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( ps->weapon ) ) 
    432435  { 
    433436    //no ammo 
  • src/cgame/cg_tutorial.c

    r122 r123  
    650650 
    651651        case PCL_HUMAN: 
     652        case PCL_HUMAN_BSUIT: 
    652653          CG_HumanText( text, ps ); 
    653654          break; 
  • src/cgame/cg_weapons.c

    r119 r123  
    11951195  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
    11961196  { 
     1197    int ammo, clips; 
     1198 
    11971199    if( !BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) ) 
    11981200      continue; 
    11991201 
    1200     if( !ps->ammo && !ps->clips && !BG_FindInfinteAmmoForWeapon( i ) ) 
     1202    BG_UnpackAmmoArray( i, cg.snap->ps.ammo, cg.snap->ps.powerups, &ammo, &clips ); 
     1203 
     1204    if( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( i ) ) 
    12011205      colinfo[ numItems ] = 1; 
    12021206    else 
  • src/cgame/cg_weapons.c

    r122 r123  
    11411141{ 
    11421142  int           i; 
    1143   int           x = rect->x; 
    1144   int           y = rect->y; 
    1145   int           width = rect->w; 
    1146   int           height = rect->h; 
    1147   int           iconsize; 
     1143  float         x = rect->x; 
     1144  float         y = rect->y; 
     1145  float         width = rect->w; 
     1146  float         height = rect->h; 
     1147  float         iconWidth; 
     1148  float         iconHeight; 
    11481149  int           items[ 64 ]; 
    11491150  int           numItems = 0, selectedItem = 0; 
     
    11781179  { 
    11791180    vertical = qtrue; 
    1180     iconsize = width; 
    1181     length = height / width; 
     1181    iconWidth = width * cgDC.aspectScale; 
     1182    iconHeight = width; 
     1183    length = height / ( width * cgDC.aspectScale ); 
    11821184  } 
    11831185  else if( height <= width ) 
    11841186  { 
    11851187    vertical = qfalse; 
    1186     iconsize = height; 
    1187     length = width / height; 
     1188    iconWidth = height * cgDC.aspectScale; 
     1189    iconHeight = height; 
     1190    length = width / ( height * cgDC.aspectScale ); 
    11881191  } 
    11891192 
     
    12531256 
    12541257      if( items[ item ] <= 32 ) 
    1255         CG_DrawPic( x, y, iconsize, iconsize, cg_weapons[ items[ item ] ].weaponIcon ); 
     1258        CG_DrawPic( x, y, iconWidth, iconHeight, cg_weapons[ items[ item ] ].weaponIcon ); 
    12561259      else if( items[ item ] > 32 ) 
    1257         CG_DrawPic( x, y, iconsize, iconsize, cg_upgrades[ items[ item ] - 32 ].upgradeIcon ); 
     1260        CG_DrawPic( x, y, iconWidth, iconHeight, cg_upgrades[ items[ item ] - 32 ].upgradeIcon ); 
    12581261 
    12591262      trap_R_SetColor( NULL ); 
     
    12611264 
    12621265    if( vertical ) 
    1263       y += iconsize; 
     1266      y += iconHeight; 
    12641267    else 
    1265       x += iconsize; 
     1268      x += iconWidth; 
    12661269  } 
    12671270} 
     
    12931296      if( ( name = cg_weapons[ cg.weaponSelect ].humanName ) ) 
    12941297      { 
    1295         w = CG_Text_Width( name, scale, 0 ); 
     1298        w = UI_Text_Width( name, scale, 0 ); 
    12961299        x = rect->x + rect->w / 2; 
    1297         CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); 
     1300        UI_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); 
    12981301      } 
    12991302    } 
     
    13061309      if( ( name = cg_upgrades[ cg.weaponSelect - 32 ].humanName ) ) 
    13071310      { 
    1308         w = CG_Text_Width( name, scale, 0 ); 
     1311        w = UI_Text_Width( name, scale, 0 ); 
    13091312        x = rect->x + rect->w / 2; 
    1310         CG_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); 
     1313        UI_Text_Paint( x - w / 2, rect->y + rect->h, scale, color, name, 0, 0, textStyle ); 
    13111314      } 
    13121315    } 
  • src/client/cl_cgame.c

    r119 r123  
    332332        } 
    333333 
    334         if ( !strcmp( cmd, "map_restart" ) ) { 
     334        if ( !strcmp( cmd, "restartmap" ) ) { 
    335335                // clear notify lines and outgoing commands before passing 
    336336                // the restart to the cgame 
  • src/client/cl_cgame.c

    r54 r123  
    386386*/ 
    387387void CL_ShutdownCGame( void ) { 
    388         cls.keyCatchers &= ~KEYCATCH_CGAME; 
     388        Key_SetCatcher( Key_GetCatcher( ) & ~KEYCATCH_CGAME ); 
    389389        cls.cgameStarted = qfalse; 
    390390        if ( !cgvm ) { 
     
    620620                return Key_GetCatcher(); 
    621621  case CG_KEY_SETCATCHER: 
    622                 Key_SetCatcher( args[1] ); 
     622                // Don't allow the cgame module to close the console 
     623                Key_SetCatcher( args[1] | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ); 
    623624    return 0; 
    624625  case CG_KEY_GETKEY: 
     
    653654        case CG_PARSE_SOURCE_FILE_AND_LINE: 
    654655                return Parse_SourceFileAndLine( args[1], VMA(2), VMA(3) ); 
     656 
     657        case CG_KEY_SETOVERSTRIKEMODE: 
     658                Key_SetOverstrikeMode( args[1] ); 
     659    return 0; 
     660        case CG_KEY_GETOVERSTRIKEMODE: 
     661                return Key_GetOverstrikeMode( ); 
    655662 
    656663        case CG_MEMSET: 
  • src/client/cl_main.c

    r119 r123  
    3131cvar_t  *cl_noprint; 
    3232cvar_t  *cl_motd; 
    33  
     33cvar_t  *cl_master; 
    3434cvar_t  *rcon_client_password; 
    3535cvar_t  *rconAddress; 
     
    983983                return; 
    984984        } 
    985         Com_Printf( "Resolving %s\n", MASTER_SERVER_NAME ); 
    986         if ( !NET_StringToAdr( MASTER_SERVER_NAME, &cls.updateServer  ) ) { 
     985        Com_Printf( "Resolving %s\n", cl_master->string ); 
     986        if ( !NET_StringToAdr( cl_master->string, &cls.updateServer  ) ) { 
    987987                Com_Printf( "Couldn't resolve address\n" ); 
    988988                return; 
    989989        } 
    990990        cls.updateServer.port = BigShort( PORT_MASTER ); 
    991         Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", MASTER_SERVER_NAME, 
     991        Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", cl_master->string, 
    992992                cls.updateServer.ip[0], cls.updateServer.ip[1], 
    993993                cls.updateServer.ip[2], cls.updateServer.ip[3], 
     
    26162616        cl_noprint = Cvar_Get( "cl_noprint", "0", 0 ); 
    26172617        cl_motd = Cvar_Get ("cl_motd", "1", 0); 
    2618  
     2618  cl_master = Cvar_Get("cl_master","master.tremulous.net",CVAR_ARCHIVE); 
    26192619        cl_timeout = Cvar_Get ("cl_timeout", "200", 0); 
    26202620 
     
    32133213 
    32143214        if( cls.masterNum == 1 ) { 
    3215                 NET_StringToAdr( MASTER_SERVER_NAME, &to ); 
     3215                NET_StringToAdr( cl_master->string, &to ); 
    32163216                cls.nummplayerservers = -1; 
    32173217                cls.pingUpdateSource = AS_MPLAYER; 
    32183218        } 
    32193219        else { 
    3220                 NET_StringToAdr( MASTER_SERVER_NAME, &to ); 
     3220                NET_StringToAdr( cl_master->string, &to ); 
    32213221                cls.numglobalservers = -1; 
    32223222                cls.pingUpdateSource = AS_GLOBAL; 
  • src/client/cl_main.c

    r122 r123  
    654654        // start the demo loop again 
    655655        Cbuf_AddText ("d1\n"); 
    656         cls.keyCatchers = 0; 
     656        Key_SetCatcher( 0 ); 
    657657} 
    658658 
     
    799799        if ( com_dedicated->integer ) { 
    800800                cls.state = CA_DISCONNECTED; 
    801                 cls.keyCatchers = KEYCATCH_CONSOLE; 
     801                Key_SetCatcher( KEYCATCH_CONSOLE ); 
    802802                return; 
    803803        } 
     
    808808 
    809809        Con_Close(); 
    810         cls.keyCatchers = 0; 
     810        Key_SetCatcher( 0 ); 
    811811 
    812812        // if we are already connected to the local host, stay connected 
     
    822822                Q_strncpyz( cls.servername, "localhost", sizeof(cls.servername) ); 
    823823                cls.state = CA_CHALLENGING;             // so the connect screen is drawn 
    824                 cls.keyCatchers = 0; 
     824                Key_SetCatcher( 0 ); 
    825825                SCR_UpdateScreen(); 
    826826                clc.connectTime = -RETRANSMIT_TIMEOUT; 
     
    11701170        } 
    11711171 
    1172         cls.keyCatchers = 0; 
     1172        Key_SetCatcher( 0 ); 
    11731173        clc.connectTime = -99999;       // CL_CheckForResend() will fire immediately 
    11741174        clc.connectPacketCount = 0; 
     
    21822182#endif 
    21832183 
    2184         if ( cls.state == CA_DISCONNECTED && !( cls.keyCatchers & KEYCATCH_UI ) 
     2184        if ( cls.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI ) 
    21852185                && !com_sv_running->integer ) { 
    21862186                // if disconnected, bring up the menu 
     
    25992599*/ 
    26002600void CL_Init( void ) { 
    2601         const char  *playerName; 
    2602  
    26032601        Com_Printf( "----- Client Initialization -----\n" ); 
    26042602 
     
    26922690 
    26932691        // userinfo 
    2694         playerName = getenv( "USER" );                          // Unixy stuff 
    2695         if( playerName == NULL ) 
    2696         { 
    2697                 playerName = getenv( "USERNAME" );      // Windows 
    2698                 if( playerName == NULL ) 
    2699                 { 
    2700                         playerName = "Newbie";                                          // Default 
    2701                 } 
    2702         } 
    2703         Cvar_Get ("name", playerName, CVAR_USERINFO | CVAR_ARCHIVE ); 
     2692        Cvar_Get ("name", Sys_GetCurrentUser( ), CVAR_USERINFO | CVAR_ARCHIVE ); 
    27042693 
    27052694        Cvar_Get ("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE ); 
    27062695        Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE ); 
    2707         Cvar_Get ("model", "sarge", CVAR_USERINFO | CVAR_ARCHIVE ); 
    2708         Cvar_Get ("headmodel", "sarge", CVAR_USERINFO | CVAR_ARCHIVE ); 
    2709         Cvar_Get ("team_model", "james", CVAR_USERINFO | CVAR_ARCHIVE ); 
    2710         Cvar_Get ("team_headmodel", "*james", CVAR_USERINFO | CVAR_ARCHIVE ); 
    27112696        Cvar_Get ("color1",  "4", CVAR_USERINFO | CVAR_ARCHIVE ); 
    27122697        Cvar_Get ("color2", "5", CVAR_USERINFO | CVAR_ARCHIVE ); 
    27132698        Cvar_Get ("handicap", "100", CVAR_USERINFO | CVAR_ARCHIVE ); 
    2714         Cvar_Get ("teamtask", "0", CVAR_USERINFO ); 
    27152699        Cvar_Get ("sex", "male", CVAR_USERINFO | CVAR_ARCHIVE ); 
    2716         Cvar_Get ("cl_anonymous", "0", CVAR_USERINFO | CVAR_ARCHIVE ); 
    27172700 
    27182701        Cvar_Get ("password", "", CVAR_USERINFO); 
    2719         Cvar_Get ("cg_predictItems", "1", CVAR_USERINFO | CVAR_ARCHIVE ); 
    27202702 
    27212703 
     
    28212803 
    28222804        Com_Memset( &cls, 0, sizeof( cls ) ); 
     2805        Key_SetCatcher( 0 ); 
    28232806 
    28242807        Com_Printf( "-----------------------\n" ); 
  • src/client/client.h

    r119 r123  
    345345extern  cvar_t  *cl_showTimeDelta; 
    346346extern  cvar_t  *cl_freezeDemo; 
     347extern  cvar_t  *cl_master; 
    347348 
    348349extern  cvar_t  *cl_yawspeed; 
  • src/client/client.h

    r122 r123  
    271271typedef struct { 
    272272        connstate_t     state;                          // connection status 
    273         int                     keyCatchers;            // bit flags 
    274273 
    275274        qboolean        cddialog;                       // bring up the cd needed dialog next frame 
     
    446445float CL_KeyState (kbutton_t *key); 
    447446char *Key_KeynumToString (int keynum); 
     447int Key_GetCatcher( void ); 
     448void Key_SetCatcher( int catcher ); 
    448449 
    449450// 
  • src/game/g_active.c

    r119 r123  
    376376  pmove_t pm; 
    377377  gclient_t *client; 
     378  qboolean      doPmove = qtrue; 
    378379 
    379380  client = ent->client; 
     
    382383  client->buttons = ucmd->buttons; 
    383384 
    384   if( client->sess.spectatorState != SPECTATOR_FOLLOW ) 
    385   { 
    386     if( client->sess.spectatorState == SPECTATOR_LOCKED ) 
    387       client->ps.pm_type = PM_FREEZE; 
    388     else 
    389       client->ps.pm_type = PM_SPECTATOR; 
    390  
     385  if( client->sess.spectatorState == SPECTATOR_LOCKED || client->sess.spectatorState == SPECTATOR_FOLLOW ) 
     386    client->ps.pm_type = PM_FREEZE; 
     387  else 
     388    client->ps.pm_type = PM_SPECTATOR; 
     389 
     390  if ( client->sess.spectatorState == SPECTATOR_FOLLOW ) 
     391  { 
     392    gclient_t *cl; 
     393    if ( client->sess.spectatorClient >= 0 ) 
     394    { 
     395      cl = &level.clients[ client->sess.spectatorClient ]; 
     396      if ( cl->sess.sessionTeam != TEAM_SPECTATOR ) 
     397        doPmove = qfalse; 
     398    } 
     399  } 
     400 
     401  if (doPmove) 
     402  { 
    391403    client->ps.speed = BG_FindSpeedForClass( client->ps.stats[ STAT_PCLASS ] ); 
    392404 
     
    551563 
    552564    if( BG_InventoryContainsUpgrade( UP_JETPACK, client->ps.stats ) && BG_UpgradeIsActive( UP_JETPACK, client->ps.stats ) ) 
     565    { 
     566      //don't run when jetpack on 
    553567      client->ps.stats[ STAT_STATE ] &= ~SS_SPEEDBOOST; 
     568    } 
    554569 
    555570    if( ( client->ps.stats[ STAT_STATE ] & SS_SPEEDBOOST ) && !crouched ) 
     
    666681    if( client->ps.weapon == WP_LUCIFER_CANNON ) 
    667682    { 
     683      int ammo; 
     684 
     685      BG_UnpackAmmoArray( WP_LUCIFER_CANNON, client->ps.ammo, client->ps.powerups, &ammo, NULL ); 
     686 
    668687      if( client->ps.stats[ STAT_MISC ] < LCANNON_TOTAL_CHARGE && ucmd->buttons & BUTTON_ATTACK ) 
    669688        client->ps.stats[ STAT_MISC ] += ( 100.0f / LCANNON_CHARGE_TIME ) * LCANNON_TOTAL_CHARGE; 
     
    672691        client->ps.stats[ STAT_MISC ] = LCANNON_TOTAL_CHARGE; 
    673692 
    674       if( client->ps.stats[ STAT_MISC ] > ( client->ps.ammo * LCANNON_TOTAL_CHARGE ) / 10 ) 
    675         client->ps.stats[ STAT_MISC ] = client->ps.ammo * LCANNON_TOTAL_CHARGE / 10; 
     693      if( client->ps.stats[ STAT_MISC ] > ( ammo * LCANNON_TOTAL_CHARGE ) / 10 ) 
     694        client->ps.stats[ STAT_MISC ] = ammo * LCANNON_TOTAL_CHARGE / 10; 
    676695    } 
    677696 
     
    695714 
    696715          // Let the client know which buildables will be removed by building 
    697           for( i = 0; i < MAX_MISC; i++ ) 
     716          for( i = 0; i < MAX_POWERUPS; i++ ) 
    698717          { 
    699718            if( i < level.numBuildablesForRemoval ) 
    700               client->ps.misc[ i ] = level.markedBuildables[ i ]->s.number; 
     719              client->ps.powerups[ i ] = level.markedBuildables[ i ]->s.number; 
    701720            else 
    702               client->ps.misc[ i ] = 0; 
     721              client->ps.powerups[ i ] = 0; 
    703722          } 
    704723        } 
    705724        else 
    706725        { 
    707           for( i = 0; i < MAX_MISC; i++ ) 
    708             client->ps.misc[ i ] = 0; 
     726          for( i = 0; i < MAX_POWERUPS; i++ ) 
     727            client->ps.powerups[ i ] = 0; 
    709728        } 
    710729 
     730      case WP_BLASTER: 
    711731        //update build timer 
    712732        if( client->ps.stats[ STAT_MISC ] > 0 ) 
     
    732752        { 
    733753          ent->client->medKitHealthToRestore--; 
    734           ent->health++; 
     754          do_health( ent,1 ); 
    735755        } 
    736756        else 
     
    747767          { 
    748768            ent->client->medKitHealthToRestore--; 
    749             ent->health++; 
     769            do_health( ent,1 ); 
    750770 
    751771            client->medKitIncrementTime = level.time + 
     
    762782  { 
    763783    client->time1000 -= 1000; 
     784 
     785    //jetpack power management 
     786    if( BG_InventoryContainsUpgrade( UP_JETPACK, client->ps.stats ) ) 
     787    { 
     788      if(BG_UpgradeIsActive( UP_JETPACK, client->ps.stats ) ) 
     789      { 
     790        if(g_jetpackLimit.integer > 0) 
     791        { 
     792          //decrease jetpack power 
     793          if(client->jetpack_power > 0) 
     794          { 
     795            client->jetpack_power--; 
     796 
     797            //if no power, can't reactive jetpack for a moment 
     798            if(client->jetpack_power == 0) 
     799              client->jetpack_beat = g_jetpackLimit.integer / 10; 
     800          } 
     801        } 
     802      } 
     803      else 
     804      { 
     805        //recover jetpack 
     806        if(client->jetpack_beat > 0) 
     807          client->jetpack_beat--; 
     808        else if( level.reactorPresent && client->jetpack_power < g_jetpackLimit.integer) 
     809          client->jetpack_power++; 
     810      } 
     811    } 
    764812 
    765813    //client is poison clouded 
     
    825873      if( ent->health > 0 && ent->health < client->ps.stats[ STAT_MAX_HEALTH ] && 
    826874          ( ent->lastDamageTime + ALIEN_REGEN_DAMAGE_TIME ) < level.time ) 
    827         ent->health += BG_FindRegenRateForClass( client->ps.stats[ STAT_PCLASS ] ) * modifier; 
     875        do_health( ent,BG_FindRegenRateForClass( client->ps.stats[ STAT_PCLASS ] ) * modifier ); 
    828876 
    829877      if( ent->health > client->ps.stats[ STAT_MAX_HEALTH ] ) 
     
    852900    if( client->ps.weapon == WP_ALEVEL3_UPG ) 
    853901    { 
    854       int maxAmmo; 
     902      int ammo, maxAmmo; 
    855903 
    856904      BG_FindAmmoForWeapon( WP_ALEVEL3_UPG, &maxAmmo, NULL ); 
    857  
    858       if( client->ps.ammo < maxAmmo ) 
    859         client->ps.ammo++; 
     905      BG_UnpackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, &ammo, NULL ); 
     906 
     907      if( ammo < maxAmmo ) 
     908      { 
     909        ammo++; 
     910        BG_PackAmmoArray( WP_ALEVEL3_UPG, client->ps.ammo, client->ps.powerups, ammo, 0 ); 
     911      } 
    860912    } 
    861913  } 
     
    13301382    msec = 200; 
    13311383 
    1332   client->unlaggedTime = ucmd->serverTime; 
     1384  if( ucmd->serverTime < level.time - g_unlagged.integer ) 
     1385     client->unlaggedTime = level.time - g_unlagged.integer; 
     1386  else 
     1387     client->unlaggedTime = ucmd->serverTime; 
    13331388 
    13341389  if( pmove_msec.integer < 8 ) 
     
    13611416    SpectatorThink( ent, ucmd ); 
    13621417    return; 
     1418  } 
     1419 
     1420  if (g_freeFunds.integer) 
     1421  { 
     1422     // give full evo/credits 
     1423     if (client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS) 
     1424     { 
     1425        client->ps.persistant[ PERS_CREDIT ] = ALIEN_MAX_KILLS; 
     1426     } 
     1427     else 
     1428     { 
     1429        client->ps.persistant[ PERS_CREDIT ] = HUMAN_MAX_CREDITS; 
     1430     } 
    13631431  } 
    13641432 
     
    14741542    } 
    14751543 
    1476     //switch jetpack off if no reactor 
    1477     if( !level.reactorPresent ) 
     1544    //switch jetpack off if no power 
     1545    if( g_jetpackLimit.integer && (client->jetpack_beat || !client->jetpack_power)) 
     1546    { 
    14781547      BG_DeactivateUpgrade( UP_JETPACK, client->ps.stats ); 
     1548 
     1549      trap_SendServerCommand( ent - g_entities, 
     1550        "print \"Your jetpack is out of power\n\"" ); 
     1551    } 
    14791552  } 
    14801553 
     
    17651838      cl = &level.clients[ clientNum ]; 
    17661839 
    1767       if( cl->pers.connected == CON_CONNECTED && cl->sess.sessionTeam != TEAM_SPECTATOR ) 
     1840      if( cl->pers.connected == CON_CONNECTED ) 
    17681841      { 
    17691842        flags = ( cl->ps.eFlags & ~( EF_VOTED | EF_TEAMVOTED ) ) | 
    17701843          ( ent->client->ps.eFlags & ( EF_VOTED | EF_TEAMVOTED ) ); 
    17711844        ent->client->ps = cl->ps; 
     1845        ent->client->ps.eFlags = flags; 
    17721846        ent->client->ps.pm_flags |= PMF_FOLLOW; 
    1773         ent->client->ps.eFlags = flags; 
     1847        ent->client->ps.pm_flags &= ~PMF_QUEUED; 
    17741848      } 
    17751849    } 
     
    17891863{ 
    17901864  clientPersistant_t  *pers; 
     1865 
     1866   if (ent->client->pers.floodTimer) 
     1867   { 
     1868     ent->client->pers.floodTimer -= 5; 
     1869     if (ent->client->pers.floodTimer < 0) 
     1870     ent->client->pers.floodTimer = 0; 
     1871   } 
    17911872 
    17921873  if( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) 
     
    18341915} 
    18351916 
    1836  
     1917void do_health( gentity_t *ent, int quantity ) 
     1918{ 
     1919  int i = 0; 
     1920 
     1921  if( ent->health == ent->client->ps.stats[ STAT_MAX_HEALTH ] ) 
     1922    return; 
     1923 
     1924  ent->health += quantity; 
     1925  if( ent->health >= ent->client->ps.stats[ STAT_MAX_HEALTH ] ) 
     1926  { 
     1927    ent->health = ent->client->ps.stats[ STAT_MAX_HEALTH ]; 
     1928    for( i = 0; i < MAX_CLIENTS; i++ ) 
     1929      ent->credits[ i ] = 0; 
     1930  } 
     1931} 
     1932 
  • src/game/g_active.c

    r122 r123  
    413413    pm.ps = &client->ps; 
    414414    pm.cmd = *ucmd; 
    415     pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; // spectators can fly through bodies 
     415    pm.tracemask = MASK_DEADSOLID; // spectators can fly through bodies 
    416416    pm.trace = trap_Trace; 
    417417    pm.pointcontents = trap_PointContents; 
     
    15931593 
    15941594  if( pm.ps->pm_type == PM_DEAD ) 
    1595     pm.tracemask = MASK_PLAYERSOLID; // & ~CONTENTS_BODY; 
     1595    pm.tracemask = MASK_DEADSOLID; 
    15961596 
    15971597  if( pm.ps->stats[ STAT_STATE ] & SS_INFESTING || 
    15981598      pm.ps->stats[ STAT_STATE ] & SS_HOVELING ) 
    1599     pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; 
     1599    pm.tracemask = MASK_DEADSOLID; 
    16001600  else 
    16011601    pm.tracemask = MASK_PLAYERSOLID; 
     
    17571757  } 
    17581758 
    1759   if( level.framenum > client->retriggerArmouryMenu && client->retriggerArmouryMenu ) 
    1760   { 
    1761     G_TriggerMenu( client->ps.clientNum, MN_H_ARMOURY ); 
    1762  
    1763     client->retriggerArmouryMenu = 0; 
    1764   } 
    1765  
    17661759  // Give clients some credit periodically 
    17671760  if( ent->client->lastKillTime + FREEKILL_PERIOD < level.time ) 
  • src/game/g_client.c

    r119 r123  
    8282/* 
    8383=============== 
     84G_CheckGUID 
     85=============== 
     86*/ 
     87qboolean G_ValidGUID(char *in) 
     88{ 
     89  int count = 0; 
     90  while( *in ) 
     91  { 
     92    count ++; 
     93    //check that the char is an alphanumeric one (with uppercased letter) 
     94    if( !((*in >= '0' && *in <= '9') || (*in >= 'A' && *in <= 'F')) ) 
     95      return qfalse; 
     96 
     97    in++; 
     98  } 
     99 
     100  if( count != 32 ) 
     101    return qfalse; 
     102 
     103  return qtrue; 
     104} 
     105 
     106/* 
     107=============== 
    84108G_AddCreditToClient 
    85109=============== 
     
    90114    return; 
    91115 
    92   //if we're already at the max and trying to add credit then stop 
     116  client->ps.persistant[ PERS_CREDIT ] += credit; 
     117 
    93118  if( cap ) 
    94119  { 
    95120    if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) 
    96121    { 
    97       if( client->ps.persistant[ PERS_CREDIT ] >= ALIEN_MAX_KILLS && 
    98           credit > 0 ) 
    99         return; 
     122      if( client->ps.persistant[ PERS_CREDIT ] > ALIEN_MAX_KILLS ) 
     123      { 
     124        if( g_autoDonate.integer ) 
     125          G_Donate(client, client->ps.persistant[ PERS_CREDIT ] - ALIEN_MAX_KILLS); 
     126        client->ps.persistant[ PERS_CREDIT ] = ALIEN_MAX_KILLS; 
     127      } 
    100128    } 
    101129    else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) 
    102130    { 
    103       if( client->ps.persistant[ PERS_CREDIT ] >= HUMAN_MAX_CREDITS && 
    104           credit > 0 ) 
    105         return; 
    106     } 
    107   } 
    108  
    109   client->ps.persistant[ PERS_CREDIT ] += credit; 
    110  
    111   if( cap ) 
    112   { 
    113     if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) 
    114     { 
    115       if( client->ps.persistant[ PERS_CREDIT ] > ALIEN_MAX_KILLS ) 
    116         client->ps.persistant[ PERS_CREDIT ] = ALIEN_MAX_KILLS; 
    117     } 
    118     else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) 
    119     { 
    120131      if( client->ps.persistant[ PERS_CREDIT ] > HUMAN_MAX_CREDITS ) 
     132      { 
     133        if( g_autoDonate.integer ) 
     134          G_Donate(client, client->ps.persistant[ PERS_CREDIT ] - HUMAN_MAX_CREDITS); 
    121135        client->ps.persistant[ PERS_CREDIT ] = HUMAN_MAX_CREDITS; 
     136      } 
    122137    } 
    123138  } 
     
    583598 
    584599    //sinking bodies can't be infested 
    585     ent->killedBy = ent->s.misc = MAX_CLIENTS; 
     600    ent->killedBy = ent->s.powerups = MAX_CLIENTS; 
    586601    ent->timestamp = level.time; 
    587602  } 
     
    657672    body->classname = "alienCorpse"; 
    658673 
    659   body->s.misc = MAX_CLIENTS; 
     674  body->s.powerups = MAX_CLIENTS; 
    660675 
    661676  body->think = BodySink; 
     
    827842 
    828843    // check colors 
    829     if( ch == Q_COLOR_ESCAPE ) 
    830     { 
    831       // solo trailing carat is not a color prefix 
    832       if( !*in ) 
    833         break; 
    834  
    835       // don't allow black in a name, period 
    836       if( ColorIndex( *in ) == 0 ) 
    837       { 
    838         in++; 
    839         continue; 
    840       } 
    841  
     844    if( ch == Q_COLOR_ESCAPE && ( ( *in && *in != Q_COLOR_ESCAPE ) || !*in ) ) 
     845    { 
    842846      // make sure room in dest for both chars 
    843847      if( len > outSize - 2 ) 
     
    845849 
    846850      *out++ = ch; 
    847       *out++ = *in++; 
    848851      len += 2; 
     852 
     853      // solo trailing carat is not a color prefix 
     854      if( !*in ) { 
     855        *out++ = COLOR_WHITE; 
     856        break; 
     857      } 
     858 
     859      // don't allow black in a name, period 
     860      if( ColorIndex( *in ) == 0 ) 
     861        *out++ = COLOR_WHITE; 
     862      else 
     863        *out++ = *in; 
     864 
     865      in++; 
    849866      continue; 
    850867    } 
     
    873890  if( *p == 0 || colorlessLen == 0 ) 
    874891    Q_strncpyz( p, "UnnamedPlayer", outSize ); 
     892} 
     893 
     894 
     895/* 
     896=================== 
     897G_NextNewbieName 
     898 
     899Generate a unique, known-good name for an UnnamedPlayer 
     900=================== 
     901*/ 
     902char *G_NextNewbieName( gentity_t *ent ) 
     903{ 
     904  char newname[ MAX_NAME_LENGTH ]; 
     905  char namePrefix[ MAX_NAME_LENGTH - 4 ]; 
     906  char err[ MAX_STRING_CHARS ]; 
     907 
     908  if( g_newbieNamePrefix.string[ 0 ] ) 
     909    Q_strncpyz( namePrefix, g_newbieNamePrefix.string , sizeof( namePrefix ) ); 
     910  else 
     911    strcpy( namePrefix, "Newbie#" ); 
     912 
     913  while( level.numNewbies < 10000 ) 
     914  { 
     915    strcpy( newname, va( "%s%i", namePrefix, level.numNewbies ) ); 
     916    if ( G_admin_name_check( ent, newname, err, sizeof( err ) ) ) 
     917    { 
     918      return va( "%s", newname ); 
     919    } 
     920    level.numNewbies++; // Only increments if the last requested name was used. 
     921  } 
     922  return "UnnamedPlayer"; 
    875923} 
    876924 
     
    9541002  char      err[ MAX_STRING_CHARS ]; 
    9551003  qboolean  revertName = qfalse; 
     1004  qboolean  showRenameMsg = qtrue; 
    9561005  gclient_t *client; 
    9571006  char      c1[ MAX_INFO_STRING ]; 
     
    9821031  if( strcmp( oldname, newname ) ) 
    9831032  { 
    984     // in case we need to revert and there's no oldname 
    985     if( client->pers.connected != CON_CONNECTED ) 
    986         Q_strncpyz( oldname, "UnnamedPlayer", sizeof( oldname ) ); 
    987  
    988     if( client->pers.nameChangeTime && 
     1033 
     1034     if( !strlen( oldname ) && client->pers.connected != CON_CONNECTED ) 
     1035       showRenameMsg = qfalse; 
     1036      // in case we need to revert and there's no oldname 
     1037     ClientCleanName( va( "%s", client->pers.netname ), oldname, sizeof( oldname ) ); 
     1038 
     1039     if( g_newbieNumbering.integer ) 
     1040     { 
     1041       if( !strcmp( newname, "UnnamedPlayer" ) ) 
     1042          Q_strncpyz( newname, G_NextNewbieName( ent ), sizeof( newname ) ); 
     1043       if( !strcmp( oldname, "UnnamedPlayer" ) ) 
     1044          Q_strncpyz( oldname, G_NextNewbieName( ent ), sizeof( oldname ) ); 
     1045     } 
     1046 
     1047    if( client->pers.muted ) 
     1048    { 
     1049      trap_SendServerCommand( ent - g_entities, 
     1050        "print \"You cannot change your name while you are muted\n\"" ); 
     1051      revertName = qtrue; 
     1052    } 
     1053    else if( client->pers.nameChangeTime && 
    9891054      ( level.time - client->pers.nameChangeTime ) 
    9901055      <= ( g_minNameChangePeriod.value * 1000 ) ) 
     
    10201085      Q_strncpyz( client->pers.netname, newname, 
    10211086        sizeof( client->pers.netname ) ); 
     1087      Info_SetValueForKey( userinfo, "name", newname ); 
     1088      trap_SetUserinfo( clientNum, userinfo ); 
    10221089      if( client->pers.connected == CON_CONNECTED ) 
    10231090      { 
     
    10341101  } 
    10351102 
    1036   if( client->pers.connected == CON_CONNECTED ) 
     1103  if( client->pers.connected >= CON_CONNECTING && showRenameMsg ) 
    10371104  { 
    10381105    if( strcmp( oldname, client->pers.netname ) ) 
    10391106    { 
    10401107      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE 
    1041         " renamed to %s\n\"", oldname, client->pers.netname ) ); 
    1042       G_LogPrintf( "ClientRename: %i [%s] (%s) \"%s\" -> \"%s\"\n", clientNum, 
     1108        " renamed to %s" S_COLOR_WHITE "\n\"", oldname, client->pers.netname ) ); 
     1109      G_LogPrintf( "ClientRename: %i [%s] (%s) \"%s^7\" -> \"%s^7\"\n", clientNum, 
    10431110         client->pers.ip, client->pers.guid, oldname, client->pers.netname ); 
    10441111      G_admin_namelog_update( client, qfalse ); 
     
    10581125 
    10591126  // set model 
    1060   if( client->ps.stats[ STAT_PCLASS ] == PCL_HUMAN_BSUIT ) 
     1127  if( client->ps.stats[ STAT_PCLASS ] == PCL_HUMAN && BG_InventoryContainsUpgrade( UP_BATTLESUIT, client->ps.stats ) ) 
    10611128  { 
    10621129    Com_sprintf( buffer, MAX_QPATH, "%s/%s",  BG_FindModelNameForClass( PCL_HUMAN_BSUIT ), 
     
    11701237  char      reason[ MAX_STRING_CHARS ] = {""}; 
    11711238  int       i; 
     1239  int       used_privateSlots; 
     1240  int       privateClients; 
    11721241 
    11731242  ent = &g_entities[ clientNum ]; 
     
    11841253  } 
    11851254 
     1255  privateClients = trap_Cvar_VariableIntegerValue( "sv_privateClients" ); 
     1256  if( firstTime && clientNum >= privateClients && !G_admin_guid_permission( value, ADMF_VIP ) ) 
     1257  { 
     1258    // not flag ADMF_VIP, not already connected player after mapchange, and not privateClient... 
     1259    // may be refused, because too many players in game 
     1260    used_privateSlots = 0; 
     1261    for( i = 0 ; i < privateClients; i++ ) 
     1262    { 
     1263      if( level.clients[ i ].pers.connected != CON_DISCONNECTED ) 
     1264      { 
     1265        used_privateSlots++; 
     1266      } 
     1267    } 
     1268      
     1269    if( ( level.numConnectedClients - used_privateSlots ) >= ( level.maxclients - privateClients - g_hiddenClients.integer ) ) 
     1270    { 
     1271      // not flag ADMF_VIP and maxPlayers exceeded 
     1272      return "Server is full"; 
     1273    } 
     1274  } 
    11861275 
    11871276  // IP filtering 
     
    12161305 
    12171306  // add guid to session so we don't have to keep parsing userinfo everywhere 
    1218   if( !guid[0] ) 
     1307  if( !G_ValidGUID(guid) ) 
    12191308  { 
    12201309    Q_strncpyz( client->pers.guid, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 
     
    12381327  // get and distribute relevent paramters 
    12391328  ClientUserinfoChanged( clientNum ); 
    1240   G_LogPrintf( "ClientConnect: %i [%s] (%s) \"%s\"\n", clientNum, 
     1329  G_LogPrintf( "ClientConnect: %i [%s] (%s) \"%s^7\"\n", clientNum, 
    12411330   client->pers.ip, client->pers.guid, client->pers.netname ); 
    12421331 
     
    12941383  // locate ent at a spawn point 
    12951384 
     1385  client->pers.classSelection = PCL_NONE; 
    12961386  ClientSpawn( ent, NULL, NULL, NULL ); 
    12971387 
     
    13011391  G_admin_namelog_update( client, qfalse ); 
    13021392 
     1393  // autoregister client if possible 
     1394  G_admin_autoregister( ent ); 
     1395 
    13031396  // request the clients PTR code 
    13041397  trap_SendServerCommand( ent - g_entities, "ptrcrequest" ); 
     
    13081401  // count current clients and rank for scoreboard 
    13091402  CalculateRanks( ); 
     1403} 
     1404 
     1405/* 
     1406================== 
     1407ClientPingOverride 
     1408 
     1409Called by server every time a client connects to check 
     1410whether it is immune to ping restrictions. 
     1411================== 
     1412*/ 
     1413int ClientPingOverride( void ) 
     1414{ 
     1415  char userinfo[ MAX_INFO_STRING ]; 
     1416  // create a temporary gentity 
     1417  gentity_t ent; 
     1418  gclient_t client; 
     1419  ent.client = &client; 
     1420 
     1421  // userinfo for the client is not yet availible so just use Argv(1) 
     1422  trap_Argv( 1, userinfo, sizeof( userinfo ) ); 
     1423  Q_strncpyz( client.pers.guid, Info_ValueForKey( userinfo, "cl_guid" ), sizeof( client.pers.guid ) ); 
     1424  if ( !client.pers.guid[0] ) 
     1425    return 0; 
     1426   
     1427  return G_admin_permission( &ent, ADMF_PINGOVERRIDE ); 
    13101428} 
    13111429 
     
    13551473    client->sess.spectatorState = SPECTATOR_LOCKED; 
    13561474  } 
     1475   
     1476 
     1477  // if this is after !restart keepteams or !restart switchteams, apply said selection 
     1478  if ( client->sess.restartTeam != PTE_NONE ) { 
     1479    G_ChangeTeam( ent, client->sess.restartTeam ); 
     1480    client->sess.restartTeam = PTE_NONE; 
     1481  } 
     1482 
     1483   
    13571484 
    13581485  if( origin != NULL ) 
     
    14791606  BG_FindAmmoForWeapon( weapon, &maxAmmo, &maxClips ); 
    14801607  BG_AddWeaponToInventory( weapon, client->ps.stats ); 
    1481   client->ps.ammo = maxAmmo; 
    1482   client->ps.clips = maxClips; 
     1608  BG_PackAmmoArray( weapon, client->ps.ammo, client->ps.powerups, maxAmmo, maxClips ); 
    14831609 
    14841610  ent->client->ps.stats[ STAT_PCLASS ] = ent->client->pers.classSelection; 
     
    15041630 
    15051631  client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA; 
     1632 
     1633  client->jetpack_beat = 0; 
     1634  client->jetpack_power = g_jetpackLimit.integer; 
    15061635 
    15071636  G_SetOrigin( ent, spawn_origin ); 
     
    16661795  } 
    16671796 
    1668   G_LogPrintf( "ClientDisconnect: %i [%s] (%s) \"%s\"\n", clientNum, 
     1797  G_LogPrintf( "ClientDisconnect: %i [%s] (%s) \"%s^7\"\n", clientNum, 
    16691798   ent->client->pers.ip, ent->client->pers.guid, ent->client->pers.netname ); 
    16701799 
  • src/game/g_client.c

    r122 r123  
    993993{ 
    994994  gentity_t *ent; 
    995   int       teamTask, teamLeader, health; 
     995  int       health; 
    996996  char      *s; 
    997997  char      model[ MAX_QPATH ]; 
     
    10241024    client->pers.localClient = qtrue; 
    10251025 
    1026   // check the item prediction 
    1027   s = Info_ValueForKey( userinfo, "cg_predictItems" ); 
    1028  
    1029   if( !atoi( s ) ) 
    1030     client->pers.predictItemPickup = qfalse; 
    1031   else 
    1032     client->pers.predictItemPickup = qtrue; 
    1033  
    10341026  // set name 
    10351027  Q_strncpyz( oldname, client->pers.netname, sizeof( oldname ) ); 
     
    11861178  s = Info_ValueForKey( userinfo, "teamoverlay" ); 
    11871179 
    1188   if( ! *s || atoi( s ) != 0 ) 
     1180  if( !*s || atoi( s ) != 0 ) 
    11891181    client->pers.teamInfo = qtrue; 
    11901182  else 
    11911183    client->pers.teamInfo = qfalse; 
    1192  
    1193   // team task (0 = none, 1 = offence, 2 = defence) 
    1194   teamTask = atoi( Info_ValueForKey( userinfo, "teamtask" ) ); 
    1195   // team Leader (1 = leader, 0 is normal player) 
    1196   teamLeader = client->sess.teamLeader; 
    11971184 
    11981185  // colors 
     
    12091196 
    12101197  Com_sprintf( userinfo, sizeof( userinfo ), 
    1211     "n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\" 
    1212     "hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\" 
    1213     "tl\\%d\\ig\\%16s", 
    1214     client->pers.netname, team, model, model, c1, c2, 
    1215     client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, 
    1216     teamLeader, BG_ClientListString( &client->sess.ignoreList ) ); 
     1198    "n\\%s\\t\\%i\\model\\%s\\c1\\%s\\c2\\%s\\" 
     1199    "hc\\%i\\ig\\%16s", 
     1200    client->pers.netname, team, model, c1, c2, 
     1201    client->pers.maxHealth, BG_ClientListString( &client->sess.ignoreList ) ); 
    12171202 
    12181203  trap_SetConfigstring( CS_PLAYERS + clientNum, userinfo ); 
  • src/game/g_cmds.c

    r119 r123  
    382382      maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER ); 
    383383 
    384     client->ps.ammo = maxAmmo; 
    385     client->ps.clips = maxClips; 
     384    BG_PackAmmoArray( client->ps.weapon, client->ps.ammo, client->ps.powerups, maxAmmo, maxClips ); 
    386385  } 
    387386} 
     
    622621  ent->client->pers.joinedATeam = qtrue; 
    623622  ent->client->pers.teamChangeTime = level.time; 
    624  
    625623  //update ClientInfo 
    626624  ClientUserinfoChanged( ent->client->ps.clientNum ); 
     625  CalculateRanks( ); 
    627626} 
    628627 
     
    640639  int     aliens = level.numAlienClients; 
    641640  int     humans = level.numHumanClients; 
     641  int     warmup; 
    642642 
    643643  // stop team join spam 
    644644  if( level.time - ent->client->pers.teamChangeTime < 1000 ) 
    645645    return; 
     646 
     647  // do warm up 
     648  if( g_doWarmup.integer ) 
     649  { 
     650    warmup = g_warmup.integer - ( ( level.time - level.startTime ) / 1000) - 1; 
     651    if( warmup > 0 ) 
     652    { 
     653      trap_SendServerCommand( ent - g_entities, va( "print \"team: you can't join" 
     654            " a team during warm up (%d seconds remaining)\n\"", warmup ) ); 
     655      return; 
     656    } 
     657  } 
    646658 
    647659  if( oldteam == PTE_ALIENS ) 
     
    659671  } 
    660672 
    661   if( !Q_stricmp( s, "spectate" ) ) 
    662     team = PTE_NONE; 
    663   else if( !force && oldteam == PTE_NONE && g_maxGameClients.integer && 
     673  // g_maxGameClients stuff 
     674  if( !force && oldteam == PTE_NONE && g_maxGameClients.integer && 
    664675           level.numPlayingClients >= g_maxGameClients.integer ) 
    665676  { 
     
    669680    return; 
    670681  } 
     682 
     683  //guard against build timer exploit 
     684  if( ent->client->pers.teamSelection != PTE_NONE && 
     685      ( ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0 || 
     686      ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0_UPG || 
     687      BG_InventoryContainsWeapon( WP_HBUILD, ent->client->ps.stats ) || 
     688      BG_InventoryContainsWeapon( WP_HBUILD2, ent->client->ps.stats ) ) && 
     689      ent->client->ps.stats[ STAT_MISC ] > 0 ) 
     690  { 
     691    trap_SendServerCommand( ent-g_entities, va( "print \"You cannot change teams until build timer expires\n\"" ) ); 
     692    return; 
     693  } 
     694 
     695  if( !Q_stricmp( s, "spectate" ) ) 
     696    team = PTE_NONE; 
    671697  else if( !Q_stricmp( s, "aliens" ) ) 
    672698  { 
     
    677703      return;  
    678704    } 
    679     else if( level.humanTeamLocked ) 
    680     { 
    681       // if only one team has been locked, let people join the other 
    682       // regardless of balance 
    683       force = qtrue; 
    684     } 
    685  
    686     if( !force && g_teamForceBalance.integer && aliens > humans ) 
    687     { 
    688       G_TriggerMenu( ent - g_entities, MN_A_TEAMFULL ); 
     705 
     706    if( !force && !level.humanTeamLocked && g_teamForceBalance.integer && aliens > humans ) 
     707    { 
     708      trap_SendServerCommand( ent-g_entities, va("print \"team: The alien team has too many players.\n\"" ) ); 
    689709      return; 
    690710    } 
     
    700720      return;  
    701721    } 
    702     else if( level.alienTeamLocked ) 
    703     { 
    704       // if only one team has been locked, let people join the other 
    705       // regardless of balance 
    706       force = qtrue; 
    707     } 
    708  
    709     if( !force && g_teamForceBalance.integer && humans > aliens ) 
    710     { 
    711       G_TriggerMenu( ent - g_entities, MN_H_TEAMFULL ); 
     722    if( !force && !level.alienTeamLocked && g_teamForceBalance.integer && humans > aliens ) 
     723    { 
     724      trap_SendServerCommand( ent-g_entities, va("print \"team: The human team has too many players.\n\"" ) ); 
    712725      return; 
    713726    } 
     
    719732    if( level.humanTeamLocked && level.alienTeamLocked ) 
    720733      team = PTE_NONE; 
    721     else if( humans > aliens ) 
     734    else if(humans > aliens ) 
    722735      team = PTE_ALIENS; 
    723736    else if( humans < aliens ) 
     
    738751 
    739752  // stop team join spam 
    740   if( oldteam == team ) 
    741     return; 
    742  
    743   //guard against build timer exploit 
    744   if( oldteam != PTE_NONE && 
    745      ( ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0 || 
    746        ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0_UPG || 
    747        BG_InventoryContainsWeapon( WP_HBUILD, ent->client->ps.stats ) || 
    748        BG_InventoryContainsWeapon( WP_HBUILD2, ent->client->ps.stats ) ) && 
    749       ent->client->ps.stats[ STAT_MISC ] > 0 ) 
    750   { 
    751     if( ent->client->pers.teamSelection == PTE_ALIENS ) 
    752       G_TriggerMenu( ent->client->ps.clientNum, MN_A_TEAMCHANGEBUILDTIMER ); 
     753  if( ent->client->pers.teamSelection == team ) 
     754    return; 
     755 
     756  G_ChangeTeam( ent, team ); 
     757 
     758  if( team == PTE_ALIENS ) 
     759  { 
     760    if ( oldteam == PTE_HUMANS ) 
     761      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " abandoned humans and joined the aliens\n\"", ent->client->pers.netname ) ); 
    753762    else 
    754       G_TriggerMenu( ent->client->ps.clientNum, MN_H_TEAMCHANGEBUILDTIMER ); 
    755     return; 
    756   } 
    757  
    758  
    759   G_ChangeTeam( ent, team ); 
    760  
    761   if( team == PTE_ALIENS ) 
    762     trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " joined the aliens\n\"", ent->client->pers.netname ) ); 
     763      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " joined the aliens\n\"", ent->client->pers.netname ) ); 
     764  } 
    763765  else if( team == PTE_HUMANS ) 
    764     trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " joined the humans\n\"", ent->client->pers.netname ) ); 
     766  { 
     767    if ( oldteam == PTE_ALIENS ) 
     768      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " abandoned aliens and joined the humans\n\"", ent->client->pers.netname ) ); 
     769    else 
     770      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " joined the humans\n\"", ent->client->pers.netname ) ); 
     771  } 
     772  else if( team == PTE_NONE ) 
     773  { 
     774    if ( oldteam == PTE_HUMANS ) 
     775      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " left the humans\n\"", ent->client->pers.netname ) ); 
     776    else 
     777      trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " left the aliens\n\"", ent->client->pers.netname ) ); 
     778  } 
    765779} 
    766780 
     
    771785================== 
    772786*/ 
    773 static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message ) 
    774 { 
     787static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message, const char *prefix ) 
     788{ 
     789  qboolean toSend = qtrue, usePrefix = qfalse; 
     790 
    775791  qboolean ignore = qfalse; 
    776792 
     
    787803    return; 
    788804 
    789   if( mode == SAY_TEAM && !OnSameTeam( ent, other ) ) 
    790   { 
    791     if( other->client->pers.teamSelection != PTE_NONE ) 
    792       return; 
    793  
    794     if( !G_admin_permission( other, ADMF_SPEC_ALLCHAT ) ) 
    795       return; 
     805  if( ( mode == SAY_TEAM || mode == SAY_ACTION_T ) && !OnSameTeam( ent, other ) ) 
     806  { 
     807    toSend = qfalse; 
     808 
     809    if( other->client->ps.stats[ STAT_PTEAM ]  == PTE_NONE && 
     810        G_admin_permission( other, ADMF_SPEC_ALLCHAT ) ) { 
     811      usePrefix = qtrue; 
     812      toSend = qtrue; 
     813    } 
     814      
     815    // spec following someone in talker's steam may see 
     816    // that teamchat if g_specsSeeTeamchat is enabled 
     817    if( other->client->ps.stats[ STAT_PTEAM ] == ent->client->ps.stats[ STAT_PTEAM ] && 
     818        ent->client->pers.teamSelection != PTE_NONE && g_specsSeeTeamchat.integer ) 
     819      toSend = qtrue; 
    796820 
    797821    // specs with ADMF_SPEC_ALLCHAT flag can see team chat 
    798822  } 
     823 
     824  if( mode == SAY_ADMINS && !G_admin_permission( other, ADMF_ADMINCHAT) ) 
     825         return; 
     826 
     827  if( mode == SAY_ALL ) 
     828    usePrefix = qtrue; 
    799829 
    800830  if( BG_ClientListTest( &other->client->sess.ignoreList, ent-g_entities ) ) 
    801831    ignore = qtrue; 
    802832   
    803   trap_SendServerCommand( other-g_entities, va( "%s \"%s%s%c%c%s\"", 
    804     mode == SAY_TEAM ? "tchat" : "chat", 
    805     ( ignore ) ? "[skipnotify]" : "", 
    806     name, Q_COLOR_ESCAPE, color, message ) ); 
     833  if( toSend ) 
     834  { 
     835    trap_SendServerCommand( other-g_entities, va( "%s \"%s%s%s%c%c%s\"", 
     836      ( mode == SAY_TEAM || mode == SAY_ACTION_T ) ? "tchat" : "chat", 
     837      ( ignore ) ? "[skipnotify]" : "", 
     838      usePrefix ? prefix : "", 
     839      name, Q_COLOR_ESCAPE, color, message ) ); 
     840  } 
    807841} 
    808842 
     
    844878    default: 
    845879    case SAY_ALL: 
    846       G_LogPrintf( "say: %s: %s\n", ent->client->pers.netname, chatText ); 
    847       Com_sprintf( name, sizeof( name ), "%s%s%c%c"EC": ", prefix, 
     880      if(ent->client->pers.teamSelection == PTE_NONE && G_admin_level(ent)<g_minLevelToSpecMM1.integer) 
     881      { 
     882        trap_SendServerCommand( ent-g_entities,va( "print \"Sorry, but your admin level is not permitted to speak to all while spectating.\n\"") );  
     883        return; 
     884      } 
     885      G_LogPrintf( "say: %s%s^7: ^2%s^7\n", prefix, ent->client->pers.netname, chatText ); 
     886      Com_sprintf( name, sizeof( name ), "%s%c%c"EC": ", 
    848887                   ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); 
    849888      color = COLOR_GREEN; 
    850889      break; 
    851890 
     891     case SAY_ACTION: 
     892       G_LogPrintf( "action: %s: %s\n", ent->client->pers.netname, chatText ); 
     893       Com_sprintf( name, sizeof( name ), "^2%s^7%s%s%c%c"EC" ", g_actionPrefix.string, prefix, 
     894             ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); 
     895       color = COLOR_WHITE; 
     896       break; 
     897     case SAY_ACTION_T: 
     898       G_LogPrintf( "actionteam: %s: %s\n", ent->client->pers.netname, chatText ); 
     899       if( Team_GetLocationMsg( ent, location, sizeof( location ) ) ) 
     900       Com_sprintf( name, sizeof( name ), EC"^5%s^7%s%c%c"EC"(%s)"EC" ", g_actionPrefix.string,  
     901             ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location ); 
     902       else 
     903         Com_sprintf( name, sizeof( name ), EC"^5%s^7%s%c%c"EC""EC" ", g_actionPrefix.string,  
     904         ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); 
     905         color = COLOR_WHITE; 
     906       break; 
     907 
    852908    case SAY_TEAM: 
    853       G_LogPrintf( "sayteam: %s: %s\n", ent->client->pers.netname, chatText ); 
     909      G_LogPrintf( "sayteam: %s%s^7: ^5%s^7\n", prefix, ent->client->pers.netname, chatText ); 
    854910      if( Team_GetLocationMsg( ent, location, sizeof( location ) ) ) 
    855911        Com_sprintf( name, sizeof( name ), EC"(%s%c%c"EC") (%s)"EC": ", 
     
    858914        Com_sprintf( name, sizeof( name ), EC"(%s%c%c"EC")"EC": ", 
    859915          ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); 
    860       color = COLOR_CYAN; 
     916       
     917      if( ent->client->pers.teamSelection == PTE_NONE ) 
     918        color = COLOR_YELLOW; 
     919      else 
     920        color = COLOR_CYAN; 
     921       
    861922      break; 
    862923 
     
    871932      color = COLOR_MAGENTA; 
    872933      break; 
     934       
     935    case SAY_ADMINS: 
     936      if( G_admin_permission( ent, ADMF_ADMINCHAT ) ) //Differentiate between inter-admin chatter and user-admin alerts 
     937      { 
     938        G_LogPrintf( "say_admins: [ADMIN]%s: %s\n", ent->client->pers.netname, chatText ); 
     939        Com_sprintf( name, sizeof( name ), "%s[ADMIN]%s%c%c"EC": ", prefix, 
     940                               ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); 
     941        color = COLOR_MAGENTA; 
     942       } 
     943       else 
     944       { 
     945         G_LogPrintf( "say_admins: [PLAYER]%s: %s\n", ent->client->pers.netname, chatText ); 
     946         Com_sprintf( name, sizeof( name ), "%s[PLAYER]%s%c%c"EC": ", prefix, 
     947                             ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE ); 
     948         color = COLOR_MAGENTA; 
     949        } 
     950       break; 
    873951  } 
    874952 
    875953  Q_strncpyz( text, chatText, sizeof( text ) ); 
    876954 
     955  //R1's simple flood protection (lowered in g_client timer actions) 
     956   if ( g_floodProtection.integer && !G_admin_permission( ent, ADMF_NOCENSORFLOOD ) ) 
     957   { 
     958     if ( ent->client->pers.floodTimer >= 100 )  return; 
     959     ent->client->pers.floodTimer += g_floodProtection.integer; 
     960   } 
     961 
     962 
    877963  if( target ) 
    878964  { 
    879     G_SayTo( ent, target, mode, color, name, text ); 
    880     return; 
    881   } 
    882  
    883   // echo the text to the console 
    884   if( g_dedicated.integer ) 
    885     G_Printf( "%s%s\n", name, text); 
     965    G_SayTo( ent, target, mode, color, name, text, prefix ); 
     966    return; 
     967  } 
    886968 
    887969  // send it to all the apropriate clients 
     
    889971  { 
    890972    other = &g_entities[ j ]; 
    891     G_SayTo( ent, other, mode, color, name, text ); 
     973    G_SayTo( ent, other, mode, color, name, text, prefix ); 
    892974  } 
    893975   
     
    908990  char    *p; 
    909991  char    *args; 
     992  int     offset = 0; 
    910993  int     mode = SAY_ALL; 
    911994 
     
    913996  if( Q_stricmpn( args, "say_team ", 9 ) == 0 ) 
    914997    mode = SAY_TEAM; 
     998  if( Q_stricmpn( args, "say_admins ", 11 ) == 0 || Q_stricmpn( args, "a ", 2 ) == 0) 
     999    mode = SAY_ADMINS; 
    9151000 
    9161001  // support parsing /m out of say text since some people have a hard 
     
    9241009    return; 
    9251010  } 
     1011   
     1012  if( !Q_stricmpn( args, "say /a ", 7) || 
     1013      !Q_stricmpn( args, "say_team /a ", 12) || 
     1014      !Q_stricmpn( args, "say /say_admins ", 16) || 
     1015      !Q_stricmpn( args, "say_team /say_admins ", 21) ) 
     1016  { 
     1017      mode = SAY_ADMINS; 
     1018      offset =3; 
     1019  } 
     1020   
     1021  if( mode == SAY_ADMINS)   
     1022  if(!G_admin_permission( ent, ADMF_ADMINCHAT ) ) 
     1023  { 
     1024    if( !g_publicSayadmins.integer ) 
     1025    { 
     1026     ADMP( "Sorry, but public use of say_admins has been disabled.\n" ); 
     1027     return; 
     1028    } 
     1029    else 
     1030    { 
     1031      ADMP( "Your message has been sent to any available admins and to the server logs.\n" ); 
     1032    } 
     1033  } 
     1034   
     1035  if( g_allowDonate.integer ) 
     1036  { 
     1037    args = G_SayConcatArgs(0); 
     1038    if( !Q_stricmpn( args, "say /donate", 11 ) || 
     1039      !Q_stricmpn( args, "say_team /donate", 16 ) ) 
     1040    { 
     1041      Cmd_Donate_f( ent ); 
     1042      return; 
     1043    } 
     1044  } 
    9261045 
    9271046  if( trap_Argc( ) < 2 ) 
    9281047    return; 
    9291048 
     1049  if( g_allowShare.integer ) 
     1050  { 
     1051    args = G_SayConcatArgs(0); 
     1052    if( !Q_stricmpn( args, "say /share", 10 ) || 
     1053      !Q_stricmpn( args, "say_team /share", 15 ) ) 
     1054    { 
     1055      Cmd_Share_f( ent ); 
     1056      return; 
     1057    } 
     1058  } 
     1059   
     1060  if( g_allowActions.integer && !Q_stricmpn( args, "say /me ", 8 ) ) 
     1061  { 
     1062    mode = SAY_ACTION; 
     1063    offset = 4; 
     1064  } 
     1065 
     1066  if( g_allowActions.integer && !Q_stricmpn( args, "say_team /me ", 13 ) ) 
     1067  { 
     1068    mode = SAY_ACTION_T; 
     1069    offset = 4; 
     1070  } 
     1071 
    9301072  p = ConcatArgs( 1 ); 
     1073  p += offset; 
    9311074 
    9321075  G_Say( ent, NULL, mode, p ); 
     
    9601103  p = ConcatArgs( 2 ); 
    9611104 
    962   G_LogPrintf( "tell: %s to %s: %s\n", ent->client->pers.netname, target->client->pers.netname, p ); 
     1105  G_LogPrintf( "tell: %s^7 to %s^7: ^6%s^7\n", ent->client->pers.netname, target->client->pers.netname, p ); 
    9631106  G_Say( ent, target, SAY_TELL, p ); 
    9641107  // don't tell to the player self if it was already directed to this player 
     
    10561199 
    10571200    if( clientNum != -1 && 
    1058       level.clients[ clientNum ].pers.connected == CON_DISCONNECTED ) 
     1201      level.clients[ clientNum ].pers.connected != CON_CONNECTED ) 
    10591202    { 
    10601203      clientNum = -1; 
     
    11241267      "Un-Mute player \'%s\'", name ); 
    11251268  } 
    1126   else if( !Q_stricmp( arg1, "map_restart" ) ) 
     1269  else if( !Q_stricmp( arg1, "restartmap" ) ) 
    11271270  { 
    11281271    Com_sprintf( level.voteString, sizeof( level.voteString ), "%s", arg1 ); 
     
    11431286        sizeof( level.voteDisplayString ), "Change to map '%s'", arg2 ); 
    11441287  } 
    1145   else if( !Q_stricmp( arg1, "draw" ) ) 
    1146   { 
    1147     Com_sprintf( level.voteString, sizeof( level.voteString ), "evacuation" ); 
     1288  else if( !Q_stricmp( arg1, "nextmap" ) ) 
     1289  { 
     1290    Com_sprintf( level.voteString, sizeof( level.voteString ), "advanceMapRotation" ); 
    11481291    Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), 
    1149         "End match in a draw" ); 
     1292        "Skip to next map in rotation" ); 
    11501293  } 
    11511294  else 
     
    11531296    trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" ); 
    11541297    trap_SendServerCommand( ent-g_entities, "print \"Valid vote commands are: " 
    1155       "map, map_restart, draw, kick, mute and unmute\n" ); 
     1298      "map, restartmap, nextmap, kick, mute and unmute\n" ); 
    11561299    return; 
    11571300  } 
     
    11591302  trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE 
    11601303        " called a vote\n\"", ent->client->pers.netname ) ); 
     1304  G_Printf( "'%s^7' called a vote for '%s'\n", ent->client->pers.netname,  
     1305    level.voteString ) ; 
    11611306 
    11621307  ent->client->pers.voteCount++; 
     
    14791624} 
    14801625 
     1626#define EVOLVE_TRACE_HEIGHT 128.0f 
    14811627#define AS_OVER_RT3         ((ALIENSENSE_RANGE*0.5f)/M_ROOT3) 
    14821628 
     
    15521698  int       clientNum; 
    15531699  int       i; 
     1700  trace_t   tr, tr2; 
    15541701  vec3_t    infestOrigin; 
    15551702  int       allowedClasses[ PCL_NUM_CLASSES ]; 
     
    15571704  pClass_t  currentClass = ent->client->ps.stats[ STAT_PCLASS ]; 
    15581705  pClass_t  newClass; 
     1706 
    15591707  int       numLevels; 
     1708  vec3_t    fromMins, fromMaxs, toMins, toMaxs; 
     1709  vec3_t    temp; 
     1710 
    15601711  int       entityList[ MAX_GENTITIES ]; 
    15611712  vec3_t    range = { AS_OVER_RT3, AS_OVER_RT3, AS_OVER_RT3 }; 
     
    15631714  int       num; 
    15641715  gentity_t *other; 
     1716  qboolean  humanNear = qfalse; 
    15651717 
    15661718  if( ent->client->ps.stats[ STAT_HEALTH ] <= 0 ) 
     
    15901742      return; 
    15911743    } 
     1744        else if( g_grangerMode.integer && newClass == PCL_ALIEN_BUILDER0_UPG && !level.overmindPresent) 
     1745        { 
     1746                newClass = PCL_ALIEN_BUILDER0; 
     1747        } 
    15921748 
    15931749    //if we are not currently spectating, we are attempting evolution 
    15941750    if( ent->client->pers.classSelection != PCL_NONE ) 
    15951751    { 
    1596       if( ( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) || 
    1597           ( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) 
    1598       { 
    1599         trap_SendServerCommand( ent-g_entities, va( "print \"You cannot evolve while wallwalking\n\"" ) ); 
     1752 
     1753      if( !level.overmindPresent ) 
     1754      { 
     1755        G_TriggerMenu( clientNum, MN_A_NOOVMND_EVOLVE ); 
    16001756        return; 
    16011757      } 
    1602  
     1758       
    16031759      //check there are no humans nearby 
    16041760      VectorAdd( ent->client->ps.origin, range, maxs ); 
    16051761      VectorSubtract( ent->client->ps.origin, range, mins ); 
    1606  
     1762       
    16071763      num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); 
    16081764      for( i = 0; i < num; i++ ) 
     
    16131769            ( other->s.eType == ET_BUILDABLE && other->biteam == BIT_HUMANS ) ) 
    16141770        { 
    1615           G_TriggerMenu( clientNum, MN_A_TOOCLOSE ); 
    1616           return; 
     1771          humanNear = qtrue; 
    16171772        } 
    1618       } 
    1619  
    1620       if( !level.overmindPresent ) 
    1621       { 
    1622         G_TriggerMenu( clientNum, MN_A_NOOVMND_EVOLVE ); 
     1773        //If its the OM, then ignore all humans. 
     1774        if(other->s.eType == ET_BUILDABLE && other->s.modelindex == BA_A_OVERMIND) 
     1775        { 
     1776          humanNear = qfalse; 
     1777          break; 
     1778        } 
     1779      } 
     1780       
     1781      if(humanNear == qtrue) 
     1782      { 
     1783        G_TriggerMenu( clientNum, MN_A_TOOCLOSE ); 
    16231784        return; 
    16241785      } 
     1786       
     1787      if( ( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) || 
     1788          ( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) 
     1789      { 
     1790        trap_SendServerCommand( ent-g_entities, va( "print \"You cannot evolve while wallwalking\n\"" ) ); 
     1791        return; 
     1792      } 
     1793 
    16251794 
    16261795      //guard against selling the HBUILD weapons exploit 
     
    16291798          ent->client->ps.stats[ STAT_MISC ] > 0 ) 
    16301799      { 
    1631         G_TriggerMenu( ent->client->ps.clientNum, MN_A_EVOLVEBUILDTIMER ); 
     1800        trap_SendServerCommand( ent-g_entities, 
     1801            va( "print \"You cannot evolve until build timer expires\n\"" ) ); 
    16321802        return; 
    16331803      } 
     
    16371807                                           (short)ent->client->ps.persistant[ PERS_CREDIT ], 0 ); 
    16381808 
    1639       if( G_RoomForClassChange( ent, newClass, infestOrigin ) ) 
     1809      BG_FindBBoxForClass( currentClass, 
     1810                           fromMins, fromMaxs, NULL, NULL, NULL ); 
     1811      BG_FindBBoxForClass( newClass, 
     1812                           toMins, toMaxs, NULL, NULL, NULL ); 
     1813 
     1814      VectorCopy( ent->s.pos.trBase, infestOrigin ); 
     1815 
     1816      infestOrigin[ 2 ] += ( fabs( toMins[ 2 ] ) - fabs( fromMins[ 2 ] ) ) + 1.0f; 
     1817      VectorCopy( infestOrigin, temp ); 
     1818      temp[ 2 ] += EVOLVE_TRACE_HEIGHT; 
     1819 
     1820      //compute a place up in the air to start the real trace 
     1821      trap_Trace( &tr, infestOrigin, toMins, toMaxs, temp, ent->s.number, MASK_SHOT ); 
     1822      VectorCopy( infestOrigin, temp ); 
     1823      temp[ 2 ] += ( EVOLVE_TRACE_HEIGHT * tr.fraction ) - 1.0f; 
     1824 
     1825      //trace down to the ground so that we can evolve on slopes 
     1826      trap_Trace( &tr, temp, toMins, toMaxs, infestOrigin, ent->s.number, MASK_SHOT ); 
     1827      VectorCopy( tr.endpos, infestOrigin ); 
     1828 
     1829      //make REALLY sure 
     1830      trap_Trace( &tr2, ent->s.pos.trBase, NULL, NULL, infestOrigin, ent->s.number, MASK_SHOT ); 
     1831 
     1832      //check there is room to evolve 
     1833      if( !tr.startsolid && tr2.fraction == 1.0f ) 
    16401834      { 
    16411835        //...check we can evolve to that class 
    1642         if( numLevels >= 0 && 
     1836        if( (numLevels >= 0 || g_freeFunds.integer) && 
    16431837            BG_FindStagesForClass( newClass, g_alienStage.integer ) && 
    16441838            BG_ClassIsAllowed( newClass ) ) 
    16451839        { 
     1840          G_LogOnlyPrintf("ClientTeamClass: %i alien %s\n", clientNum, s); 
     1841 
    16461842          ent->client->pers.evolveHealthFraction = (float)ent->client->ps.stats[ STAT_HEALTH ] / 
    16471843            (float)BG_FindHealthForClass( currentClass ); 
     
    16521848            ent->client->pers.evolveHealthFraction = 1.0f; 
    16531849 
    1654           //remove credit 
    1655           G_AddCreditToClient( ent->client, -(short)numLevels, qtrue ); 
     1850          //remove credit if not freefunds 
     1851          if (!g_freeFunds.integer) 
     1852             G_AddCreditToClient( ent->client, -(short)numLevels, qtrue ); 
    16561853          ent->client->pers.classSelection = newClass; 
    16571854          ClientUserinfoChanged( clientNum ); 
     
    16821879            BG_ClassIsAllowed( newClass ) ) 
    16831880        { 
     1881          G_LogOnlyPrintf("ClientTeamClass: %i alien %s\n", clientNum, s); 
     1882 
    16841883          ent->client->pers.classSelection = 
    16851884            ent->client->ps.stats[ STAT_PCLASS ] = newClass; 
     
    17181917      return; 
    17191918    } 
     1919 
     1920    G_LogOnlyPrintf("ClientTeamClass: %i human %s\n", clientNum, s); 
    17201921 
    17211922    G_PushSpawnQueue( &level.humanSpawnQueue, clientNum ); 
     
    17941995 
    17951996      // Don't allow destruction of buildables that cannot be rebuilt 
    1796       if( G_TimeTilSuddenDeath( ) <= 0 && 
    1797           BG_FindBuildPointsForBuildable( traceEnt->s.modelindex ) ) 
    1798       { 
     1997      if( level.suddenDeath && traceEnt->health > 0 && 
     1998        ( ( g_suddenDeathMode.integer == SDMODE_SELECTIVE && 
     1999          !BG_FindReplaceableTestForBuildable( traceEnt->s.modelindex ) ) || 
     2000        ( g_suddenDeathMode.integer == SDMODE_BP && 
     2001          BG_FindBuildPointsForBuildable( traceEnt->s.modelindex ) ) || 
     2002        g_suddenDeathMode.integer == SDMODE_NO_BUILD ) )  
     2003      { 
     2004        trap_SendServerCommand( ent-g_entities, 
     2005          "print \"During Sudden Death you can only decon buildings that " 
     2006          "can be rebuilt\n\"" ); 
    17992007        return; 
    18002008      } 
     
    18202028              ent->client->pers.netname ) ); 
    18212029 
    1822           G_LogPrintf( "Decon: %i %i 0: %s deconstructed %s\n", 
     2030          G_LogPrintf( "Decon: %i %i 0: %s ^3deconstructed^7 %s\n", 
    18232031            ent->client->ps.clientNum, 
    18242032            traceEnt->s.modelindex, 
     
    18312039            G_FreeEntity( traceEnt ); 
    18322040 
    1833           if( !g_cheats.integer ) 
     2041          // cheat or fast build -> no build timer 
     2042          if( !g_cheats.integer && !g_fastBuild.integer ) 
    18342043            ent->client->ps.stats[ STAT_MISC ] += 
    18352044              BG_FindBuildDelayForWeapon( ent->s.weapon ) >> 2; 
    18362045        } 
     2046      } 
     2047      else  
     2048      { 
     2049         // We *can* deconstrute building on fire :) 
     2050          G_LogPrintf( "Decon: %i %i 0: %s ^3deconstructed^7 %s\n", 
     2051            ent->client->ps.clientNum, 
     2052            traceEnt->s.modelindex, 
     2053            ent->client->pers.netname,  
     2054            BG_FindNameForBuildable( traceEnt->s.modelindex ) ); 
     2055 
     2056          if( !deconstruct ) 
     2057            G_Damage( traceEnt, ent, ent, forward, tr.endpos, 10000, 0, MOD_SUICIDE ); 
     2058          else 
     2059            G_FreeEntity( traceEnt ); 
     2060 
     2061          // cheat or fast build -> no build timer 
     2062          if( !g_cheats.integer && !g_fastBuild.integer ) 
     2063            ent->client->ps.stats[ STAT_MISC ] += 
     2064              BG_FindBuildDelayForWeapon( ent->s.weapon ) >> 2; 
    18372065      } 
    18382066    } 
     
    19062134    //special case to allow switching between 
    19072135    //the blaster and the primary weapon 
     2136    ent->client->ps.weaponTime = 0; 
    19082137 
    19092138    if( ent->client->ps.weapon != WP_BLASTER ) 
     
    19892218        !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) ) 
    19902219    { 
    1991       G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOENERGYAMMOHERE ); 
     2220      trap_SendServerCommand( ent-g_entities, va( 
     2221        "print \"You must be near a reactor, repeater or armoury\n\"" ) ); 
    19922222      return; 
    19932223    } 
     
    19982228    if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) ) 
    19992229    { 
    2000       G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOARMOURYHERE ); 
     2230      trap_SendServerCommand( ent-g_entities, va( "print \"You must be near a powered armoury\n\"" ) ); 
    20012231      return; 
    20022232    } 
     
    20122242    } 
    20132243 
    2014     //can afford this? 
    2015     if( BG_FindPriceForWeapon( weapon ) > (short)ent->client->ps.persistant[ PERS_CREDIT ] ) 
     2244    //can afford this? (if free funds then go buy, it's free !) 
     2245    if( !g_freeFunds.integer && BG_FindPriceForWeapon( weapon ) > (short)ent->client->ps.persistant[ PERS_CREDIT ] ) 
    20162246    { 
    20172247      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOFUNDS ); 
     
    20552285      maxAmmo = (int)( (float)maxAmmo * BATTPACK_MODIFIER ); 
    20562286 
    2057     ent->client->ps.ammo = maxAmmo; 
    2058     ent->client->ps.clips = maxClips; 
     2287    BG_PackAmmoArray( weapon, ent->client->ps.ammo, ent->client->ps.powerups, 
     2288                      maxAmmo, maxClips ); 
    20592289 
    20602290    G_ForceWeaponChange( ent, weapon ); 
     
    20642294 
    20652295    //subtract from funds 
    2066     G_AddCreditToClient( ent->client, -(short)BG_FindPriceForWeapon( weapon ), qfalse ); 
     2296    if (!g_freeFunds.integer) // buy it for free 
     2297       G_AddCreditToClient( ent->client, -(short)BG_FindPriceForWeapon( weapon ), qfalse ); 
    20672298  } 
    20682299  else if( upgrade != UP_NONE ) 
     
    20762307 
    20772308    //can afford this? 
    2078     if( BG_FindPriceForUpgrade( upgrade ) > (short)ent->client->ps.persistant[ PERS_CREDIT ] ) 
     2309    if( !g_freeFunds.integer && BG_FindPriceForUpgrade( upgrade ) > (short)ent->client->ps.persistant[ PERS_CREDIT ] ) 
    20792310    { 
    20802311      G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOFUNDS ); 
     
    21202351        if( !G_RoomForClassChange( ent, PCL_HUMAN_BSUIT, newOrigin ) ) 
    21212352        { 
    2122           G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOROOMBSUITON ); 
     2353          trap_SendServerCommand( ent-g_entities, va( "print \"Not enough room here to put on a Battle Suit\n\"") ); 
    21232354          return; 
    21242355        } 
     
    21362367 
    21372368    //subtract from funds 
    2138     G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse ); 
     2369    if (!g_freeFunds.integer) 
     2370       G_AddCreditToClient( ent->client, -(short)BG_FindPriceForUpgrade( upgrade ), qfalse ); 
    21392371  } 
    21402372  else 
     
    21642396  if( !G_BuildableRange( ent->client->ps.origin, 100, BA_H_ARMOURY ) ) 
    21652397  { 
    2166     G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOARMOURYHERE ); 
     2398    trap_SendServerCommand( ent-g_entities, va( "print \"You must be near a powered armoury\n\"" ) ); 
    21672399    return; 
    21682400  } 
     
    21872419          ent->client->ps.stats[ STAT_MISC ] > 0 ) 
    21882420      { 
    2189         G_TriggerMenu( ent->client->ps.clientNum, MN_H_ARMOURYBUILDTIMER ); 
     2421        trap_SendServerCommand( ent-g_entities, va( "print \"Cannot sell until build timer expires\n\"" ) ); 
    21902422        return; 
    21912423      } 
     
    21942426 
    21952427      //add to funds 
    2196       G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); 
     2428      if (!g_freeFunds.integer)  // yes free funds but not get 9999 credits :) 
     2429         G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( weapon ), qfalse ); 
    21972430    } 
    21982431 
     
    22192452        if( !G_RoomForClassChange( ent, PCL_HUMAN, newOrigin ) ) 
    22202453        { 
    2221           G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOROOMBSUITOFF ); 
     2454          trap_SendServerCommand( ent-g_entities, va( "print \"Not enough room here to take off your  Battle Suit\n\"") ); 
    22222455          return; 
    22232456        } 
     
    22342467 
    22352468      //add to funds 
    2236       G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( upgrade ), qfalse ); 
     2469      if (!g_freeFunds.integer) 
     2470         G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( upgrade ), qfalse ); 
    22372471    } 
    22382472  } 
     
    22452479          ent->client->ps.stats[ STAT_MISC ] > 0 ) 
    22462480      { 
    2247         G_TriggerMenu( ent->client->ps.clientNum, MN_H_ARMOURYBUILDTIMER ); 
     2481        trap_SendServerCommand( ent-g_entities, va( "print \"Cannot sell until build timer expires\n\"" ) ); 
    22482482        continue; 
    22492483      } 
     
    22552489 
    22562490        //add to funds 
    2257         G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( i ), qfalse ); 
     2491        if (!g_freeFunds.integer) 
     2492            G_AddCreditToClient( ent->client, (short)BG_FindPriceForWeapon( i ), qfalse ); 
    22582493      } 
    22592494 
     
    22712506          BG_FindPurchasableForUpgrade( i ) ) 
    22722507      { 
    2273  
    2274         // shouldn't really need to test for this, but just to be safe 
    2275         if( i == UP_BATTLESUIT ) 
    2276         { 
    2277           vec3_t newOrigin; 
    2278  
    2279           if( !G_RoomForClassChange( ent, PCL_HUMAN, newOrigin ) ) 
    2280           { 
    2281             G_TriggerMenu( ent->client->ps.clientNum, MN_H_NOROOMBSUITOFF ); 
    2282             continue; 
    2283           } 
    2284           VectorCopy( newOrigin, ent->s.pos.trBase ); 
    2285           ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN; 
    2286         } 
    2287  
    22882508        BG_RemoveUpgradeFromInventory( i, ent->client->ps.stats ); 
    22892509 
     
    22992519                !BG_FindInfinteAmmoForWeapon( j ) ) 
    23002520            { 
    2301               ent->client->ps.ammo = 0; 
    2302               ent->client->ps.clips = 0; 
     2521              BG_PackAmmoArray( j, ent->client->ps.ammo, ent->client->ps.powerups, 0, 0 ); 
    23032522            } 
    23042523          } 
     
    23062525 
    23072526        //add to funds 
    2308         G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( i ), qfalse ); 
     2527        if (!g_freeFunds.integer) 
     2528           G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( i ), qfalse ); 
    23092529      } 
    23102530    } 
     
    23412561 
    23422562  buildable = BG_FindBuildNumForName( s ); 
     2563 
     2564  if( level.suddenDeath ) 
     2565  { 
     2566    if( g_suddenDeathMode.integer == SDMODE_SELECTIVE && 
     2567      !BG_FindReplaceableTestForBuildable( buildable ) ) 
     2568    { 
     2569      trap_SendServerCommand( ent-g_entities, 
     2570        "print \"Only essential buildings can be rebuilt in Sudden Death\n\"" ); 
     2571      return; 
     2572    } 
     2573    else if( g_suddenDeathMode.integer == SDMODE_NO_BUILD ) 
     2574    { 
     2575      trap_SendServerCommand( ent-g_entities, 
     2576        "print \"Building is not allowed during Sudden Death\n\"" ); 
     2577    } 
     2578  } 
     2579 
     2580  if(g_repeaterOnReactor.integer && buildable == BA_H_REACTOR && level.reactorPresent) 
     2581    buildable = BA_H_REPEATER; 
     2582 
    23432583  team = ent->client->ps.stats[ STAT_PTEAM ]; 
    23442584 
     
    24072647} 
    24082648 
     2649/* 
     2650================= 
     2651Cmd_Share_f 
     2652================= 
     2653*/ 
     2654void Cmd_Share_f( gentity_t *ent ) 
     2655{ 
     2656  int   i, clientNum = 0, creds = 0, skipargs = 0; 
     2657  int   clientNums[ MAX_CLIENTS ] = { -1 }; 
     2658  char  cmd[ 12 ]; 
     2659  char  arg1[ MAX_STRING_TOKENS ]; 
     2660  char  arg2[ MAX_STRING_TOKENS ]; 
     2661  pTeam_t team; 
     2662 
     2663  if( !ent || !ent->client || ( ent->client->pers.teamSelection == PTE_NONE ) ) 
     2664  { 
     2665    return; 
     2666  } 
     2667   
     2668  if( !g_allowShare.integer ) 
     2669  { 
     2670    return; 
     2671  } 
     2672 
     2673  team = ent->client->pers.teamSelection; 
     2674 
     2675  G_SayArgv( 0, cmd, sizeof( cmd ) ); 
     2676  if( !Q_stricmp( cmd, "say" ) || !Q_stricmp( cmd, "say_team" ) ) 
     2677  { 
     2678    skipargs = 1; 
     2679    G_SayArgv( 1, cmd, sizeof( cmd ) ); 
     2680  } 
     2681 
     2682  // target player name is in arg1 
     2683  G_SayArgv( 1+skipargs, arg1, sizeof( arg1 ) ); 
     2684  // amount to be shared is in arg2 
     2685  G_SayArgv( 2+skipargs, arg2, sizeof( arg2 ) ); 
     2686 
     2687  if( arg1[0] && !strchr( arg1, ';' ) && Q_stricmp( arg1, "target_in_aim" ) ) 
     2688  { 
     2689    //check arg1 is a number 
     2690    for( i = 0; arg1[ i ]; i++ ) 
     2691    { 
     2692      if( arg1[ i ] < '0' || arg1[ i ] > '9' ) 
     2693      { 
     2694        clientNum = -1; 
     2695        break; 
     2696      } 
     2697    } 
     2698 
     2699    if( clientNum >= 0 ) 
     2700    { 
     2701      clientNum = atoi( arg1 ); 
     2702    } 
     2703    else if( G_ClientNumbersFromString( arg1, clientNums, MAX_CLIENTS ) == 1 ) 
     2704    { 
     2705      // there was one partial name match 
     2706      clientNum = clientNums[ 0 ];  
     2707    } 
     2708    else 
     2709    { 
     2710      // look for an exact name match before bailing out 
     2711      clientNum = G_ClientNumberFromString( ent, arg1 ); 
     2712      if( clientNum == -1 ) 
     2713      { 
     2714        trap_SendServerCommand( ent-g_entities, 
     2715          "print \"share: invalid player name specified.\n\"" ); 
     2716        return; 
     2717      } 
     2718    } 
     2719  } 
     2720  else // arg1 not set 
     2721  { 
     2722    vec3_t      forward, end; 
     2723    trace_t     tr; 
     2724    gentity_t   *traceEnt; 
     2725 
     2726     
     2727    // trace a teammate 
     2728    AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL ); 
     2729    VectorMA( ent->client->ps.origin, 8192 * 16, forward, end ); 
     2730 
     2731    trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number, MASK_PLAYERSOLID ); 
     2732    traceEnt = &g_entities[ tr.entityNum ]; 
     2733 
     2734    if( tr.fraction < 1.0f && traceEnt->client && 
     2735      ( traceEnt->client->pers.teamSelection == team ) ) 
     2736    { 
     2737      clientNum = traceEnt - g_entities; 
     2738    } 
     2739    else 
     2740    { 
     2741      trap_SendServerCommand( ent-g_entities, 
     2742        va( "print \"share: aim at a teammate to share %s.\n\"", 
     2743        ( team == PTE_HUMANS ) ? "credits" : "evolvepoints" ) ); 
     2744      return; 
     2745    } 
     2746  } 
     2747 
     2748  // verify target player team 
     2749  if( ( clientNum < 0 ) || ( clientNum >= level.maxclients ) || 
     2750      ( level.clients[ clientNum ].pers.teamSelection != team ) ) 
     2751  { 
     2752    trap_SendServerCommand( ent-g_entities, 
     2753      "print \"share: not a valid player of your team.\n\"" ); 
     2754    return; 
     2755  } 
     2756 
     2757  if( !arg2[0] || strchr( arg2, ';' ) ) 
     2758  { 
     2759    // default credit count 
     2760    if( team == PTE_HUMANS ) 
     2761    { 
     2762      creds = FREEKILL_HUMAN; 
     2763    } 
     2764    else if( team == PTE_ALIENS ) 
     2765    { 
     2766      creds = FREEKILL_ALIEN; 
     2767    } 
     2768  } 
     2769  else 
     2770  { 
     2771    //check arg2 is a number 
     2772    for( i = 0; arg2[ i ]; i++ ) 
     2773    { 
     2774      if( arg2[ i ] < '0' || arg2[ i ] > '9' ) 
     2775      { 
     2776        trap_SendServerCommand( ent-g_entities, 
     2777          "print \"usage: share [name|slot#] [amount]\n\"" ); 
     2778        break; 
     2779      } 
     2780    } 
     2781 
     2782    // credit count from parameter 
     2783    creds = atoi( arg2 ); 
     2784  } 
     2785 
     2786  // player specified "0" to transfer 
     2787  if( creds <= 0 ) 
     2788  { 
     2789    trap_SendServerCommand( ent-g_entities, 
     2790      "print \"Ooh, you are a generous one, indeed!\n\"" ); 
     2791    return; 
     2792  } 
     2793 
     2794  // transfer only credits the player really has 
     2795  if( creds > ent->client->ps.persistant[ PERS_CREDIT ] ) 
     2796  { 
     2797    creds = ent->client->ps.persistant[ PERS_CREDIT ]; 
     2798  } 
     2799 
     2800  // player has no credits 
     2801  if( creds <= 0 ) 
     2802  { 
     2803    trap_SendServerCommand( ent-g_entities, 
     2804      "print \"Earn some first, lazy gal!\n\"" ); 
     2805    return; 
     2806  } 
     2807 
     2808  // allow transfers only up to the credit/evo limit 
     2809  if( ( team == PTE_HUMANS ) &&  
     2810      ( creds > HUMAN_MAX_CREDITS - level.clients[ clientNum ].ps.persistant[ PERS_CREDIT ] ) ) 
     2811  { 
     2812    creds = HUMAN_MAX_CREDITS - level.clients[ clientNum ].ps.persistant[ PERS_CREDIT ]; 
     2813  } 
     2814  else if( ( team == PTE_ALIENS ) &&  
     2815      ( creds > ALIEN_MAX_KILLS - level.clients[ clientNum ].ps.persistant[ PERS_CREDIT ] ) ) 
     2816  { 
     2817    creds = ALIEN_MAX_KILLS - level.clients[ clientNum ].ps.persistant[ PERS_CREDIT ]; 
     2818  } 
     2819 
     2820  // target cannot take any more credits 
     2821  if( creds <= 0 ) 
     2822  { 
     2823    trap_SendServerCommand( ent-g_entities, 
     2824      va( "print \"share: player cannot receive any more %s.\n\"", 
     2825        ( team == PTE_HUMANS ) ? "credits" : "evolvepoints" ) ); 
     2826    return; 
     2827  } 
     2828 
     2829  // transfer credits 
     2830  ent->client->ps.persistant[ PERS_CREDIT ] -= creds; 
     2831  trap_SendServerCommand( ent-g_entities, 
     2832    va( "print \"share: transferred %d %s to %s^7.\n\"", creds, 
     2833      ( team == PTE_HUMANS ) ? "credits" : "evolvepoints", 
     2834      level.clients[ clientNum ].pers.netname ) ); 
     2835  level.clients[ clientNum ].ps.persistant[ PERS_CREDIT ] += creds; 
     2836  trap_SendServerCommand( clientNum, 
     2837    va( "print \"You have received %d %s from %s^7.\n\"", creds, 
     2838      ( team == PTE_HUMANS ) ? "credits" : "evolvepoints", 
     2839      ent->client->pers.netname ) ); 
     2840 
     2841  G_LogPrintf( "Share: %i %i %i %d: %s^7 transferred %d%s to %s^7\n", 
     2842    ent->client->ps.clientNum, 
     2843    clientNum, 
     2844    team, 
     2845    creds, 
     2846    ent->client->pers.netname, 
     2847    creds, 
     2848    ( team == PTE_HUMANS ) ? "c" : "e", 
     2849    level.clients[ clientNum ].pers.netname ); 
     2850} 
     2851 
    24092852 
    24102853/* 
     
    25172960 
    25182961    // can't follow another spectator 
    2519     if( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) 
     2962    if( level.clients[ clientnum ].pers.teamSelection == PTE_NONE ) 
    25202963      continue; 
    25212964 
     
    25302973} 
    25312974 
     2975 /* 
     2976 ================= 
     2977Cmd_Donate_f 
     2978 
     2979Alms for the poor 
     2980================= 
     2981*/ 
     2982void Cmd_Donate_f( gentity_t *ent ) 
     2983{ 
     2984  int divisor; 
     2985  char s[20]; 
     2986  int skipargs = 0; 
     2987  int value; 
     2988 
     2989  if( !ent->client || !g_allowDonate.integer ) return; 
     2990 
     2991  if( ent->client->pers.teamSelection == PTE_ALIENS ) 
     2992    divisor = level.numAlienClients-1; 
     2993  else if( ent->client->pers.teamSelection == PTE_HUMANS ) 
     2994    divisor = level.numHumanClients-1; 
     2995  else 
     2996         return; 
     2997 
     2998  if(ent->client->pers.teamSelection == PTE_NONE ) 
     2999  { 
     3000    trap_SendServerCommand( ent-g_entities, 
     3001      va( "print \"donate: spectators cannot be so gracious\n\"" ) ); 
     3002    return; 
     3003  } 
     3004 
     3005  if( divisor < 1 ) { 
     3006    trap_SendServerCommand( ent-g_entities, 
     3007      "print \"donate: get yourself some teammates first\n\"" ); 
     3008    return; 
     3009  } 
     3010 
     3011  G_SayArgv ( 0, s, sizeof( s ) ); 
     3012  if ( !Q_stricmp( s, "say" ) || !Q_stricmp( s, "say_team" ) ) 
     3013  { 
     3014     skipargs = 1; 
     3015     G_SayArgv ( 1, s, sizeof( s )); //usefull ? 
     3016  } 
     3017   
     3018  G_SayArgv( 1 + skipargs, s, sizeof( s ) ); 
     3019  value = atoi(s); 
     3020  if( value <= 0 ) { 
     3021    trap_SendServerCommand( ent-g_entities, 
     3022      "print \"donate: very funny\n\"" ); 
     3023    return; 
     3024  } 
     3025 
     3026  G_Donate(ent->client, value); 
     3027} 
     3028 
    25323029/* 
    25333030================= 
     
    25453042/* 
    25463043================= 
    2547 Cmd_Follow_f 
     3044Cmd_Follow_f (with r1 changes in here) 
    25483045================= 
    25493046*/ 
     
    27883285  { "say", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f }, 
    27893286  { "say_team", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f }, 
     3287  { "say_admins", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f }, 
     3288  { "a", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f }, 
    27903289  { "m", CMD_MESSAGE|CMD_INTERMISSION, G_PrivateMessage }, 
    27913290  { "mt", CMD_MESSAGE|CMD_INTERMISSION, G_PrivateMessage }, 
    2792  
     3291  { "me", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f }, 
    27933292  { "score", CMD_INTERMISSION, ScoreboardMessage }, 
    27943293 
     
    28073306  { "ptrcverify", 0, Cmd_PTRCVerify_f }, 
    28083307  { "ptrcrestore", 0, Cmd_PTRCRestore_f }, 
     3308  { "share", CMD_TEAM, Cmd_Share_f }, 
     3309  { "donate", CMD_TEAM, Cmd_Donate_f }, 
    28093310 
    28103311  { "follow", CMD_NOTEAM, Cmd_Follow_f }, 
     
    30483549  gentity_t *tmpent; 
    30493550 
     3551  if ( g_floodProtection.integer && !G_admin_permission( ent, ADMF_NOCENSORFLOOD ) ) 
     3552  { 
     3553    if ( ent->client->pers.floodTimer >= 100 )  return; 
     3554    ent->client->pers.floodTimer += g_floodProtection.integer; 
     3555  } 
     3556 
    30503557  if( !g_privateMessages.integer && ent ) 
    30513558  { 
     
    31023609 
    31033610  color = teamonly ? COLOR_CYAN : COLOR_YELLOW; 
     3611 
     3612  if( !Q_stricmp( name, "console" ) ) 
     3613  { 
     3614    ADMP( va( "^%cPrivate message: ^7%s\n", color, msg ) ); 
     3615    ADMP( va( "^%csent to Console.\n", color ) ); 
     3616 
     3617    G_LogPrintf( "privmsg: %s^7: Console: ^6%s^7\n", 
     3618      ( ent ) ? ent->client->pers.netname : "Console", msg ); 
     3619 
     3620    return; 
     3621  } 
    31043622 
    31053623  Q_strncpyz( str, 
     
    31173635    trap_SendServerCommand( pids[ i ], va( 
    31183636      "chat \"%s^%c -> ^7%s^7: (%d recipients): ^%c%s^7\" %i", 
    3119       ( ent ) ? ent->client->pers.netname : "console", 
     3637      ( ent ) ? ent->client->pers.netname : "Console", 
    31203638      color, 
    31213639      name, 
     
    31243642      msg, 
    31253643      ent ? ent-g_entities : -1 ) ); 
    3126     if( ent ) 
    3127     { 
    3128       trap_SendServerCommand( pids[ i ], va( 
    3129         "print \">> to reply, say: /m %d [your message] <<\n\"", 
    3130         ( ent - g_entities ) ) );  
    3131     } 
     3644 
    31323645    trap_SendServerCommand( pids[ i ], va(  
    31333646      "cp \"^%cprivate message from ^7%s^7\"", color, 
    3134       ( ent ) ? ent->client->pers.netname : "console" ) ); 
     3647      ( ent ) ? ent->client->pers.netname : "Console" ) ); 
    31353648  } 
    31363649 
     
    31403653  else 
    31413654  { 
    3142     ADMP( va( "^%cPrivate message: ^7%s\n", color, msg ) ); 
     3655    if( ent ) 
     3656      ADMP( va( "^%cPrivate message: ^7%s\n", color, msg ) ); 
     3657 
    31433658    ADMP( va( "%s\n", str ) ); 
    3144  
    3145     G_LogPrintf( "%s: %s: %s: %s\n", 
    3146       ( teamonly ) ? "tprivmsg" : "privmsg", 
    3147       ( ent ) ? ent->client->pers.netname : "console", 
    3148       name, msg ); 
    31493659  } 
    31503660 
  • src/game/g_cmds.c

    r122 r123  
    8383{ 
    8484  gclient_t *cl; 
    85   int       idnum; 
     85  int       i; 
    8686  char      s2[ MAX_STRING_CHARS ]; 
    8787  char      n2[ MAX_STRING_CHARS ]; 
    8888 
    8989  // numeric values are just slot numbers 
    90   if( s[ 0 ] >= '0' && s[ 0 ] <= '9' ) 
    91   { 
    92     idnum = atoi( s ); 
    93  
    94     if( idnum < 0 || idnum >= level.maxclients ) 
     90  for( i = 0; s[ i ] && isdigit( s[ i ] ); i++ ); 
     91  if( !s[ i ] ) 
     92  { 
     93    i = atoi( s ); 
     94 
     95    if( i < 0 || i >= level.maxclients ) 
    9596      return -1; 
    9697 
    97     cl = &level.clients[ idnum ]; 
     98    cl = &level.clients[ i ]; 
    9899 
    99100    if( cl->pers.connected == CON_DISCONNECTED ) 
    100101      return -1; 
    101102 
    102     return idnum; 
     103    return i; 
    103104  } 
    104105 
     
    106107  G_SanitiseName( s, s2 ); 
    107108 
    108   for( idnum = 0, cl = level.clients; idnum < level.maxclients; idnum++, cl++ ) 
     109  for( i = 0, cl = level.clients; i < level.maxclients; i++, cl++ ) 
    109110  { 
    110111    if( cl->pers.connected == CON_DISCONNECTED ) 
     
    114115 
    115116    if( !strcmp( n2, s2 ) ) 
    116       return idnum; 
     117      return i; 
    117118  } 
    118119 
     
    950951  } 
    951952 
    952   Com_sprintf( text, sizeof( text ), "%s^7", chatText ); 
     953  Q_strncpyz( text, chatText, sizeof( text ) ); 
    953954 
    954955  //R1's simple flood protection (lowered in g_client timer actions) 
     
    16681669  VectorCopy( newOrigin, temp ); 
    16691670  temp[ 2 ] += nudgeHeight; 
    1670   trap_Trace( &tr, newOrigin, toMins, toMaxs, temp, ent->s.number, MASK_SHOT ); 
     1671  trap_Trace( &tr, newOrigin, toMins, toMaxs, temp, ent->s.number, MASK_PLAYERSOLID ); 
    16711672 
    16721673  //trace down to the ground so that we can evolve on slopes 
    16731674  VectorCopy( newOrigin, temp ); 
    16741675  temp[ 2 ] += ( nudgeHeight * tr.fraction ); 
    1675   trap_Trace( &tr, temp, toMins, toMaxs, newOrigin, ent->s.number, MASK_SHOT ); 
     1676  trap_Trace( &tr, temp, toMins, toMaxs, newOrigin, ent->s.number, MASK_PLAYERSOLID ); 
    16761677  VectorCopy( tr.endpos, newOrigin ); 
    16771678 
    16781679  //make REALLY sure 
    16791680  trap_Trace( &tr, newOrigin, toMins, toMaxs, newOrigin, 
    1680     ent->s.number, MASK_SHOT ); 
     1681    ent->s.number, MASK_PLAYERSOLID ); 
    16811682 
    16821683  //check there is room to evolve 
     
    23742375  } 
    23752376 
    2376   if( trap_Argc( ) >= 2 ) 
    2377   { 
    2378     trap_Argv( 2, s, sizeof( s ) ); 
    2379  
    2380     //retrigger the armoury menu 
    2381     if( !Q_stricmp( s, "retrigger" ) ) 
    2382       ent->client->retriggerArmouryMenu = level.framenum + RAM_FRAMES; 
    2383   } 
    2384  
    23852377  //update ClientInfo 
    23862378  ClientUserinfoChanged( ent->client->ps.clientNum ); 
     
    25402532  else 
    25412533    trap_SendServerCommand( ent-g_entities, va( "print \"Unknown item\n\"" ) ); 
    2542  
    2543   if( trap_Argc( ) >= 2 ) 
    2544   { 
    2545     trap_Argv( 2, s, sizeof( s ) ); 
    2546  
    2547     //retrigger the armoury menu 
    2548     if( !Q_stricmp( s, "retrigger" ) ) 
    2549       ent->client->retriggerArmouryMenu = level.framenum + RAM_FRAMES; 
    2550   } 
    25512534 
    25522535  //update ClientInfo 
  • src/game/g_local.h

    r119 r123  
    199199  qboolean          active;             // for power repeater, but could be useful elsewhere 
    200200  qboolean          powered;            // for human buildables 
     201  int               buildpoints;        // buildpoints remains to this generator 
    201202  int               builtBy;            // clientNum of person that built this 
    202203  gentity_t         *dccNode;           // controlling dcc 
     
    295296{ 
    296297  team_t            sessionTeam; 
     298  pTeam_t           restartTeam; //for !restart keepteams and !restart switchteams 
    297299  int               spectatorTime;    // for determining next-in-line to play 
    298300  spectatorState_t  spectatorState; 
     
    357359  qboolean            denyBuild; 
    358360  int                 adminLevel; 
     361  int                 floodTimer; 
    359362} clientPersistant_t; 
    360363 
     
    461464  int                 unlaggedTime; 
    462465 
     466  int                 jetpack_beat;         // waiting time before turn on jetpack when power down 
     467  int                 jetpack_power; 
    463468}; 
    464469 
     
    533538  int               num_entities;   // current number, <= MAX_GENTITIES 
    534539 
    535   int               warmupTime;     // restart match at this time 
    536  
    537540  fileHandle_t      logFile; 
    538541 
     
    558561  int               numPlayingClients;            // connected, non-spectators 
    559562  int               sortedClients[MAX_CLIENTS];   // sorted by score 
     563  int               numNewbies;                   // number of UnnamedPlayers who have been renamed this round. 
    560564 
    561565  int               snd_fry;                      // sound index for standing in lava 
    562  
    563   int               warmupModificationCount;      // for detecting if g_warmup is changed 
    564566 
    565567  // voting state 
     
    635637  pTeam_t           lastWin; 
    636638 
     639  int               suddenDeathABuildPoints; 
     640  int               suddenDeathHBuildPoints; 
     641  qboolean          suddenDeath; 
    637642  timeWarning_t     suddenDeathWarning; 
    638643  timeWarning_t     timelimitWarning; 
     
    655660 
    656661  char              layout[ MAX_QPATH ]; 
     662 
     663  int               warmupMessageTime;            // last warmup message level.time 
    657664 
    658665  pTeam_t           surrenderTeam; 
     
    695702void      G_MatchOnePlayer( int *plist, int num, char *err, int len ); 
    696703int       G_ClientNumbersFromString( char *s, int *plist, int max ); 
     704void      G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText ); 
    697705int       G_SayArgc( void ); 
    698706qboolean  G_SayArgv( int n, char *buffer, int bufferLength ); 
     
    703711void      G_SanitiseName( char *in, char *out ); 
    704712void      G_PrivateMessage( gentity_t *ent ); 
     713void      Cmd_Share_f( gentity_t *ent ); 
     714void      Cmd_Donate_f( gentity_t *ent ); 
    705715 
    706716// 
     
    746756                    buildable_t spawn, vec3_t spawnOrigin ); 
    747757 
     758gentity_t*        G_FindGenerator( buildableTeam_t team, vec3_t origin ); 
    748759buildable_t       G_IsPowered( vec3_t origin ); 
    749760qboolean          G_IsDCCBuilt( void ); 
     
    915926void      player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ); 
    916927qboolean  SpotWouldTelefrag( gentity_t *spot ); 
     928char     *G_NextNewbieName( gentity_t *ent ); 
    917929 
    918930// 
     
    944956void G_RunThink( gentity_t *ent ); 
    945957void QDECL G_LogPrintf( const char *fmt, ... ); 
     958void QDECL G_LogOnlyPrintf( const char *fmt, ... ); 
    946959void SendScoreboardMessageToAllClients( void ); 
    947960void QDECL G_Printf( const char *fmt, ... ); 
     
    953966void LogExit( const char *string ); 
    954967int  G_TimeTilSuddenDeath( void ); 
     968void G_Donate( gclient_t *client, short value ); 
    955969 
    956970// 
     
    962976void ClientBegin( int clientNum ); 
    963977void ClientCommand( int clientNum ); 
     978int ClientPingOverride( void ); 
    964979 
    965980// 
     
    11001115extern  vmCvar_t  g_dedicated; 
    11011116extern  vmCvar_t  g_cheats; 
     1117extern  vmCvar_t  g_version; 
    11021118extern  vmCvar_t  g_maxclients;     // allow this many total, including spectators 
    11031119extern  vmCvar_t  g_maxGameClients;   // allow this many active 
     
    11061122extern  vmCvar_t  g_minNameChangePeriod; 
    11071123extern  vmCvar_t  g_maxNameChanges; 
     1124extern  vmCvar_t  g_newbieNumbering; 
     1125extern  vmCvar_t  g_newbieNamePrefix; 
    11081126 
    11091127extern  vmCvar_t  g_timelimit; 
    11101128extern  vmCvar_t  g_suddenDeathTime; 
     1129extern  vmCvar_t  g_suddenDeathMode; 
    11111130extern  vmCvar_t  g_friendlyFire; 
    11121131extern  vmCvar_t  g_friendlyFireHumans; 
    11131132extern  vmCvar_t  g_friendlyFireAliens; 
    11141133extern  vmCvar_t  g_friendlyBuildableFire; 
     1134extern  vmCvar_t  g_friendlyFireMovementAttacks; 
    11151135extern  vmCvar_t  g_password; 
    11161136extern  vmCvar_t  g_needpass; 
     
    11291149extern  vmCvar_t  g_warmup; 
    11301150extern  vmCvar_t  g_doWarmup; 
     1151extern  vmCvar_t  g_warmupMessage; 
    11311152extern  vmCvar_t  g_blood; 
    11321153extern  vmCvar_t  g_allowVote; 
     
    11401161extern  vmCvar_t  pmove_msec; 
    11411162extern  vmCvar_t  g_rankings; 
     1163extern  vmCvar_t  g_allowShare; 
     1164extern  vmCvar_t  g_allowDonate; 
     1165extern  vmCvar_t  g_grangerMode; 
     1166extern  vmCvar_t  g_repeaterOnReactor; 
     1167extern  vmCvar_t  g_jetpackLimit; 
     1168extern  vmCvar_t  g_autoDonate; 
    11421169extern  vmCvar_t  g_enableDust; 
    11431170extern  vmCvar_t  g_enableBreath; 
     
    11461173extern  vmCvar_t  g_humanBuildPoints; 
    11471174extern  vmCvar_t  g_alienBuildPoints; 
     1175extern  vmCvar_t  g_reactorBuildPoints; 
     1176extern  vmCvar_t  g_repeaterBuildPoints; 
     1177extern  vmCvar_t  g_overmindBuildPoints; 
     1178extern  vmCvar_t  g_eggBuildPoints; 
     1179extern  vmCvar_t  g_zoneBuildPoints; 
    11481180extern  vmCvar_t  g_humanStage; 
    11491181extern  vmCvar_t  g_humanKills; 
     
    11701202extern  vmCvar_t  g_initialMapRotation; 
    11711203extern  vmCvar_t  g_chatTeamPrefix; 
     1204extern  vmCvar_t  g_specsSeeTeamchat; 
    11721205 
    11731206extern  vmCvar_t  g_shove; 
     
    11831216extern  vmCvar_t  g_adminNameProtect; 
    11841217extern  vmCvar_t  g_adminTempBan; 
    1185  
     1218extern  vmCvar_t  g_minLevelToSpecMM1; 
     1219extern  vmCvar_t  g_adminWarnMessage; 
    11861220extern  vmCvar_t  g_privateMessages; 
     1221extern  vmCvar_t  g_publicSayadmins; 
     1222extern  vmCvar_t  g_allowActions; 
     1223extern  vmCvar_t  g_actionPrefix; 
     1224extern  vmCvar_t  g_floodProtection; 
     1225extern  vmCvar_t  g_autoRegister; 
     1226 
     1227extern  vmCvar_t  g_slapKnockback; 
     1228extern  vmCvar_t  g_slapDamage; 
     1229 
     1230extern  vmCvar_t  g_hiddenClients; 
     1231 
     1232extern  vmCvar_t  g_dretchPunt; 
     1233 
     1234extern vmCvar_t g_freeFunds; 
     1235extern vmCvar_t g_fastBuild; 
     1236extern vmCvar_t g_noBaseAttack; 
     1237extern vmCvar_t g_cheatAdminLevel; // an admin above or equal this level can use cheat, disable if 0 
     1238 
     1239extern vmCvar_t  g_playerVotePercent; 
     1240extern vmCvar_t  g_globalVotePercent; 
    11871241 
    11881242void      trap_Printf( const char *fmt ); 
     
    12341288void      trap_SnapVector( float *v ); 
    12351289void      trap_SendGameStat( const char *data ); 
     1290 
     1291void      do_health( gentity_t *ent, int quantity ); 
  • src/game/g_local.h

    r122 r123  
    325325  qboolean            localClient;        // true if "ip" info key is "localhost" 
    326326  qboolean            initialSpawn;       // the first spawn should be at a cool location 
    327   qboolean            predictItemPickup;  // based on cg_predictItems userinfo 
    328327  qboolean            pmoveFixed;         // 
    329328  char                netname[ MAX_NETNAME ]; 
     
    459458 
    460459  int                 lastFlameBall;        // s.number of the last flame ball fired 
    461  
    462 #define RAM_FRAMES  1                       // number of frames to wait before retriggering 
    463   int                 retriggerArmouryMenu; // frame number to retrigger the armoury menu 
    464460 
    465461  unlagged_t          unlaggedHist[ MAX_UNLAGGED_MARKERS ]; 
  • src/qcommon/common.c

    r119 r123  
    3434 
    3535int demo_protocols[] = 
    36 { PROTOCOL_VERSION, 0 }; 
     36{ 66, 67, 68, 69, 0 }; 
    3737 
    3838#define MAX_NUM_ARGVS   50 
     
    23722372*/ 
    23732373void Com_Init( char *commandLine ) { 
    2374         char    *s; 
    23752374 
    23762375        Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, __DATE__ ); 
     
    24792478        Cmd_AddCommand ("writeconfig", Com_WriteConfig_f ); 
    24802479 
    2481         s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ ); 
    2482         com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO ); 
     2480        com_version = Cvar_Get ("version", FULL_VERSION, CVAR_ROM | CVAR_SERVERINFO ); 
    24832481 
    24842482        Sys_Init(); 
     
    26962694        } while ( msec < minMsec ); 
    26972695        Cbuf_Execute (); 
     2696        Cdelay_Frame (); 
    26982697 
    26992698        if (com_altivec->modified) 
  • src/qcommon/common.c

    r62 r123  
    29472947} 
    29482948 
     2949#ifndef DEDICATED 
     2950/* 
     2951=============== 
     2952Field_CompleteKeyname 
     2953=============== 
     2954*/ 
     2955static void Field_CompleteKeyname( void ) 
     2956{ 
     2957        matchCount = 0; 
     2958        shortestMatch[ 0 ] = 0; 
     2959 
     2960        Key_KeynameCompletion( FindMatches ); 
     2961 
     2962        if( matchCount == 0 ) 
     2963                return; 
     2964 
     2965        Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) - 
     2966                strlen( completionString ) ], shortestMatch, 
     2967                sizeof( completionField->buffer ) ); 
     2968        completionField->cursor = strlen( completionField->buffer ); 
     2969 
     2970        if( matchCount == 1 ) 
     2971        { 
     2972                Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " ); 
     2973                completionField->cursor++; 
     2974                return; 
     2975        } 
     2976 
     2977        Com_Printf( "]%s\n", completionField->buffer ); 
     2978         
     2979        Key_KeynameCompletion( PrintMatches ); 
     2980} 
     2981#endif 
     2982 
    29492983/* 
    29502984=============== 
     
    29632997                return; 
    29642998 
    2965         Q_strcat( completionField->buffer, sizeof( completionField->buffer ), 
    2966                         shortestMatch + strlen( completionString ) ); 
     2999        Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) - 
     3000                strlen( completionString ) ], shortestMatch, 
     3001                sizeof( completionField->buffer ) ); 
    29673002        completionField->cursor = strlen( completionField->buffer ); 
    29683003 
     
    30053040                completionString = Cmd_Argv( completionArgument - 1 ); 
    30063041 
     3042#ifndef DEDICATED 
     3043        // Unconditionally add a '\' to the start of the buffer 
     3044        if( completionField->buffer[ 0 ] && 
     3045                        completionField->buffer[ 0 ] != '\\' ) 
     3046        { 
     3047                if( completionField->buffer[ 0 ] != '/' ) 
     3048                { 
     3049                        // Buffer is full, refuse to complete 
     3050                        if( strlen( completionField->buffer ) + 1 >= 
     3051                                sizeof( completionField->buffer ) ) 
     3052                                return; 
     3053 
     3054                        memmove( &completionField->buffer[ 1 ], 
     3055                                &completionField->buffer[ 0 ], 
     3056                                strlen( completionField->buffer ) + 1 ); 
     3057                        completionField->cursor++; 
     3058                } 
     3059 
     3060                completionField->buffer[ 0 ] = '\\'; 
     3061        } 
     3062#endif 
     3063 
    30073064        if( completionArgument > 1 ) 
    30083065        { 
     
    30103067 
    30113068#ifndef DEDICATED 
    3012                 // If the very first token does not have a leading \ or /, 
    3013                 // refuse to autocomplete 
    3014                 if( cmd == completionField->buffer ) 
    3015                 { 
    3016                         if( baseCmd[ 0 ] != '\\' && baseCmd[ 0 ] != '/' ) 
    3017                                 return; 
    3018  
     3069                // This should always be true 
     3070                if( baseCmd[ 0 ] == '\\' || baseCmd[ 0 ] == '/' ) 
    30193071                        baseCmd++; 
    3020                 } 
    30213072#endif 
    30223073 
     
    30493100                                Field_CompleteFilename( "", "txt", qfalse ); 
    30503101                        } 
    3051                         else if( !Q_stricmp( baseCmd, "demo" ) && completionArgument == 2 ) 
    3052                         { 
    3053                                 char demoExt[ 16 ]; 
    3054  
    3055                                 Com_sprintf( demoExt, sizeof( demoExt ), ".dm_%d", PROTOCOL_VERSION ); 
    3056                                 Field_CompleteFilename( "demos", demoExt, qtrue ); 
    3057                         } 
    30583102                        else if( ( !Q_stricmp( baseCmd, "toggle" ) || 
    30593103                                                !Q_stricmp( baseCmd, "vstr" ) || 
     
    30703114                                        Field_CompleteCommand( p, qfalse, qtrue ); 
    30713115                        } 
     3116#ifndef DEDICATED 
     3117                        else if( !Q_stricmp( baseCmd, "demo" ) && completionArgument == 2 ) 
     3118                        { 
     3119                                char demoExt[ 16 ]; 
     3120 
     3121                                Com_sprintf( demoExt, sizeof( demoExt ), ".dm_%d", PROTOCOL_VERSION ); 
     3122                                Field_CompleteFilename( "demos", demoExt, qtrue ); 
     3123                        } 
    30723124                        else if( !Q_stricmp( baseCmd, "rcon" ) && completionArgument == 2 ) 
    30733125                        { 
     
    30783130                                        Field_CompleteCommand( p, qtrue, qtrue ); 
    30793131                        } 
    3080                         else if( !Q_stricmp( baseCmd, "bind" ) && completionArgument >= 3 ) 
     3132                        else if( !Q_stricmp( baseCmd, "bind" ) ) 
    30813133                        { 
    3082                                 // Skip "bind <key> " 
    3083                                 p = Com_SkipTokens( cmd, 2, " " ); 
    3084  
    3085                                 if( p > cmd ) 
    3086                                         Field_CompleteCommand( p, qtrue, qtrue ); 
     3134                                if( completionArgument == 2 ) 
     3135                                { 
     3136                                        // Skip "bind " 
     3137                                        p = Com_SkipTokens( cmd, 1, " " ); 
     3138 
     3139                                        if( p > cmd ) 
     3140                                                Field_CompleteKeyname( ); 
     3141                                } 
     3142                                else if( completionArgument >= 3 ) 
     3143                                { 
     3144                                        // Skip "bind <key> " 
     3145                                        p = Com_SkipTokens( cmd, 2, " " ); 
     3146 
     3147                                        if( p > cmd ) 
     3148                                                Field_CompleteCommand( p, qtrue, qtrue ); 
     3149                                } 
    30873150                        } 
     3151#endif 
    30883152                } 
    30893153        } 
     
    31063170 
    31073171                if( matchCount == 0 ) 
    3108                         return; // no matches 
    3109  
    3110                 if( cmd == completionField->buffer ) 
    3111                 { 
    3112 #ifndef DEDICATED 
    3113                         Com_sprintf( completionField->buffer, 
    3114                                         sizeof( completionField->buffer ), "\\%s", shortestMatch ); 
    3115 #else 
    3116                         Com_sprintf( completionField->buffer, 
    3117                                         sizeof( completionField->buffer ), "%s", shortestMatch ); 
    3118 #endif 
    3119                 } 
    3120                 else 
    3121                 { 
    3122                         Q_strcat( completionField->buffer, sizeof( completionField->buffer ), 
    3123                                         shortestMatch + strlen( completionString ) ); 
    3124                 } 
     3172                        return; // no matches 
     3173 
     3174                Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) - 
     3175                        strlen( completionString ) ], shortestMatch, 
     3176                        sizeof( completionField->buffer ) ); 
    31253177 
    31263178                completionField->cursor = strlen( completionField->buffer ); 
  • src/qcommon/cvar.c

    r119 r123  
    834834        for (var = cvar_vars ; var ; var = var->next) { 
    835835                if (var->flags & bit) { 
    836                         Info_SetValueForKey (info, var->name, var->string); 
     836                        if (!strcmp (var->name, "sv_maxclients")) { 
     837                                cvar_t *g_hiddenClients = Cvar_Get ("g_hiddenClients", "0", 0); 
     838                                Info_SetValueForKey (info, var->name, 
     839                                        va ("%i", var->integer - g_hiddenClients->integer)); 
     840                        } else { 
     841                                Info_SetValueForKey (info, var->name, var->string); 
     842                        } 
    837843                } 
    838844        } 
  • src/qcommon/cvar.c

    r1 r123  
    499499qboolean Cvar_Command( void ) { 
    500500        cvar_t  *v; 
    501         char            string[ TRUNCATE_LENGTH ]; 
    502         char            resetString[ TRUNCATE_LENGTH ]; 
    503         char            latchedString[ TRUNCATE_LENGTH ]; 
    504501 
    505502        // check variables 
     
    511508        // perform a variable print or set 
    512509        if ( Cmd_Argc() == 1 ) { 
    513                 Com_TruncateLongString( string, v->string ); 
    514                 Com_TruncateLongString( resetString, v->resetString ); 
    515510                Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\"", 
    516                                 v->name, string ); 
     511                                v->name, v->string ); 
    517512 
    518513                if ( !( v->flags & CVAR_ROM ) ) { 
    519                         if ( !Q_stricmp( string, resetString ) ) { 
     514                        if ( !Q_stricmp( v->string, v->resetString ) ) { 
    520515                                Com_Printf (", the default" ); 
    521516                        } else { 
    522517                                Com_Printf (" default:\"%s" S_COLOR_WHITE "\"", 
    523                                                 resetString ); 
     518                                                v->resetString ); 
    524519                        } 
    525520                } 
     
    528523 
    529524                if ( v->latchedString ) { 
    530                         Com_TruncateLongString( latchedString, v->latchedString ); 
    531                         Com_Printf( "latched: \"%s\"\n", latchedString ); 
     525                        Com_Printf( "latched: \"%s\"\n", v->latchedString ); 
    532526                } 
    533527                return qtrue; 
  • src/qcommon/files.c

    r119 r123  
    9898e.g. the qpath "sound/newstuff/test.wav" would be searched for in the following places: 
    9999 
     100home path + current game's directory 
    100101home path + current game's zip files 
    101 home path + current game's directory 
     102base path + current game's directory 
    102103base path + current game's zip files 
    103 base path + current game's directory 
     104cd path + current game's directory 
    104105cd path + current game's zip files 
    105 cd path + current game's directory 
    106  
     106 
     107home path + base game's directory 
    107108home path + base game's zip file 
    108 home path + base game's directory 
     109base path + base game's directory 
    109110base path + base game's zip file 
    110 base path + base game's directory 
     111cd path + base game's directory 
    111112cd path + base game's zip file 
    112 cd path + base game's directory 
    113  
     113 
     114home path + BASEGAME's directory 
    114115home path + BASEGAME's zip file 
    115 home path + BASEGAME's directory 
     116base path + BASEGAME's directory 
    116117base path + BASEGAME's zip file 
    117 base path + BASEGAME's directory 
     118cd path + BASEGAME's directory 
    118119cd path + BASEGAME's zip file 
    119 cd path + BASEGAME's directory 
    120120 
    121121server download, to be written to home path + current game's directory 
     
    24052405        Q_strncpyz( fs_gamedir, dir, sizeof( fs_gamedir ) ); 
    24062406 
    2407         // 
    2408         // add the directory to the search path 
    2409         // 
    2410         search = Z_Malloc (sizeof(searchpath_t)); 
    2411         search->dir = Z_Malloc( sizeof( *search->dir ) ); 
    2412  
    2413         Q_strncpyz( search->dir->path, path, sizeof( search->dir->path ) ); 
    2414         Q_strncpyz( search->dir->gamedir, dir, sizeof( search->dir->gamedir ) ); 
    2415         search->next = fs_searchpaths; 
    2416         fs_searchpaths = search; 
    2417  
    24182407        // find all pak files in this directory 
    24192408        pakfile = FS_BuildOSPath( path, dir, "" ); 
     
    24362425                fs_searchpaths = search; 
    24372426        } 
     2427 
     2428        // 
     2429        // add the directory to the search path 
     2430        // 
     2431        search = Z_Malloc (sizeof(searchpath_t)); 
     2432        search->dir = Z_Malloc( sizeof( *search->dir ) ); 
     2433 
     2434        Q_strncpyz( search->dir->path, path, sizeof( search->dir->path ) ); 
     2435        Q_strncpyz( search->dir->gamedir, dir, sizeof( search->dir->gamedir ) ); 
     2436        search->next = fs_searchpaths; 
     2437        fs_searchpaths = search; 
    24382438 
    24392439        // done 
  • src/qcommon/files.c

    r40 r123  
    10551055                                        } 
    10561056 
    1057                                         if (!(pak->referenced & FS_QAGAME_REF) && strstr(filename, "qagame.qvm")) { 
     1057                                        if (!(pak->referenced & FS_QAGAME_REF) && strstr(filename, "game.qvm")) { 
    10581058                                                pak->referenced |= FS_QAGAME_REF; 
    10591059                                        } 
     
    20962096                        continue; 
    20972097                } 
    2098                 // we drop "baseq3" "." and ".." 
     2098                // we drop BASEGAME "." and ".." 
    20992099                if (Q_stricmp(name, BASEGAME) && Q_stricmpn(name, ".", 1)) { 
    21002100                        // now we need to find some .pk3 files to validate the mod 
     
    27682768FS_GamePureChecksum 
    27692769 
    2770 Returns the checksum of the pk3 from which the server loaded the qagame.qvm 
     2770Returns the checksum of the pk3 from which the server loaded the game.qvm 
    27712771===================== 
    27722772*/ 
  • src/qcommon/q_shared.h

    r119 r123  
    2929 
    3030#define PRODUCT_NAME            "tremulous" 
    31 #define PRODUCT_VERSION         "1.1.0" 
     31 
     32#ifndef PRODUCT_VERSION 
     33#define PRODUCT_VERSION         "DnC-Eggy" 
     34#endif 
    3235 
    3336#ifdef SVN_VERSION 
     
    3942#define CLIENT_WINDOW_TITLE       "Tremulous " PRODUCT_VERSION 
    4043#define CLIENT_WINDOW_MIN_TITLE   "Tremulous" 
     44 
     45#define FULL_VERSION Q3_VERSION " " PLATFORM_STRING " " __DATE__ 
    4146 
    4247#define MAX_TEAMNAME 32 
     
    9196 **********************************************************************/ 
    9297 
     98#ifdef Q3_VM 
     99 
    93100#include "../game/bg_lib.h" 
    94101 
    95 #ifndef Q3_VM 
     102#else 
    96103 
    97104#include <assert.h> 
     
    336343 
    337344#define Q_COLOR_ESCAPE  '^' 
    338 #define Q_IsColorString(p)      ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && isalnum(*((p)+1)) ) // ^[0-9a-zA-Z] 
     345#define Q_IsColorString(p)      ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) 
    339346 
    340347#define COLOR_BLACK             '0' 
     
    10131020#define MAX_STATS                               16 
    10141021#define MAX_PERSISTANT                  16 
    1015 #define MAX_MISC                        16 
     1022#define MAX_POWERUPS                    16 
    10161023#define MAX_WEAPONS                             16               
    10171024 
     
    10851092        int                     stats[MAX_STATS]; 
    10861093        int                     persistant[MAX_PERSISTANT];     // stats that aren't cleared on death 
    1087         int                     misc[MAX_MISC]; // misc data 
    1088         int                     ammo;                   // ammo held 
    1089         int                     clips;                  // clips held 
     1094        int                     powerups[MAX_POWERUPS]; // level.time that the powerup runs out 
     1095        int                     ammo[MAX_WEAPONS]; 
    10901096 
    10911097        int                     generic1; 
     
    11511157        TR_SINE,                                        // value = base + sin( time / duration ) * delta 
    11521158        TR_GRAVITY, 
    1153         TR_BUOYANCY 
     1159        TR_BUOYANCY //TA: what the hell is this doing in here anyway? 
    11541160} trType_t; 
    11551161 
     
    12051211 
    12061212        // for players 
    1207         int             misc;                   // bit flags 
     1213        int             powerups;               // bit flags 
    12081214        int             weapon;                 // determines weapon and flash model, etc 
    12091215        int             legsAnim;               // mask off ANIM_TOGGLEBIT 
     
    12751281 
    12761282// server browser sources 
    1277 // AS_MPLAYER is no longer used 
    1278 #define AS_GLOBAL                       0 
     1283// TTimo: AS_MPLAYER is no longer used 
     1284#define AS_GLOBAL                       2 
    12791285#define AS_MPLAYER              1 
    1280 #define AS_LOCAL                        2 
     1286#define AS_LOCAL                        0 
    12811287#define AS_FAVORITES    3 
    12821288 
     
    13161322#define MAX_SERVERSTATUSREQUESTS        16 
    13171323 
    1318 #define SAY_ALL         0 
    1319 #define SAY_TEAM        1 
    1320 #define SAY_TELL        2 
     1324#define SAY_ALL               0 
     1325#define SAY_TEAM              1 
     1326#define SAY_TELL              2 
     1327#define SAY_ACTION      3 
     1328#define SAY_ACTION_T    4 
     1329#define SAY_ADMINS      5 
    13211330 
    13221331#endif  // __Q_SHARED_H 
  • src/qcommon/q_shared.h

    r122 r123  
    943943#define KEYCATCH_CONSOLE                0x0001 
    944944#define KEYCATCH_UI                                     0x0002 
    945 #define KEYCATCH_MESSAGE                0x0004 
    946945#define KEYCATCH_CGAME                  0x0008 
    947946 
  • src/qcommon/qcommon.h

    r119 r123  
    222222*/ 
    223223 
    224 #define PROTOCOL_VERSION        70 
     224#define PROTOCOL_VERSION        69 
    225225 
    226226// maintain a list of compatible protocols for demo playing 
     
    365365// Do not call inside a command function, or current args will be destroyed. 
    366366 
     367void Cdelay_Frame (void); 
     368//Check if a delayed command have to be executed and decreases the remaining 
     369//delay time for all of them 
     370 
    367371//=========================================================================== 
    368372 
     
    404408void    Cmd_TokenizeString( const char *text ); 
    405409void    Cmd_TokenizeStringIgnoreQuotes( const char *text_in ); 
     410void    Cmd_TokenizeStringParseCvar( const char *text_in ); 
    406411// Takes a null terminated string.  Does not need to be /n terminated. 
    407412// breaks the string up into arg tokens. 
  • src/qcommon/qcommon.h

    r62 r123  
    689689// vsnprintf is ISO/IEC 9899:1999 
    690690// abstracting this to make it portable 
    691 #ifdef WIN32 
     691#ifdef _WIN32 
    692692#define Q_vsnprintf _vsnprintf 
     693#define Q_snprintf _snprintf 
    693694#else 
    694695#define Q_vsnprintf vsnprintf 
     696#define Q_snprintf snprintf 
    695697#endif 
    696698 
     
    920922// start all the client stuff using the hunk 
    921923 
     924void Key_KeynameCompletion( void(*callback)(const char *s) ); 
     925// for keyname autocompletion 
     926 
    922927void Key_WriteBindings( fileHandle_t f ); 
    923928// for writing the config files 
  • src/ui/ui_main.c

    r119 r123  
    4242}; 
    4343 
    44 static const char *netSources[ ] = 
    45 { 
     44static const char *netSources[] = { 
     45  "LAN", 
     46  "Mplayer", 
    4647  "Internet", 
    47   "Mplayer", 
    48   "LAN", 
    4948  "Favorites" 
    5049}; 
  • src/ui/ui_main.c

    r122 r123  
    33Copyright (C) 1999-2005 Id Software, Inc. 
    44Copyright (C) 2000-2006 Tim Angus 
    5  
     5  
    66This file is part of Tremulous. 
    7  
     7  
    88Tremulous is free software; you can redistribute it 
    99and/or modify it under the terms of the GNU General Public License as 
    1010published by the Free Software Foundation; either version 2 of the License, 
    1111or (at your option) any later version. 
    12  
     12  
    1313Tremulous is distributed in the hope that it will be 
    1414useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
    1515MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1616GNU General Public License for more details. 
    17  
     17  
    1818You should have received a copy of the GNU General Public License 
    1919along with Tremulous; if not, write to the Free Software 
     
    2424/* 
    2525======================================================================= 
    26  
     26  
    2727USER INTERFACE MAIN 
    28  
     28  
    2929======================================================================= 
    3030*/ 
    3131 
    32 // use this to get a demo build without an explicit demo build, i.e. to get the demo ui files to build 
    33 //#define PRE_RELEASE_TADEMO 
    34  
    3532#include "ui_local.h" 
    3633 
    3734uiInfo_t uiInfo; 
    3835 
    39 static const char *MonthAbbrev[] = { 
    40   "Jan","Feb","Mar", 
    41   "Apr","May","Jun", 
    42   "Jul","Aug","Sep", 
    43   "Oct","Nov","Dec" 
     36static const char *MonthAbbrev[ ] = 
     37{ 
     38  "Jan", "Feb", "Mar", 
     39  "Apr", "May", "Jun", 
     40  "Jul", "Aug", "Sep", 
     41  "Oct", "Nov", "Dec" 
    4442}; 
    45  
    46  
    47 static const char *skillLevels[] = { 
    48   "I Can Win", 
    49   "Bring It On", 
    50   "Hurt Me Plenty", 
    51   "Hardcore", 
    52   "Nightmare" 
    53 }; 
    54  
    55 static const int numSkillLevels = sizeof(skillLevels) / sizeof(const char*); 
    56  
    5743 
    5844static const char *netSources[] = { 
     
    6248  "Favorites" 
    6349}; 
    64 static const int numNetSources = sizeof(netSources) / sizeof(const char*); 
    65  
    66 static const serverFilter_t serverFilters[] = { 
    67   {"All", "" }, 
    68   {"Quake 3 Arena", "" }, 
    69   {"Team Arena", "missionpack" }, 
    70   {"Rocket Arena", "arena" }, 
    71   {"Alliance", "alliance20" }, 
    72   {"Weapons Factory Arena", "wfa" }, 
    73   {"OSP", "osp" }, 
    74 }; 
    75  
    76 static const char *teamArenaGameTypes[] = { 
    77   "FFA", 
    78   "TOURNAMENT", 
    79   "SP", 
    80   "TEAM DM", 
    81   "CTF", 
    82   "1FCTF", 
    83   "OVERLOAD", 
    84   "HARVESTER", 
    85   "TEAMTOURNAMENT" 
    86 }; 
    87  
    88 static int const numTeamArenaGameTypes = sizeof(teamArenaGameTypes) / sizeof(const char*); 
    89  
    90  
    91 static const char *teamArenaGameNames[] = { 
    92   "Free For All", 
    93   "Tournament", 
    94   "Single Player", 
    95   "Team Deathmatch", 
    96   "Capture the Flag", 
    97   "One Flag CTF", 
    98   "Overload", 
    99   "Harvester", 
    100   "Team Tournament", 
    101 }; 
    102  
    103 static int const numTeamArenaGameNames = sizeof(teamArenaGameNames) / sizeof(const char*); 
    104  
    105  
    106 static const int numServerFilters = sizeof(serverFilters) / sizeof(serverFilter_t); 
    107  
    108 static const char *sortKeys[] = { 
    109   "Server Name", 
    110   "Map Name", 
    111   "Open Player Spots", 
    112   "Game Type", 
    113   "Ping Time" 
    114 }; 
    115 static const int numSortKeys = sizeof(sortKeys) / sizeof(const char*); 
    116  
    117 static char* netnames[] = { 
     50 
     51static const int numNetSources = sizeof( netSources ) / sizeof( const char* ); 
     52 
     53static const char* netnames[ ] = 
     54{ 
    11855  "???", 
    11956  "UDP", 
     
    12259}; 
    12360 
    124 static int gamecodetoui[] = {4,2,3,0,5,1,6}; 
    125  
    126  
    127 static void UI_StartServerRefresh(qboolean full); 
    128 static void UI_StopServerRefresh( void ); 
    129 static void UI_DoServerRefresh( void ); 
    130 static void UI_FeederSelection(float feederID, int index); 
    131 static void UI_BuildServerDisplayList(qboolean force); 
    132 static void UI_BuildServerStatus(qboolean force); 
    133 static void UI_BuildFindPlayerList(qboolean force); 
    134 static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ); 
    135 static int UI_MapCountByGameType(qboolean singlePlayer); 
    136 static int UI_HeadCountByTeam( void ); 
    137 static const char *UI_SelectedMap(int index, int *actual); 
    138 static const char *UI_SelectedHead(int index, int *actual); 
    139 static int UI_GetIndexFromSelection(int actual); 
    140  
    141 int ProcessNewUI( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 ); 
     61/* 
     62================ 
     63cvars 
     64================ 
     65*/ 
     66 
     67typedef struct 
     68{ 
     69  vmCvar_t  *vmCvar; 
     70  char    *cvarName; 
     71  char    *defaultString; 
     72  int     cvarFlags; 
     73} 
     74 
     75cvarTable_t; 
     76 
     77vmCvar_t  ui_browserShowFull; 
     78vmCvar_t  ui_browserShowEmpty; 
     79 
     80vmCvar_t  ui_dedicated; 
     81vmCvar_t  ui_netSource; 
     82vmCvar_t  ui_selectedMap; 
     83vmCvar_t  ui_lastServerRefresh_0; 
     84vmCvar_t  ui_lastServerRefresh_1; 
     85vmCvar_t  ui_lastServerRefresh_2; 
     86vmCvar_t  ui_lastServerRefresh_3; 
     87vmCvar_t  ui_lastServerRefresh_0_time; 
     88vmCvar_t  ui_lastServerRefresh_1_time; 
     89vmCvar_t  ui_lastServerRefresh_2_time; 
     90vmCvar_t  ui_lastServerRefresh_3_time; 
     91vmCvar_t  ui_smallFont; 
     92vmCvar_t  ui_bigFont; 
     93vmCvar_t  ui_findPlayer; 
     94vmCvar_t  ui_serverStatusTimeOut; 
     95vmCvar_t  ui_textWrapCache; 
     96vmCvar_t  ui_developer; 
     97 
     98vmCvar_t  ui_winner; 
     99 
     100static cvarTable_t    cvarTable[ ] = 
     101{ 
     102  { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE }, 
     103  { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE }, 
     104 
     105  { &ui_dedicated, "ui_dedicated", "0", CVAR_ARCHIVE }, 
     106  { &ui_netSource, "ui_netSource", "0", CVAR_ARCHIVE }, 
     107  { &ui_selectedMap, "ui_selectedMap", "0", CVAR_ARCHIVE }, 
     108  { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0", "", CVAR_ARCHIVE}, 
     109  { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1", "", CVAR_ARCHIVE}, 
     110  { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2", "", CVAR_ARCHIVE}, 
     111  { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3", "", CVAR_ARCHIVE}, 
     112  { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0_time", "", CVAR_ARCHIVE}, 
     113  { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1_time", "", CVAR_ARCHIVE}, 
     114  { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2_time", "", CVAR_ARCHIVE}, 
     115  { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3_time", "", CVAR_ARCHIVE}, 
     116  { &ui_smallFont, "ui_smallFont", "0.2", CVAR_ARCHIVE}, 
     117  { &ui_bigFont, "ui_bigFont", "0.5", CVAR_ARCHIVE}, 
     118  { &ui_findPlayer, "ui_findPlayer", "", CVAR_ARCHIVE}, 
     119  { &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE}, 
     120  { &ui_textWrapCache, "ui_textWrapCache", "1", CVAR_ARCHIVE }, 
     121  { &ui_developer, "ui_developer", "0", CVAR_ARCHIVE | CVAR_CHEAT }, 
     122}; 
     123 
     124static int    cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] ); 
    142125 
    143126/* 
    144127================ 
    145128vmMain 
    146  
     129  
    147130This is the only way control passes into the module. 
    148131This must be the very first function compiled into the .qvm file 
    149132================ 
    150133*/ 
    151 vmCvar_t  ui_new; 
    152 vmCvar_t  ui_debug; 
    153 vmCvar_t  ui_initialized; 
    154 vmCvar_t  ui_teamArenaFirstRun; 
    155  
    156 void _UI_Init( qboolean ); 
    157 void _UI_Shutdown( void ); 
    158 void _UI_KeyEvent( int key, qboolean down ); 
    159 void _UI_MouseEvent( int dx, int dy ); 
    160 void _UI_Refresh( int realtime ); 
    161 qboolean _UI_IsFullscreen( void ); 
     134void UI_Init( qboolean ); 
     135void UI_Shutdown( void ); 
     136void UI_KeyEvent( int key, qboolean down ); 
     137void UI_MouseEvent( int dx, int dy ); 
     138void UI_Refresh( int realtime ); 
     139qboolean UI_IsFullscreen( void ); 
     140void UI_SetActiveMenu( uiMenuCommand_t menu ); 
    162141intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, 
    163                               int arg4, int arg5, int arg6, int arg7, 
    164                               int arg8, int arg9, int arg10, int arg11  ) { 
    165   switch ( command ) { 
     142                 int arg4, int arg5, int arg6, int arg7, 
     143                 int arg8, int arg9, int arg10, int arg11  ) 
     144{ 
     145  switch( command ) 
     146  { 
    166147    case UI_GETAPIVERSION: 
    167148      return UI_API_VERSION; 
    168149 
    169150    case UI_INIT: 
    170       _UI_Init(arg0); 
     151      UI_Init( arg0 ); 
    171152      return 0; 
    172153 
    173154    case UI_SHUTDOWN: 
    174       _UI_Shutdown(); 
     155      UI_Shutdown(); 
    175156      return 0; 
    176157 
    177158    case UI_KEY_EVENT: 
    178       _UI_KeyEvent( arg0, arg1 ); 
     159      UI_KeyEvent( arg0, arg1 ); 
    179160      return 0; 
    180161 
    181162    case UI_MOUSE_EVENT: 
    182       _UI_MouseEvent( arg0, arg1 ); 
     163      UI_MouseEvent( arg0, arg1 ); 
    183164      return 0; 
    184165 
    185166    case UI_REFRESH: 
    186       _UI_Refresh( arg0 ); 
     167      UI_Refresh( arg0 ); 
    187168      return 0; 
    188169 
    189170    case UI_IS_FULLSCREEN: 
    190       return _UI_IsFullscreen(); 
     171      return UI_IsFullscreen(); 
    191172 
    192173    case UI_SET_ACTIVE_MENU: 
    193       _UI_SetActiveMenu( arg0 ); 
     174      UI_SetActiveMenu( arg0 ); 
    194175      return 0; 
    195176 
    196177    case UI_CONSOLE_COMMAND: 
    197       return UI_ConsoleCommand(arg0); 
     178      return UI_ConsoleCommand( arg0 ); 
    198179 
    199180    case UI_DRAW_CONNECT_SCREEN: 
     
    207188 
    208189 
    209 void AssetCache( void ) { 
     190void AssetCache( void ) 
     191{ 
    210192  uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR ); 
    211193  uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR ); 
     
    219201} 
    220202 
    221 void _UI_DrawSides(float x, float y, float w, float h, float size) { 
     203void UI_DrawSides( float x, float y, float w, float h, float size ) 
     204{ 
    222205  UI_AdjustFrom640( &x, &y, &w, &h ); 
    223206  size *= uiInfo.uiDC.xscale; 
     
    226209} 
    227210 
    228 void _UI_DrawTopBottom(float x, float y, float w, float h, float size) { 
     211void UI_DrawTopBottom( float x, float y, float w, float h, float size ) 
     212{ 
    229213  UI_AdjustFrom640( &x, &y, &w, &h ); 
    230214  size *= uiInfo.uiDC.yscale; 
     
    232216  trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader ); 
    233217} 
     218 
    234219/* 
    235220================ 
    236221UI_DrawRect 
    237  
     222  
    238223Coordinates are 640*480 virtual values 
    239224================= 
    240225*/ 
    241 void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) { 
     226void UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) 
     227{ 
    242228  trap_R_SetColor( color ); 
    243229 
    244   _UI_DrawTopBottom(x, y, width, height, size); 
    245   _UI_DrawSides(x, y, width, height, size); 
     230  UI_DrawTopBottom( x, y, width, height, size ); 
     231  UI_DrawSides( x, y, width, height, size ); 
    246232 
    247233  trap_R_SetColor( NULL ); 
    248 } 
    249  
    250  
    251  
    252  
    253 int Text_Width(const char *text, float scale, int limit) { 
    254   int count,len; 
    255   float out; 
    256   glyphInfo_t *glyph; 
    257   float useScale; 
    258   const char *s = text; 
    259   fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; 
    260   if (scale <= ui_smallFont.value) { 
    261     font = &uiInfo.uiDC.Assets.smallFont; 
    262   } else if (scale >= ui_bigFont.value) { 
    263     font = &uiInfo.uiDC.Assets.bigFont; 
    264   } 
    265   useScale = scale * font->glyphScale; 
    266   out = 0; 
    267   if (text) { 
    268     len = strlen(text); 
    269     if (limit > 0 && len > limit) { 
    270       len = limit; 
    271     } 
    272     count = 0; 
    273     while (s && *s && count < len) { 
    274       if ( Q_IsColorString(s) ) { 
    275         s += 2; 
    276         continue; 
    277       } else { 
    278         glyph = &font->glyphs[(int)*s]; 
    279         out += glyph->xSkip; 
    280         s++; 
    281         count++; 
    282       } 
    283     } 
    284   } 
    285   return out * useScale; 
    286 } 
    287  
    288 int Text_Height(const char *text, float scale, int limit) { 
    289   int len, count; 
    290   float max; 
    291   glyphInfo_t *glyph; 
    292   float useScale; 
    293   const char *s = text; 
    294   fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; 
    295   if (scale <= ui_smallFont.value) { 
    296     font = &uiInfo.uiDC.Assets.smallFont; 
    297   } else if (scale >= ui_bigFont.value) { 
    298     font = &uiInfo.uiDC.Assets.bigFont; 
    299   } 
    300   useScale = scale * font->glyphScale; 
    301   max = 0; 
    302   if (text) { 
    303     len = strlen(text); 
    304     if (limit > 0 && len > limit) { 
    305       len = limit; 
    306     } 
    307     count = 0; 
    308     while (s && *s && count < len) { 
    309       if ( Q_IsColorString(s) ) { 
    310         s += 2; 
    311         continue; 
    312       } else { 
    313         glyph = &font->glyphs[(int)*s]; 
    314         if (max < glyph->height) { 
    315           max = glyph->height; 
    316         } 
    317         s++; 
    318         count++; 
    319       } 
    320     } 
    321   } 
    322   return max * useScale; 
    323 } 
    324  
    325 void Text_PaintChar(float x, float y, float width, float height, float scale, float s, float t, float s2, float t2, qhandle_t hShader) { 
    326   float w, h; 
    327   w = width * scale; 
    328   h = height * scale; 
    329   UI_AdjustFrom640( &x, &y, &w, &h ); 
    330   trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader ); 
    331 } 
    332  
    333 void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style) { 
    334   int len, count; 
    335   vec4_t newColor; 
    336   glyphInfo_t *glyph; 
    337   float useScale; 
    338   fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; 
    339   if (scale <= ui_smallFont.value) { 
    340     font = &uiInfo.uiDC.Assets.smallFont; 
    341   } else if (scale >= ui_bigFont.value) { 
    342     font = &uiInfo.uiDC.Assets.bigFont; 
    343   } 
    344   useScale = scale * font->glyphScale; 
    345   if (text) { 
    346     const char *s = text; 
    347     trap_R_SetColor( color ); 
    348     memcpy(&newColor[0], &color[0], sizeof(vec4_t)); 
    349     len = strlen(text); 
    350     if (limit > 0 && len > limit) { 
    351       len = limit; 
    352     } 
    353     count = 0; 
    354     while (s && *s && count < len) { 
    355       glyph = &font->glyphs[(int)*s]; 
    356       //int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top; 
    357       //float yadj = scale * (Assets.textFont.glyphs[text[i]].imageHeight - Assets.textFont.glyphs[text[i]].height); 
    358       if ( Q_IsColorString( s ) ) { 
    359         memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); 
    360         newColor[3] = color[3]; 
    361         trap_R_SetColor( newColor ); 
    362         s += 2; 
    363         continue; 
    364       } else { 
    365         float yadj = useScale * glyph->top; 
    366         if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) { 
    367           int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2; 
    368           colorBlack[3] = newColor[3]; 
    369           trap_R_SetColor( colorBlack ); 
    370           Text_PaintChar(x + ofs, y - yadj + ofs, 
    371                             glyph->imageWidth, 
    372                             glyph->imageHeight, 
    373                             useScale, 
    374                             glyph->s, 
    375                             glyph->t, 
    376                             glyph->s2, 
    377                             glyph->t2, 
    378                             glyph->glyph); 
    379           trap_R_SetColor( newColor ); 
    380           colorBlack[3] = 1.0; 
    381         } 
    382         else if( style == ITEM_TEXTSTYLE_NEON ) 
    383         { 
    384           vec4_t glow, outer, inner, white; 
    385  
    386           glow[ 0 ] = newColor[ 0 ] * 0.5; 
    387           glow[ 1 ] = newColor[ 1 ] * 0.5; 
    388           glow[ 2 ] = newColor[ 2 ] * 0.5; 
    389           glow[ 3 ] = newColor[ 3 ] * 0.2; 
    390  
    391           outer[ 0 ] = newColor[ 0 ]; 
    392           outer[ 1 ] = newColor[ 1 ]; 
    393           outer[ 2 ] = newColor[ 2 ]; 
    394           outer[ 3 ] = newColor[ 3 ]; 
    395  
    396           inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5; 
    397           inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5; 
    398           inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5; 
    399           inner[ 3 ] = newColor[ 3 ]; 
    400  
    401           white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f; 
    402  
    403           trap_R_SetColor( glow ); 
    404           Text_PaintChar( x - 1.5, y - yadj - 1.5, 
    405                           glyph->imageWidth + 3, 
    406                           glyph->imageHeight + 3, 
    407                           useScale, 
    408                           glyph->s, 
    409                           glyph->t, 
    410                           glyph->s2, 
    411                           glyph->t2, 
    412                           glyph->glyph ); 
    413  
    414           trap_R_SetColor( outer ); 
    415           Text_PaintChar( x - 1, y - yadj - 1, 
    416                           glyph->imageWidth + 2, 
    417                           glyph->imageHeight + 2, 
    418                           useScale, 
    419                           glyph->s, 
    420                           glyph->t, 
    421                           glyph->s2, 
    422                           glyph->t2, 
    423                           glyph->glyph ); 
    424  
    425           trap_R_SetColor( inner ); 
    426           Text_PaintChar( x - 0.5, y - yadj - 0.5, 
    427                           glyph->imageWidth + 1, 
    428                           glyph->imageHeight + 1, 
    429                           useScale, 
    430                           glyph->s, 
    431                           glyph->t, 
    432                           glyph->s2, 
    433                           glyph->t2, 
    434                           glyph->glyph ); 
    435  
    436           trap_R_SetColor( white ); 
    437         } 
    438  
    439         Text_PaintChar(x, y - yadj, 
    440                           glyph->imageWidth, 
    441                           glyph->imageHeight, 
    442                           useScale, 
    443                           glyph->s, 
    444                           glyph->t, 
    445                           glyph->s2, 
    446                           glyph->t2, 
    447                           glyph->glyph); 
    448  
    449         x += (glyph->xSkip * useScale) + adjust; 
    450         s++; 
    451         count++; 
    452       } 
    453     } 
    454     trap_R_SetColor( NULL ); 
    455   } 
    456 } 
    457  
    458 void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style) { 
    459   int len, count; 
    460   vec4_t newColor; 
    461   glyphInfo_t *glyph, *glyph2; 
    462   float yadj; 
    463   float useScale; 
    464   fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; 
    465   if (scale <= ui_smallFont.value) { 
    466     font = &uiInfo.uiDC.Assets.smallFont; 
    467   } else if (scale >= ui_bigFont.value) { 
    468     font = &uiInfo.uiDC.Assets.bigFont; 
    469   } 
    470   useScale = scale * font->glyphScale; 
    471   if (text) { 
    472     const char *s = text; 
    473     trap_R_SetColor( color ); 
    474     memcpy(&newColor[0], &color[0], sizeof(vec4_t)); 
    475     len = strlen(text); 
    476     if (limit > 0 && len > limit) { 
    477       len = limit; 
    478     } 
    479     count = 0; 
    480     glyph2 = &font->glyphs[ (int) cursor]; 
    481     while (s && *s && count < len) { 
    482       glyph = &font->glyphs[(int)*s]; 
    483       if ( Q_IsColorString( s ) ) { 
    484         memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); 
    485         newColor[3] = color[3]; 
    486         trap_R_SetColor( newColor ); 
    487         s += 2; 
    488         continue; 
    489       } else { 
    490         yadj = useScale * glyph->top; 
    491         if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) { 
    492           int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2; 
    493           colorBlack[3] = newColor[3]; 
    494           trap_R_SetColor( colorBlack ); 
    495           Text_PaintChar(x + ofs, y - yadj + ofs, 
    496                             glyph->imageWidth, 
    497                             glyph->imageHeight, 
    498                             useScale, 
    499                             glyph->s, 
    500                             glyph->t, 
    501                             glyph->s2, 
    502                             glyph->t2, 
    503                             glyph->glyph); 
    504           colorBlack[3] = 1.0; 
    505           trap_R_SetColor( newColor ); 
    506         } 
    507         else if( style == ITEM_TEXTSTYLE_NEON ) 
    508         { 
    509           vec4_t glow, outer, inner, white; 
    510  
    511           glow[ 0 ] = newColor[ 0 ] * 0.5; 
    512           glow[ 1 ] = newColor[ 1 ] * 0.5; 
    513           glow[ 2 ] = newColor[ 2 ] * 0.5; 
    514           glow[ 3 ] = newColor[ 3 ] * 0.2; 
    515  
    516           outer[ 0 ] = newColor[ 0 ]; 
    517           outer[ 1 ] = newColor[ 1 ]; 
    518           outer[ 2 ] = newColor[ 2 ]; 
    519           outer[ 3 ] = newColor[ 3 ]; 
    520  
    521           inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5; 
    522           inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5; 
    523           inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5; 
    524           inner[ 3 ] = newColor[ 3 ]; 
    525  
    526           white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f; 
    527  
    528           trap_R_SetColor( glow ); 
    529           Text_PaintChar( x - 1.5, y - yadj - 1.5, 
    530                           glyph->imageWidth + 3, 
    531                           glyph->imageHeight + 3, 
    532                           useScale, 
    533                           glyph->s, 
    534                           glyph->t, 
    535                           glyph->s2, 
    536                           glyph->t2, 
    537                           glyph->glyph ); 
    538  
    539           trap_R_SetColor( outer ); 
    540           Text_PaintChar( x - 1, y - yadj - 1, 
    541                           glyph->imageWidth + 2, 
    542                           glyph->imageHeight + 2, 
    543                           useScale, 
    544                           glyph->s, 
    545                           glyph->t, 
    546                           glyph->s2, 
    547                           glyph->t2, 
    548                           glyph->glyph ); 
    549  
    550           trap_R_SetColor( inner ); 
    551           Text_PaintChar( x - 0.5, y - yadj - 0.5, 
    552                           glyph->imageWidth + 1, 
    553                           glyph->imageHeight + 1, 
    554                           useScale, 
    555                           glyph->s, 
    556                           glyph->t, 
    557                           glyph->s2, 
    558                           glyph->t2, 
    559                           glyph->glyph ); 
    560  
    561           trap_R_SetColor( white ); 
    562         } 
    563  
    564         Text_PaintChar(x, y - yadj, 
    565                           glyph->imageWidth, 
    566                           glyph->imageHeight, 
    567                           useScale, 
    568                           glyph->s, 
    569                           glyph->t, 
    570                           glyph->s2, 
    571                           glyph->t2, 
    572                           glyph->glyph); 
    573  
    574         // 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); 
    575         yadj = useScale * glyph2->top; 
    576         if (count == cursorPos && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) { 
    577           Text_PaintChar(x, y - yadj, 
    578                             glyph2->imageWidth, 
    579                             glyph2->imageHeight, 
    580                             useScale, 
    581                             glyph2->s, 
    582                             glyph2->t, 
    583                             glyph2->s2, 
    584                             glyph2->t2, 
    585                             glyph2->glyph); 
    586         } 
    587  
    588         x += (glyph->xSkip * useScale); 
    589         s++; 
    590         count++; 
    591       } 
    592     } 
    593     // need to paint cursor at end of text 
    594     if (cursorPos == len && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) { 
    595         yadj = useScale * glyph2->top; 
    596         Text_PaintChar(x, y - yadj, 
    597                           glyph2->imageWidth, 
    598                           glyph2->imageHeight, 
    599                           useScale, 
    600                           glyph2->s, 
    601                           glyph2->t, 
    602                           glyph2->s2, 
    603                           glyph2->t2, 
    604                           glyph2->glyph); 
    605  
    606     } 
    607  
    608  
    609     trap_R_SetColor( NULL ); 
    610   } 
    611 } 
    612  
    613  
    614 static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char* text, float adjust, int limit) { 
    615   int len, count; 
    616   vec4_t newColor; 
    617   glyphInfo_t *glyph; 
    618   if (text) { 
    619     const char *s = text; 
    620     float max = *maxX; 
    621     float useScale; 
    622     fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; 
    623     if (scale <= ui_smallFont.value) { 
    624       font = &uiInfo.uiDC.Assets.smallFont; 
    625     } else if (scale > ui_bigFont.value) { 
    626       font = &uiInfo.uiDC.Assets.bigFont; 
    627     } 
    628     useScale = scale * font->glyphScale; 
    629     trap_R_SetColor( color ); 
    630     len = strlen(text); 
    631     if (limit > 0 && len > limit) { 
    632       len = limit; 
    633     } 
    634     count = 0; 
    635     while (s && *s && count < len) { 
    636       glyph = &font->glyphs[(int)*s]; 
    637       if ( Q_IsColorString( s ) ) { 
    638         memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) ); 
    639         newColor[3] = color[3]; 
    640         trap_R_SetColor( newColor ); 
    641         s += 2; 
    642         continue; 
    643       } else { 
    644         float yadj = useScale * glyph->top; 
    645         if (Text_Width(s, useScale, 1) + x > max) { 
    646           *maxX = 0; 
    647           break; 
    648         } 
    649         Text_PaintChar(x, y - yadj, 
    650                        glyph->imageWidth, 
    651                        glyph->imageHeight, 
    652                        useScale, 
    653                        glyph->s, 
    654                        glyph->t, 
    655                        glyph->s2, 
    656                        glyph->t2, 
    657                        glyph->glyph); 
    658         x += (glyph->xSkip * useScale) + adjust; 
    659         *maxX = x; 
    660         count++; 
    661         s++; 
    662       } 
    663     } 
    664     trap_R_SetColor( NULL ); 
    665   } 
    666  
    667 } 
    668  
    669  
    670 void UI_ShowPostGame(qboolean newHigh) { 
    671   trap_Cvar_Set ("cg_cameraOrbit", "0"); 
    672   trap_Cvar_Set("cg_thirdPerson", "0"); 
    673   trap_Cvar_Set( "sv_killserver", "1" ); 
    674   uiInfo.soundHighScore = newHigh; 
    675   _UI_SetActiveMenu(UIMENU_POSTGAME); 
    676 } 
    677 /* 
    678 ================= 
    679 _UI_Refresh 
    680 ================= 
    681 */ 
    682  
    683 void UI_DrawCenteredPic(qhandle_t image, int w, int h) { 
    684   int x, y; 
    685   x = (SCREEN_WIDTH - w) / 2; 
    686   y = (SCREEN_HEIGHT - h) / 2; 
    687   UI_DrawHandlePic(x, y, w, h, image); 
    688 } 
    689  
    690 int frameCount = 0; 
    691 int startTime; 
    692  
    693 #define UI_FPS_FRAMES 4 
    694 void _UI_Refresh( int realtime ) 
    695 { 
    696   static int index; 
    697   static int  previousTimes[UI_FPS_FRAMES]; 
    698  
    699   //if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { 
    700   //  return; 
    701   //} 
    702  
    703   uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime; 
    704   uiInfo.uiDC.realTime = realtime; 
    705  
    706   previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime; 
    707   index++; 
    708   if ( index > UI_FPS_FRAMES ) { 
    709     int i, total; 
    710     // average multiple frames together to smooth changes out a bit 
    711     total = 0; 
    712     for ( i = 0 ; i < UI_FPS_FRAMES ; i++ ) { 
    713       total += previousTimes[i]; 
    714     } 
    715     if ( !total ) { 
    716       total = 1; 
    717     } 
    718     uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total; 
    719   } 
    720  
    721  
    722  
    723   UI_UpdateCvars(); 
    724  
    725   if (Menu_Count() > 0) { 
    726     // paint all the menus 
    727     Menu_PaintAll(); 
    728     // refresh server browser list 
    729     UI_DoServerRefresh(); 
    730     // refresh server status 
    731     UI_BuildServerStatus(qfalse); 
    732     // refresh find player list 
    733     UI_BuildFindPlayerList(qfalse); 
    734   } 
    735  
    736   // draw cursor 
    737   UI_SetColor( NULL ); 
    738  
    739   // don't draw the cursor whilst loading 
    740   if( Menu_Count( ) > 0 && !trap_Cvar_VariableValue( "ui_loading" ) ) 
    741     UI_DrawHandlePic( uiInfo.uiDC.cursorx-16, uiInfo.uiDC.cursory-16, 32, 32, uiInfo.uiDC.Assets.cursor); 
    742  
    743 #ifndef NDEBUG 
    744   if (uiInfo.uiDC.debug) 
    745   { 
    746     // cursor coordinates 
    747     //FIXME 
    748     //UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed ); 
    749   } 
    750 #endif 
    751  
    752 } 
    753  
    754 /* 
    755 ================= 
    756 _UI_Shutdown 
    757 ================= 
    758 */ 
    759 void _UI_Shutdown( void ) { 
    760   trap_LAN_SaveCachedServers(); 
    761 } 
    762  
    763 char *defaultMenu = NULL; 
    764  
    765 char *GetMenuBuffer(const char *filename) { 
    766   int len; 
    767   fileHandle_t  f; 
    768   static char buf[MAX_MENUFILE]; 
    769  
    770   len = trap_FS_FOpenFile( filename, &f, FS_READ ); 
    771   if ( !f ) { 
    772     trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) ); 
    773     return defaultMenu; 
    774   } 
    775   if ( len >= MAX_MENUFILE ) { 
    776     trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) ); 
    777     trap_FS_FCloseFile( f ); 
    778     return defaultMenu; 
    779   } 
    780  
    781   trap_FS_Read( buf, len, f ); 
    782   buf[len] = 0; 
    783   trap_FS_FCloseFile( f ); 
    784   //COM_Compress(buf); 
    785   return buf; 
    786  
    787 } 
    788  
    789 qboolean Asset_Parse(int handle) { 
    790   pc_token_t token; 
    791   const char *tempStr; 
    792  
    793   if (!trap_Parse_ReadToken(handle, &token)) 
    794     return qfalse; 
    795   if (Q_stricmp(token.string, "{") != 0) { 
    796     return qfalse; 
    797   } 
    798  
    799   while ( 1 ) { 
    800  
    801     memset(&token, 0, sizeof(pc_token_t)); 
    802  
    803     if (!trap_Parse_ReadToken(handle, &token)) 
    804       return qfalse; 
    805  
    806     if (Q_stricmp(token.string, "}") == 0) { 
    807       return qtrue; 
    808     } 
    809  
    810     // font 
    811     if (Q_stricmp(token.string, "font") == 0) { 
    812       int pointSize; 
    813       if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) { 
    814         return qfalse; 
    815       } 
    816       trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont); 
    817       uiInfo.uiDC.Assets.fontRegistered = qtrue; 
    818       continue; 
    819     } 
    820  
    821     if (Q_stricmp(token.string, "smallFont") == 0) { 
    822       int pointSize; 
    823       if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) { 
    824         return qfalse; 
    825       } 
    826       trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.smallFont); 
    827       continue; 
    828     } 
    829  
    830     if (Q_stricmp(token.string, "bigFont") == 0) { 
    831       int pointSize; 
    832       if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) { 
    833         return qfalse; 
    834       } 
    835       trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.bigFont); 
    836       continue; 
    837     } 
    838  
    839  
    840     // gradientbar 
    841     if (Q_stricmp(token.string, "gradientbar") == 0) { 
    842       if (!PC_String_Parse(handle, &tempStr)) { 
    843         return qfalse; 
    844       } 
    845       uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(tempStr); 
    846       continue; 
    847     } 
    848  
    849     // enterMenuSound 
    850     if (Q_stricmp(token.string, "menuEnterSound") == 0) { 
    851       if (!PC_String_Parse(handle, &tempStr)) { 
    852         return qfalse; 
    853       } 
    854       uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse ); 
    855       continue; 
    856     } 
    857  
    858     // exitMenuSound 
    859     if (Q_stricmp(token.string, "menuExitSound") == 0) { 
    860       if (!PC_String_Parse(handle, &tempStr)) { 
    861         return qfalse; 
    862       } 
    863       uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse ); 
    864       continue; 
    865     } 
    866  
    867     // itemFocusSound 
    868     if (Q_stricmp(token.string, "itemFocusSound") == 0) { 
    869       if (!PC_String_Parse(handle, &tempStr)) { 
    870         return qfalse; 
    871       } 
    872       uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse ); 
    873       continue; 
    874     } 
    875  
    876     // menuBuzzSound 
    877     if (Q_stricmp(token.string, "menuBuzzSound") == 0) { 
    878       if (!PC_String_Parse(handle, &tempStr)) { 
    879         return qfalse; 
    880       } 
    881       uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse ); 
    882       continue; 
    883     } 
    884  
    885     if (Q_stricmp(token.string, "cursor") == 0) { 
    886       if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr)) { 
    887         return qfalse; 
    888       } 
    889       uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr); 
    890       continue; 
    891     } 
    892  
    893     if (Q_stricmp(token.string, "fadeClamp") == 0) { 
    894       if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp)) { 
    895         return qfalse; 
    896       } 
    897       continue; 
    898     } 
    899  
    900     if (Q_stricmp(token.string, "fadeCycle") == 0) { 
    901       if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle)) { 
    902         return qfalse; 
    903       } 
    904       continue; 
    905     } 
    906  
    907     if (Q_stricmp(token.string, "fadeAmount") == 0) { 
    908       if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount)) { 
    909         return qfalse; 
    910       } 
    911       continue; 
    912     } 
    913  
    914     if (Q_stricmp(token.string, "shadowX") == 0) { 
    915       if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX)) { 
    916         return qfalse; 
    917       } 
    918       continue; 
    919     } 
    920  
    921     if (Q_stricmp(token.string, "shadowY") == 0) { 
    922       if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY)) { 
    923         return qfalse; 
    924       } 
    925       continue; 
    926     } 
    927  
    928     if (Q_stricmp(token.string, "shadowColor") == 0) { 
    929       if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor)) { 
    930         return qfalse; 
    931       } 
    932       uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3]; 
    933       continue; 
    934     } 
    935  
    936   } 
    937   return qfalse; 
    938 } 
    939  
    940 void Font_Report( void ) { 
    941   int i; 
    942   Com_Printf("Font Info\n"); 
    943   Com_Printf("=========\n"); 
    944   for ( i = 32; i < 96; i++) { 
    945     Com_Printf("Glyph handle %i: %i\n", i, uiInfo.uiDC.Assets.textFont.glyphs[i].glyph); 
    946   } 
    947 } 
    948  
    949 void UI_Report( void ) { 
    950   String_Report(); 
    951   //Font_Report(); 
    952  
    953 } 
    954  
    955 void UI_ParseMenu(const char *menuFile) { 
    956   int handle; 
    957   pc_token_t token; 
    958  
    959   /*Com_Printf("Parsing menu file:%s\n", menuFile);*/ 
    960  
    961   handle = trap_Parse_LoadSource(menuFile); 
    962   if (!handle) { 
    963     return; 
    964   } 
    965  
    966   while ( 1 ) { 
    967     memset(&token, 0, sizeof(pc_token_t)); 
    968     if (!trap_Parse_ReadToken( handle, &token )) { 
    969       break; 
    970     } 
    971  
    972     //if ( Q_stricmp( token, "{" ) ) { 
    973     //  Com_Printf( "Missing { in menu file\n" ); 
    974     //  break; 
    975     //} 
    976  
    977     //if ( menuCount == MAX_MENUS ) { 
    978     //  Com_Printf( "Too many menus!\n" ); 
    979     //  break; 
    980     //} 
    981  
    982     if ( token.string[0] == '}' ) { 
    983       break; 
    984     } 
    985  
    986     if (Q_stricmp(token.string, "assetGlobalDef") == 0) { 
    987       if (Asset_Parse(handle)) { 
    988         continue; 
    989       } else { 
    990         break; 
    991       } 
    992     } 
    993  
    994     if (Q_stricmp(token.string, "menudef") == 0) { 
    995       // start a new menu 
    996       Menu_New(handle); 
    997     } 
    998   } 
    999   trap_Parse_FreeSource(handle); 
    1000 } 
    1001  
    1002 qboolean Load_Menu(int handle) { 
    1003   pc_token_t token; 
    1004  
    1005   if (!trap_Parse_ReadToken(handle, &token)) 
    1006     return qfalse; 
    1007   if (token.string[0] != '{') { 
    1008     return qfalse; 
    1009   } 
    1010  
    1011   while ( 1 ) { 
    1012  
    1013     if (!trap_Parse_ReadToken(handle, &token)) 
    1014       return qfalse; 
    1015  
    1016     if ( token.string[0] == 0 ) { 
    1017       return qfalse; 
    1018     } 
    1019  
    1020     if ( token.string[0] == '}' ) { 
    1021       return qtrue; 
    1022     } 
    1023  
    1024     UI_ParseMenu(token.string); 
    1025   } 
    1026   return qfalse; 
    1027 } 
    1028  
    1029 void UI_LoadMenus(const char *menuFile, qboolean reset) { 
    1030   pc_token_t token; 
    1031   int handle; 
    1032   int start; 
    1033  
    1034   start = trap_Milliseconds(); 
    1035  
    1036   handle = trap_Parse_LoadSource( menuFile ); 
    1037   if (!handle) { 
    1038     trap_Error( va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n" ) ); 
    1039   } 
    1040  
    1041   ui_new.integer = 1; 
    1042  
    1043   if (reset) { 
    1044     Menu_Reset(); 
    1045   } 
    1046  
    1047   while ( 1 ) { 
    1048     if (!trap_Parse_ReadToken(handle, &token)) 
    1049       break; 
    1050     if( token.string[0] == 0 || token.string[0] == '}') { 
    1051       break; 
    1052     } 
    1053  
    1054     if ( token.string[0] == '}' ) { 
    1055       break; 
    1056     } 
    1057  
    1058     if (Q_stricmp(token.string, "loadmenu") == 0) { 
    1059       if (Load_Menu(handle)) { 
    1060         continue; 
    1061       } else { 
    1062         break; 
    1063       } 
    1064     } 
    1065   } 
    1066  
    1067   Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start); 
    1068  
    1069   trap_Parse_FreeSource( handle ); 
    1070 } 
    1071  
    1072 void UI_Load( void ) { 
    1073   char lastName[1024]; 
    1074   menuDef_t *menu = Menu_GetFocused(); 
    1075   if (menu && menu->window.name) { 
    1076     strcpy(lastName, menu->window.name); 
    1077   } 
    1078  
    1079   String_Init(); 
    1080  
    1081   UI_LoadMenus("ui/menus.txt", qtrue); 
    1082   Menus_CloseAll(); 
    1083   Menus_ActivateByName(lastName); 
    1084  
    1085 } 
    1086  
    1087 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}; 
    1088  
    1089 static void UI_DrawHandicap(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1090   int i, h; 
    1091  
    1092   h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); 
    1093   i = 20 - h / 5; 
    1094  
    1095   Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle); 
    1096 } 
    1097  
    1098 static void UI_DrawClanName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1099   Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_teamName"), 0, 0, textStyle); 
    1100 } 
    1101  
    1102  
    1103 static void UI_SetCapFragLimits(qboolean uiVars) { 
    1104   int cap = 5; 
    1105   int frag = 10; 
    1106   if (uiVars) { 
    1107     trap_Cvar_Set("ui_captureLimit", va("%d", cap)); 
    1108     trap_Cvar_Set("ui_fragLimit", va("%d", frag)); 
    1109   } else { 
    1110     trap_Cvar_Set("capturelimit", va("%d", cap)); 
    1111     trap_Cvar_Set("fraglimit", va("%d", frag)); 
    1112   } 
    1113 } 
    1114 // ui_gameType assumes gametype 0 is -1 ALL and will not show 
    1115 static void UI_DrawGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1116   Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_gameType.integer].gameType, 0, 0, textStyle); 
    1117 } 
    1118  
    1119 static void UI_DrawNetGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1120   if (ui_netGameType.integer < 0 || ui_netGameType.integer > uiInfo.numGameTypes) { 
    1121     trap_Cvar_Set("ui_netGameType", "0"); 
    1122     trap_Cvar_Set("ui_actualNetGameType", "0"); 
    1123   } 
    1124   Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_netGameType.integer].gameType , 0, 0, textStyle); 
    1125 } 
    1126  
    1127 static void UI_DrawJoinGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1128   if (ui_joinGameType.integer < 0 || ui_joinGameType.integer > uiInfo.numJoinGameTypes) { 
    1129     trap_Cvar_Set("ui_joinGameType", "0"); 
    1130   } 
    1131   Text_Paint(rect->x, rect->y, scale, color, uiInfo.joinGameTypes[ui_joinGameType.integer].gameType , 0, 0, textStyle); 
    1132 } 
    1133  
    1134  
    1135  
    1136 static int UI_TeamIndexFromName(const char *name) { 
    1137   int i; 
    1138  
    1139   if (name && *name) { 
    1140     for (i = 0; i < uiInfo.teamCount; i++) { 
    1141       if (Q_stricmp(name, uiInfo.teamList[i].teamName) == 0) { 
    1142         return i; 
    1143       } 
    1144     } 
    1145   } 
    1146  
    1147   return 0; 
    1148  
    1149 } 
    1150  
    1151 static void UI_DrawClanLogo(rectDef_t *rect, float scale, vec4_t color) { 
    1152   int i; 
    1153   i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    1154   if (i >= 0 && i < uiInfo.teamCount) { 
    1155     trap_R_SetColor( color ); 
    1156  
    1157     if (uiInfo.teamList[i].teamIcon == -1) { 
    1158       uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); 
    1159       uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); 
    1160       uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); 
    1161     } 
    1162  
    1163     UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon); 
    1164     trap_R_SetColor(NULL); 
    1165   } 
    1166 } 
    1167  
    1168 static void UI_DrawClanCinematic(rectDef_t *rect, float scale, vec4_t color) { 
    1169   int i; 
    1170   i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    1171   if (i >= 0 && i < uiInfo.teamCount) { 
    1172  
    1173     if (uiInfo.teamList[i].cinematic >= -2) { 
    1174       if (uiInfo.teamList[i].cinematic == -1) { 
    1175         uiInfo.teamList[i].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.teamList[i].imageName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); 
    1176       } 
    1177       if (uiInfo.teamList[i].cinematic >= 0) { 
    1178         trap_CIN_RunCinematic(uiInfo.teamList[i].cinematic); 
    1179         trap_CIN_SetExtents(uiInfo.teamList[i].cinematic, rect->x, rect->y, rect->w, rect->h); 
    1180         trap_CIN_DrawCinematic(uiInfo.teamList[i].cinematic); 
    1181       } else { 
    1182           trap_R_SetColor( color ); 
    1183         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal); 
    1184         trap_R_SetColor(NULL); 
    1185         uiInfo.teamList[i].cinematic = -2; 
    1186       } 
    1187     } else { 
    1188       trap_R_SetColor( color ); 
    1189       UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon); 
    1190       trap_R_SetColor(NULL); 
    1191     } 
    1192   } 
    1193  
    1194 } 
    1195  
    1196 static void UI_DrawPreviewCinematic(rectDef_t *rect, float scale, vec4_t color) { 
    1197   if (uiInfo.previewMovie > -2) { 
    1198     uiInfo.previewMovie = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.movieList[uiInfo.movieIndex]), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); 
    1199     if (uiInfo.previewMovie >= 0) { 
    1200       trap_CIN_RunCinematic(uiInfo.previewMovie); 
    1201       trap_CIN_SetExtents(uiInfo.previewMovie, rect->x, rect->y, rect->w, rect->h); 
    1202       trap_CIN_DrawCinematic(uiInfo.previewMovie); 
    1203     } else { 
    1204       uiInfo.previewMovie = -2; 
    1205     } 
    1206   } 
    1207  
    1208 } 
    1209  
    1210  
    1211 /* 
    1212 =============== 
    1213 UI_DrawInfoPane 
    1214 =============== 
    1215 */ 
    1216 static void UI_DrawInfoPane( menuItem_t *item, rectDef_t *rect, float text_x, float text_y, 
    1217                              float scale, vec4_t color, int textStyle ) 
    1218 { 
    1219   float     maxLeft = 0, maxTop = 0; 
    1220   float     maxRight = 0, maxBottom = 0; 
    1221   float     x = rect->x - text_x, y = rect->y - text_y, w, h; 
    1222   menuDef_t dummyParent; 
    1223   itemDef_t textItem; 
    1224   int       value = 0; 
    1225   char      *string = ""; 
    1226   int       class, credits; 
    1227   char      ui_currentClass[ MAX_STRING_CHARS ]; 
    1228  
    1229   trap_Cvar_VariableStringBuffer( "ui_currentClass", ui_currentClass, MAX_STRING_CHARS ); 
    1230   sscanf( ui_currentClass, "%d %d", &class, &credits ); 
    1231  
    1232   //offset the text 
    1233   x = rect->x + maxLeft; 
    1234   y = rect->y + maxTop; 
    1235   w = rect->w - ( maxLeft + maxRight + 16 + ( 2 * text_x ) ); //16 to ensure text within frame 
    1236   h = rect->h - ( maxTop + maxBottom ); 
    1237  
    1238   switch( item->type ) 
    1239   { 
    1240     case INFOTYPE_TEXT: 
    1241       textItem.text = item->v.text; 
    1242       break; 
    1243  
    1244     case INFOTYPE_CLASS: 
    1245       value = BG_ClassCanEvolveFromTo( class, item->v.pclass, credits, 0 ); 
    1246       if( value < 1 ) 
    1247       { 
    1248         textItem.text = va( "%s\n\n%s", 
    1249             BG_FindHumanNameForClassNum( item->v.pclass ), 
    1250             BG_FindInfoForClassNum( item->v.pclass ) ); 
    1251       } 
    1252       else 
    1253       { 
    1254         textItem.text = va( "%s\n\n%s\n\nKills: %d", 
    1255             BG_FindHumanNameForClassNum( item->v.pclass ), 
    1256             BG_FindInfoForClassNum( item->v.pclass ), 
    1257             value ); 
    1258       } 
    1259       break; 
    1260  
    1261     case INFOTYPE_WEAPON: 
    1262       value = BG_FindPriceForWeapon( item->v.weapon ); 
    1263       if( value == 0 ) 
    1264       { 
    1265         textItem.text = va( "%s\n\n%s\n\nCredits: Free", 
    1266             BG_FindHumanNameForWeapon( item->v.weapon ), 
    1267             BG_FindInfoForWeapon( item->v.weapon ) ); 
    1268       } 
    1269       else 
    1270       { 
    1271         textItem.text = va( "%s\n\n%s\n\nCredits: %d", 
    1272             BG_FindHumanNameForWeapon( item->v.weapon ), 
    1273             BG_FindInfoForWeapon( item->v.weapon ), 
    1274             value ); 
    1275       } 
    1276       break; 
    1277  
    1278     case INFOTYPE_UPGRADE: 
    1279       value = BG_FindPriceForUpgrade( item->v.upgrade ); 
    1280       if( value == 0 ) 
    1281       { 
    1282         textItem.text = va( "%s\n\n%s\n\nCredits: Free", 
    1283             BG_FindHumanNameForUpgrade( item->v.upgrade ), 
    1284             BG_FindInfoForUpgrade( item->v.upgrade ) ); 
    1285       } 
    1286       else 
    1287       { 
    1288         textItem.text = va( "%s\n\n%s\n\nCredits: %d", 
    1289             BG_FindHumanNameForUpgrade( item->v.upgrade ), 
    1290             BG_FindInfoForUpgrade( item->v.upgrade ), 
    1291             value ); 
    1292       } 
    1293       break; 
    1294  
    1295     case INFOTYPE_BUILDABLE: 
    1296       value = BG_FindBuildPointsForBuildable( item->v.buildable ); 
    1297       switch( BG_FindTeamForBuildable( item->v.buildable ) ) 
    1298       { 
    1299         case BIT_ALIENS: string = "Sentience"; break; 
    1300         case BIT_HUMANS: string = "Power"; break; 
    1301         default: break; 
    1302       } 
    1303  
    1304       if( value == 0 ) 
    1305       { 
    1306         textItem.text = va( "%s\n\n%s", 
    1307             BG_FindHumanNameForBuildable( item->v.buildable ), 
    1308             BG_FindInfoForBuildable( item->v.buildable ) ); 
    1309       } 
    1310       else 
    1311       { 
    1312         textItem.text = va( "%s\n\n%s\n\n%s: %d", 
    1313             BG_FindHumanNameForBuildable( item->v.buildable ), 
    1314             BG_FindInfoForBuildable( item->v.buildable ), 
    1315             string, value ); 
    1316       } 
    1317       break; 
    1318   } 
    1319  
    1320   textItem.parent = &dummyParent; 
    1321   memcpy( textItem.window.foreColor, color, sizeof( vec4_t ) ); 
    1322   textItem.window.flags = 0; 
    1323  
    1324   textItem.window.rect.x = x; 
    1325   textItem.window.rect.y = y; 
    1326   textItem.window.rect.w = w; 
    1327   textItem.window.rect.h = h; 
    1328   textItem.window.borderSize = 0; 
    1329   textItem.textRect.x = 0; 
    1330   textItem.textRect.y = 0; 
    1331   textItem.textRect.w = 0; 
    1332   textItem.textRect.h = 0; 
    1333   textItem.textalignment = ITEM_ALIGN_LEFT; 
    1334   textItem.textalignx = text_x; 
    1335   textItem.textaligny = text_y; 
    1336   textItem.textscale = scale; 
    1337   textItem.textStyle = textStyle; 
    1338  
    1339   textItem.enableCvar = NULL; 
    1340   textItem.cvarTest = NULL; 
    1341  
    1342   //hack to utilise existing autowrap code 
    1343   Item_Text_AutoWrapped_Paint( &textItem ); 
    1344 } 
    1345  
    1346  
    1347 static void UI_DrawSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1348   int i; 
    1349   i = trap_Cvar_VariableValue( "g_spSkill" ); 
    1350   if (i < 1 || i > numSkillLevels) { 
    1351     i = 1; 
    1352   } 
    1353   Text_Paint(rect->x, rect->y, scale, color, skillLevels[i-1],0, 0, textStyle); 
    1354 } 
    1355  
    1356  
    1357 static void UI_DrawTeamName(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int textStyle) { 
    1358   int i; 
    1359   i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam")); 
    1360   if (i >= 0 && i < uiInfo.teamCount) { 
    1361     Text_Paint(rect->x, rect->y, scale, color, va("%s: %s", (blue) ? "Blue" : "Red", uiInfo.teamList[i].teamName),0, 0, textStyle); 
    1362   } 
    1363 } 
    1364  
    1365 static void UI_DrawTeamMember(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int num, int textStyle) { 
    1366   // 0 - None 
    1367   // 1 - Human 
    1368   // 2..NumCharacters - Bot 
    1369   int value = trap_Cvar_VariableValue(va(blue ? "ui_blueteam%i" : "ui_redteam%i", num)); 
    1370   const char *text; 
    1371   if (value <= 0) { 
    1372     text = "Closed"; 
    1373   } else if (value == 1) { 
    1374     text = "Human"; 
    1375   } else { 
    1376     value -= 2; 
    1377  
    1378     if( value >= UI_GetNumBots( ) ) 
    1379       value = 0; 
    1380  
    1381     text = UI_GetBotNameByNumber(value); 
    1382   } 
    1383   Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); 
    1384 } 
    1385  
    1386 static void UI_DrawMapPreview(rectDef_t *rect, float scale, vec4_t color, qboolean net) { 
    1387   int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; 
    1388   if (map < 0 || map > uiInfo.mapCount) { 
    1389     if (net) { 
    1390       ui_currentNetMap.integer = 0; 
    1391       trap_Cvar_Set("ui_currentNetMap", "0"); 
    1392     } else { 
    1393       ui_currentMap.integer = 0; 
    1394       trap_Cvar_Set("ui_currentMap", "0"); 
    1395     } 
    1396     map = 0; 
    1397   } 
    1398  
    1399   if (uiInfo.mapList[map].levelShot == -1) { 
    1400     uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[map].imageName); 
    1401   } 
    1402  
    1403   if (uiInfo.mapList[map].levelShot > 0) { 
    1404     UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.mapList[map].levelShot); 
    1405   } else { 
    1406     UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen")); 
    1407   } 
    1408 } 
    1409  
    1410  
    1411 static void UI_DrawMapTimeToBeat(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1412   int minutes, seconds, time; 
    1413   if (ui_currentMap.integer < 0 || ui_currentMap.integer > uiInfo.mapCount) { 
    1414     ui_currentMap.integer = 0; 
    1415     trap_Cvar_Set("ui_currentMap", "0"); 
    1416   } 
    1417  
    1418   time = uiInfo.mapList[ui_currentMap.integer].timeToBeat[uiInfo.gameTypes[ui_gameType.integer].gtEnum]; 
    1419  
    1420   minutes = time / 60; 
    1421   seconds = time % 60; 
    1422  
    1423   Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, textStyle); 
    1424 } 
    1425  
    1426  
    1427  
    1428 static void UI_DrawMapCinematic(rectDef_t *rect, float scale, vec4_t color, qboolean net) { 
    1429  
    1430   int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; 
    1431   if (map < 0 || map > uiInfo.mapCount) { 
    1432     if (net) { 
    1433       ui_currentNetMap.integer = 0; 
    1434       trap_Cvar_Set("ui_currentNetMap", "0"); 
    1435     } else { 
    1436       ui_currentMap.integer = 0; 
    1437       trap_Cvar_Set("ui_currentMap", "0"); 
    1438     } 
    1439     map = 0; 
    1440   } 
    1441  
    1442   if (uiInfo.mapList[map].cinematic >= -1) { 
    1443     if (uiInfo.mapList[map].cinematic == -1) { 
    1444       uiInfo.mapList[map].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[map].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); 
    1445     } 
    1446     if (uiInfo.mapList[map].cinematic >= 0) { 
    1447       trap_CIN_RunCinematic(uiInfo.mapList[map].cinematic); 
    1448       trap_CIN_SetExtents(uiInfo.mapList[map].cinematic, rect->x, rect->y, rect->w, rect->h); 
    1449       trap_CIN_DrawCinematic(uiInfo.mapList[map].cinematic); 
    1450     } else { 
    1451       uiInfo.mapList[map].cinematic = -2; 
    1452     } 
    1453   } else { 
    1454     UI_DrawMapPreview(rect, scale, color, net); 
    1455   } 
    1456 } 
    1457  
    1458  
    1459  
    1460 static qboolean updateModel = qtrue; 
    1461 static qboolean q3Model = qfalse; 
    1462  
    1463 static void UI_DrawPlayerModel(rectDef_t *rect) { 
    1464   static playerInfo_t info; 
    1465   char model[MAX_QPATH]; 
    1466   char team[256]; 
    1467   char head[256]; 
    1468   vec3_t  viewangles; 
    1469   vec3_t  moveangles; 
    1470  
    1471     if (trap_Cvar_VariableValue("ui_Q3Model")) { 
    1472     strcpy(model, UI_Cvar_VariableString("model")); 
    1473     strcpy(head, UI_Cvar_VariableString("headmodel")); 
    1474     if (!q3Model) { 
    1475       q3Model = qtrue; 
    1476       updateModel = qtrue; 
    1477     } 
    1478     team[0] = '\0'; 
    1479   } else { 
    1480  
    1481     strcpy(team, UI_Cvar_VariableString("ui_teamName")); 
    1482     strcpy(model, UI_Cvar_VariableString("team_model")); 
    1483     strcpy(head, UI_Cvar_VariableString("team_headmodel")); 
    1484     if (q3Model) { 
    1485       q3Model = qfalse; 
    1486       updateModel = qtrue; 
    1487     } 
    1488   } 
    1489   if (updateModel) { 
    1490     memset( &info, 0, sizeof(playerInfo_t) ); 
    1491     viewangles[YAW]   = 180 - 10; 
    1492     viewangles[PITCH] = 0; 
    1493     viewangles[ROLL]  = 0; 
    1494     VectorClear( moveangles ); 
    1495     UI_PlayerInfo_SetModel( &info, model, head, team); 
    1496     UI_PlayerInfo_SetInfo( &info, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); 
    1497 //    UI_RegisterClientModelname( &info, model, head, team); 
    1498     updateModel = qfalse; 
    1499   } 
    1500  
    1501   UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info, uiInfo.uiDC.realTime / 2); 
    1502  
    1503 } 
    1504  
    1505 static void UI_DrawNetSource(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1506   if (ui_netSource.integer < 0 || ui_netSource.integer > numNetSources) { 
    1507     ui_netSource.integer = 0; 
    1508   } 
    1509   Text_Paint(rect->x, rect->y, scale, color, va("Source: %s", netSources[ui_netSource.integer]), 0, 0, textStyle); 
    1510 } 
    1511  
    1512 static void UI_DrawNetMapPreview(rectDef_t *rect, float scale, vec4_t color) { 
    1513  
    1514   if (uiInfo.serverStatus.currentServerPreview > 0) { 
    1515     UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.serverStatus.currentServerPreview); 
    1516   } else { 
    1517     UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen")); 
    1518   } 
    1519 } 
    1520  
    1521 static void UI_DrawNetMapCinematic(rectDef_t *rect, float scale, vec4_t color) { 
    1522   if (ui_currentNetMap.integer < 0 || ui_currentNetMap.integer > uiInfo.mapCount) { 
    1523     ui_currentNetMap.integer = 0; 
    1524     trap_Cvar_Set("ui_currentNetMap", "0"); 
    1525   } 
    1526  
    1527   if (uiInfo.serverStatus.currentServerCinematic >= 0) { 
    1528     trap_CIN_RunCinematic(uiInfo.serverStatus.currentServerCinematic); 
    1529     trap_CIN_SetExtents(uiInfo.serverStatus.currentServerCinematic, rect->x, rect->y, rect->w, rect->h); 
    1530     trap_CIN_DrawCinematic(uiInfo.serverStatus.currentServerCinematic); 
    1531   } else { 
    1532     UI_DrawNetMapPreview(rect, scale, color); 
    1533   } 
    1534 } 
    1535  
    1536  
    1537  
    1538 static void UI_DrawNetFilter(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1539   if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) { 
    1540     ui_serverFilterType.integer = 0; 
    1541   } 
    1542   Text_Paint(rect->x, rect->y, scale, color, va("Filter: %s", serverFilters[ui_serverFilterType.integer].description), 0, 0, textStyle); 
    1543 } 
    1544  
    1545  
    1546 static void UI_DrawTier(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1547   int i; 
    1548   i = trap_Cvar_VariableValue( "ui_currentTier" ); 
    1549   if (i < 0 || i >= uiInfo.tierCount) { 
    1550     i = 0; 
    1551   } 
    1552   Text_Paint(rect->x, rect->y, scale, color, va("Tier: %s", uiInfo.tierList[i].tierName),0, 0, textStyle); 
    1553 } 
    1554  
    1555 static void UI_DrawTierMap(rectDef_t *rect, int index) { 
    1556   int i; 
    1557   i = trap_Cvar_VariableValue( "ui_currentTier" ); 
    1558   if (i < 0 || i >= uiInfo.tierCount) { 
    1559     i = 0; 
    1560   } 
    1561  
    1562   if (uiInfo.tierList[i].mapHandles[index] == -1) { 
    1563     uiInfo.tierList[i].mapHandles[index] = trap_R_RegisterShaderNoMip(va("levelshots/%s", uiInfo.tierList[i].maps[index])); 
    1564   } 
    1565  
    1566   UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.tierList[i].mapHandles[index]); 
    1567 } 
    1568  
    1569 static const char *UI_EnglishMapName(const char *map) { 
    1570   int i; 
    1571   for (i = 0; i < uiInfo.mapCount; i++) { 
    1572     if (Q_stricmp(map, uiInfo.mapList[i].mapLoadName) == 0) { 
    1573       return uiInfo.mapList[i].mapName; 
    1574     } 
    1575   } 
    1576   return ""; 
    1577 } 
    1578  
    1579 static void UI_DrawTierMapName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1580   int i, j; 
    1581   i = trap_Cvar_VariableValue( "ui_currentTier" ); 
    1582   if (i < 0 || i >= uiInfo.tierCount) { 
    1583     i = 0; 
    1584   } 
    1585   j = trap_Cvar_VariableValue("ui_currentMap"); 
    1586   if (j < 0 || j > MAPS_PER_TIER) { 
    1587     j = 0; 
    1588   } 
    1589  
    1590   Text_Paint(rect->x, rect->y, scale, color, UI_EnglishMapName(uiInfo.tierList[i].maps[j]), 0, 0, textStyle); 
    1591 } 
    1592  
    1593 static void UI_DrawTierGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1594   int i, j; 
    1595   i = trap_Cvar_VariableValue( "ui_currentTier" ); 
    1596   if (i < 0 || i >= uiInfo.tierCount) { 
    1597     i = 0; 
    1598   } 
    1599   j = trap_Cvar_VariableValue("ui_currentMap"); 
    1600   if (j < 0 || j > MAPS_PER_TIER) { 
    1601     j = 0; 
    1602   } 
    1603  
    1604   Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[uiInfo.tierList[i].gameTypes[j]].gameType , 0, 0, textStyle); 
    1605 } 
    1606  
    1607  
    1608 static const char *UI_AIFromName(const char *name) { 
    1609   int j; 
    1610   for (j = 0; j < uiInfo.aliasCount; j++) { 
    1611     if (Q_stricmp(uiInfo.aliasList[j].name, name) == 0) { 
    1612       return uiInfo.aliasList[j].ai; 
    1613     } 
    1614   } 
    1615   return "James"; 
    1616 } 
    1617  
    1618 static qboolean updateOpponentModel = qtrue; 
    1619 static void UI_DrawOpponent(rectDef_t *rect) { 
    1620   static playerInfo_t info2; 
    1621   char model[MAX_QPATH]; 
    1622   char headmodel[MAX_QPATH]; 
    1623   char team[256]; 
    1624   vec3_t  viewangles; 
    1625   vec3_t  moveangles; 
    1626  
    1627   if (updateOpponentModel) { 
    1628  
    1629     strcpy(model, UI_Cvar_VariableString("ui_opponentModel")); 
    1630     strcpy(headmodel, UI_Cvar_VariableString("ui_opponentModel")); 
    1631     team[0] = '\0'; 
    1632  
    1633     memset( &info2, 0, sizeof(playerInfo_t) ); 
    1634     viewangles[YAW]   = 180 - 10; 
    1635     viewangles[PITCH] = 0; 
    1636     viewangles[ROLL]  = 0; 
    1637     VectorClear( moveangles ); 
    1638     UI_PlayerInfo_SetModel( &info2, model, headmodel, ""); 
    1639     UI_PlayerInfo_SetInfo( &info2, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); 
    1640     UI_RegisterClientModelname( &info2, model, headmodel, team); 
    1641     updateOpponentModel = qfalse; 
    1642   } 
    1643  
    1644   UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info2, uiInfo.uiDC.realTime / 2); 
    1645  
    1646 } 
    1647  
    1648 static void UI_NextOpponent( void ) { 
    1649   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); 
    1650   int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    1651   i++; 
    1652   if (i >= uiInfo.teamCount) { 
    1653     i = 0; 
    1654   } 
    1655   if (i == j) { 
    1656     i++; 
    1657     if ( i >= uiInfo.teamCount) { 
    1658       i = 0; 
    1659     } 
    1660   } 
    1661   trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName ); 
    1662 } 
    1663  
    1664 static void UI_PriorOpponent( void ) { 
    1665   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); 
    1666   int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    1667   i--; 
    1668   if (i < 0) { 
    1669     i = uiInfo.teamCount - 1; 
    1670   } 
    1671   if (i == j) { 
    1672     i--; 
    1673     if ( i < 0) { 
    1674       i = uiInfo.teamCount - 1; 
    1675     } 
    1676   } 
    1677   trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName ); 
    1678 } 
    1679  
    1680 static void UI_DrawPlayerLogo(rectDef_t *rect, vec3_t color) { 
    1681   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    1682  
    1683   if (uiInfo.teamList[i].teamIcon == -1) { 
    1684     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); 
    1685     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); 
    1686     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); 
    1687   } 
    1688  
    1689   trap_R_SetColor( color ); 
    1690   UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon ); 
    1691   trap_R_SetColor( NULL ); 
    1692 } 
    1693  
    1694 static void UI_DrawPlayerLogoMetal(rectDef_t *rect, vec3_t color) { 
    1695   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    1696   if (uiInfo.teamList[i].teamIcon == -1) { 
    1697     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); 
    1698     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); 
    1699     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); 
    1700   } 
    1701  
    1702   trap_R_SetColor( color ); 
    1703   UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal ); 
    1704   trap_R_SetColor( NULL ); 
    1705 } 
    1706  
    1707 static void UI_DrawPlayerLogoName(rectDef_t *rect, vec3_t color) { 
    1708   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    1709   if (uiInfo.teamList[i].teamIcon == -1) { 
    1710     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); 
    1711     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); 
    1712     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); 
    1713   } 
    1714  
    1715   trap_R_SetColor( color ); 
    1716   UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name ); 
    1717   trap_R_SetColor( NULL ); 
    1718 } 
    1719  
    1720 static void UI_DrawOpponentLogo(rectDef_t *rect, vec3_t color) { 
    1721   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); 
    1722   if (uiInfo.teamList[i].teamIcon == -1) { 
    1723     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); 
    1724     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); 
    1725     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); 
    1726   } 
    1727  
    1728   trap_R_SetColor( color ); 
    1729   UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon ); 
    1730   trap_R_SetColor( NULL ); 
    1731 } 
    1732  
    1733 static void UI_DrawOpponentLogoMetal(rectDef_t *rect, vec3_t color) { 
    1734   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); 
    1735   if (uiInfo.teamList[i].teamIcon == -1) { 
    1736     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); 
    1737     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); 
    1738     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); 
    1739   } 
    1740  
    1741   trap_R_SetColor( color ); 
    1742   UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal ); 
    1743   trap_R_SetColor( NULL ); 
    1744 } 
    1745  
    1746 static void UI_DrawOpponentLogoName(rectDef_t *rect, vec3_t color) { 
    1747   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); 
    1748   if (uiInfo.teamList[i].teamIcon == -1) { 
    1749     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName); 
    1750     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName)); 
    1751     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName)); 
    1752   } 
    1753  
    1754   trap_R_SetColor( color ); 
    1755   UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name ); 
    1756   trap_R_SetColor( NULL ); 
    1757 } 
    1758  
    1759 static void UI_DrawAllMapsSelection(rectDef_t *rect, float scale, vec4_t color, int textStyle, qboolean net) { 
    1760   int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; 
    1761   if (map >= 0 && map < uiInfo.mapCount) { 
    1762     Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle); 
    1763   } 
    1764 } 
    1765  
    1766 static void UI_DrawPlayerListSelection( rectDef_t *rect, float scale, 
    1767   vec4_t color, int textStyle ) 
    1768 { 
    1769   if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) 
    1770   { 
    1771     Text_Paint(rect->x, rect->y, scale, color, 
    1772       uiInfo.rawPlayerNames[ uiInfo.playerIndex ], 
    1773       0, 0, textStyle); 
    1774   } 
    1775 } 
    1776  
    1777 static void UI_DrawTeamListSelection( rectDef_t *rect, float scale, 
    1778   vec4_t color, int textStyle ) 
    1779 { 
    1780   if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount ) 
    1781   { 
    1782     Text_Paint(rect->x, rect->y, scale, color, 
    1783       uiInfo.rawTeamNames[ uiInfo.teamIndex ], 
    1784       0, 0, textStyle); 
    1785   } 
    1786 } 
    1787  
    1788 static void UI_DrawOpponentName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1789   Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, textStyle); 
    1790 } 
    1791  
    1792  
    1793 static int UI_OwnerDrawWidth(int ownerDraw, float scale) { 
    1794   int i, h, value; 
    1795   const char *text; 
    1796   const char *s = NULL; 
    1797  
    1798   switch( ownerDraw ) 
    1799   { 
    1800     case UI_HANDICAP: 
    1801         h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); 
    1802         i = 20 - h / 5; 
    1803         s = handicapValues[i]; 
    1804       break; 
    1805     case UI_CLANNAME: 
    1806         s = UI_Cvar_VariableString("ui_teamName"); 
    1807       break; 
    1808     case UI_GAMETYPE: 
    1809         s = uiInfo.gameTypes[ui_gameType.integer].gameType; 
    1810       break; 
    1811     case UI_SKILL: 
    1812         i = trap_Cvar_VariableValue( "g_spSkill" ); 
    1813         if (i < 1 || i > numSkillLevels) { 
    1814           i = 1; 
    1815         } 
    1816         s = skillLevels[i-1]; 
    1817       break; 
    1818     case UI_BLUETEAMNAME: 
    1819         i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_blueTeam")); 
    1820         if (i >= 0 && i < uiInfo.teamCount) { 
    1821           s = va("%s: %s", "Blue", uiInfo.teamList[i].teamName); 
    1822         } 
    1823       break; 
    1824     case UI_REDTEAMNAME: 
    1825         i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_redTeam")); 
    1826         if (i >= 0 && i < uiInfo.teamCount) { 
    1827           s = va("%s: %s", "Red", uiInfo.teamList[i].teamName); 
    1828         } 
    1829       break; 
    1830     case UI_BLUETEAM1: 
    1831     case UI_BLUETEAM2: 
    1832     case UI_BLUETEAM3: 
    1833     case UI_BLUETEAM4: 
    1834     case UI_BLUETEAM5: 
    1835       value = trap_Cvar_VariableValue(va("ui_blueteam%i", ownerDraw-UI_BLUETEAM1 + 1)); 
    1836       if (value <= 0) { 
    1837         text = "Closed"; 
    1838       } else if (value == 1) { 
    1839         text = "Human"; 
    1840       } else { 
    1841         value -= 2; 
    1842         if (value >= uiInfo.aliasCount) { 
    1843           value = 0; 
    1844         } 
    1845         text = uiInfo.aliasList[value].name; 
    1846       } 
    1847       s = va("%i. %s", ownerDraw-UI_BLUETEAM1 + 1, text); 
    1848       break; 
    1849     case UI_REDTEAM1: 
    1850     case UI_REDTEAM2: 
    1851     case UI_REDTEAM3: 
    1852     case UI_REDTEAM4: 
    1853     case UI_REDTEAM5: 
    1854       value = trap_Cvar_VariableValue(va("ui_redteam%i", ownerDraw-UI_REDTEAM1 + 1)); 
    1855       if (value <= 0) { 
    1856         text = "Closed"; 
    1857       } else if (value == 1) { 
    1858         text = "Human"; 
    1859       } else { 
    1860         value -= 2; 
    1861         if (value >= uiInfo.aliasCount) { 
    1862           value = 0; 
    1863         } 
    1864         text = uiInfo.aliasList[value].name; 
    1865       } 
    1866       s = va("%i. %s", ownerDraw-UI_REDTEAM1 + 1, text); 
    1867       break; 
    1868     case UI_NETSOURCE: 
    1869       if (ui_netSource.integer < 0 || ui_netSource.integer > uiInfo.numJoinGameTypes) { 
    1870         ui_netSource.integer = 0; 
    1871       } 
    1872       s = va("Source: %s", netSources[ui_netSource.integer]); 
    1873       break; 
    1874     case UI_NETFILTER: 
    1875       if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) { 
    1876         ui_serverFilterType.integer = 0; 
    1877       } 
    1878       s = va("Filter: %s", serverFilters[ui_serverFilterType.integer].description ); 
    1879       break; 
    1880     case UI_TIER: 
    1881       break; 
    1882     case UI_TIER_MAPNAME: 
    1883       break; 
    1884     case UI_TIER_GAMETYPE: 
    1885       break; 
    1886     case UI_ALLMAPS_SELECTION: 
    1887       break; 
    1888     case UI_PLAYERLIST_SELECTION: 
    1889       break; 
    1890     case UI_TEAMLIST_SELECTION: 
    1891       break; 
    1892     case UI_OPPONENT_NAME: 
    1893       break; 
    1894     case UI_KEYBINDSTATUS: 
    1895       if (Display_KeyBindPending()) { 
    1896         s = "Waiting for new key... Press ESCAPE to cancel"; 
    1897       } else { 
    1898         s = "Press ENTER or CLICK to change, Press BACKSPACE to clear"; 
    1899       } 
    1900       break; 
    1901     case UI_SERVERREFRESHDATE: 
    1902       s = UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)); 
    1903       break; 
    1904     default: 
    1905       break; 
    1906   } 
    1907  
    1908   if (s) { 
    1909     return Text_Width(s, scale, 0); 
    1910   } 
    1911   return 0; 
    1912 } 
    1913  
    1914 static void UI_DrawBotName(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1915   int value = uiInfo.botIndex; 
    1916   const char *text = ""; 
    1917  
    1918   if( value >= UI_GetNumBots( ) ) 
    1919     value = 0; 
    1920  
    1921   text = UI_GetBotNameByNumber( value ); 
    1922  
    1923   Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); 
    1924 } 
    1925  
    1926 static void UI_DrawBotSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1927   if (uiInfo.skillIndex >= 0 && uiInfo.skillIndex < numSkillLevels) { 
    1928     Text_Paint(rect->x, rect->y, scale, color, skillLevels[uiInfo.skillIndex], 0, 0, textStyle); 
    1929   } 
    1930 } 
    1931  
    1932 static void UI_DrawRedBlue(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    1933   Text_Paint(rect->x, rect->y, scale, color, (uiInfo.redBlue == 0) ? "Red" : "Blue", 0, 0, textStyle); 
    1934 } 
    1935  
    1936 /* 
    1937 =============== 
    1938 UI_BuildPlayerList 
    1939 =============== 
    1940 */ 
    1941 static void UI_BuildPlayerList( void ) { 
    1942   uiClientState_t cs; 
    1943   int   n, count, team, team2, playerTeamNumber; 
    1944   char  info[MAX_INFO_STRING]; 
    1945  
    1946   trap_GetClientState( &cs ); 
    1947   trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); 
    1948   uiInfo.playerNumber = cs.clientNum; 
    1949   uiInfo.teamLeader = atoi(Info_ValueForKey(info, "tl")); 
    1950   team = atoi(Info_ValueForKey(info, "t")); 
    1951   trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); 
    1952   count = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); 
    1953   uiInfo.playerCount = 0; 
    1954   uiInfo.myTeamCount = 0; 
    1955   uiInfo.myPlayerIndex = 0; 
    1956   playerTeamNumber = 0; 
    1957   for( n = 0; n < count; n++ ) { 
    1958     trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); 
    1959  
    1960     if (info[0]) { 
    1961       BG_ClientListParse( &uiInfo.ignoreList[ uiInfo.playerCount ], 
    1962         Info_ValueForKey( info, "ig" ) ); 
    1963       Q_strncpyz( uiInfo.rawPlayerNames[uiInfo.playerCount], 
    1964         Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
    1965       Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], 
    1966         Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
    1967       Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] ); 
    1968       uiInfo.clientNums[uiInfo.playerCount] = n; 
    1969       if( n == uiInfo.playerNumber ) 
    1970         uiInfo.myPlayerIndex = uiInfo.playerCount; 
    1971       uiInfo.playerCount++; 
    1972       team2 = atoi(Info_ValueForKey(info, "t")); 
    1973       if (team2 == team) { 
    1974         Q_strncpyz( uiInfo.rawTeamNames[uiInfo.myTeamCount], 
    1975           Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
    1976         Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount], 
    1977           Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
    1978         Q_CleanStr( uiInfo.teamNames[uiInfo.myTeamCount] ); 
    1979         uiInfo.teamClientNums[uiInfo.myTeamCount] = n; 
    1980         if (uiInfo.playerNumber == n) { 
    1981           playerTeamNumber = uiInfo.myTeamCount; 
    1982         } 
    1983         uiInfo.myTeamCount++; 
    1984       } 
    1985     } 
    1986   } 
    1987  
    1988   if (!uiInfo.teamLeader) { 
    1989     trap_Cvar_Set("cg_selectedPlayer", va("%d", playerTeamNumber)); 
    1990   } 
    1991  
    1992   n = trap_Cvar_VariableValue("cg_selectedPlayer"); 
    1993   if (n < 0 || n > uiInfo.myTeamCount) { 
    1994     n = 0; 
    1995   } 
    1996   if (n < uiInfo.myTeamCount) { 
    1997     trap_Cvar_Set("cg_selectedPlayerName", uiInfo.teamNames[n]); 
    1998   } 
    1999 } 
    2000  
    2001  
    2002 static void UI_DrawSelectedPlayer(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    2003   char name[ MAX_NAME_LENGTH ]; 
    2004   char *s; 
    2005  
    2006   if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) { 
    2007     uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000; 
    2008     UI_BuildPlayerList(); 
    2009   } 
    2010   if( uiInfo.teamLeader ) 
    2011     s = UI_Cvar_VariableString("cg_selectedPlayerName"); 
    2012   else 
    2013     s = UI_Cvar_VariableString("name"); 
    2014   Q_strncpyz( name, s, sizeof( name ) ); 
    2015   Text_Paint(rect->x, rect->y, scale, color, name, 0, 0, textStyle); 
    2016 } 
    2017  
    2018 static void UI_DrawServerRefreshDate(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    2019   if (uiInfo.serverStatus.refreshActive) { 
    2020     vec4_t lowLight, newColor; 
    2021     int numServers = trap_LAN_GetServerCount( ui_netSource.integer ); 
    2022  
    2023     lowLight[0] = 0.8 * color[0]; 
    2024     lowLight[1] = 0.8 * color[1]; 
    2025     lowLight[2] = 0.8 * color[2]; 
    2026     lowLight[3] = 0.8 * color[3]; 
    2027     LerpColor(color,lowLight,newColor,0.5+0.5*sin(uiInfo.uiDC.realTime / PULSE_DIVISOR)); 
    2028     Text_Paint(rect->x, rect->y, scale, newColor, 
    2029         numServers < 0 ? "Waiting for response..." : 
    2030         va("Getting info for %d servers (ESC to cancel)", numServers), 0, 0, textStyle); 
    2031   } else { 
    2032     char buff[64]; 
    2033     Q_strncpyz(buff, UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)), 64); 
    2034     Text_Paint(rect->x, rect->y, scale, color, va("Refresh Time: %s", buff), 0, 0, textStyle); 
    2035   } 
    2036 } 
    2037  
    2038 static void UI_DrawServerMOTD(rectDef_t *rect, float scale, vec4_t color) { 
    2039   if (uiInfo.serverStatus.motdLen) { 
    2040     float maxX; 
    2041  
    2042     if (uiInfo.serverStatus.motdWidth == -1) { 
    2043       uiInfo.serverStatus.motdWidth = 0; 
    2044       uiInfo.serverStatus.motdPaintX = rect->x + 1; 
    2045       uiInfo.serverStatus.motdPaintX2 = -1; 
    2046     } 
    2047  
    2048     if (uiInfo.serverStatus.motdOffset > uiInfo.serverStatus.motdLen) { 
    2049       uiInfo.serverStatus.motdOffset = 0; 
    2050       uiInfo.serverStatus.motdPaintX = rect->x + 1; 
    2051       uiInfo.serverStatus.motdPaintX2 = -1; 
    2052     } 
    2053  
    2054     if (uiInfo.uiDC.realTime > uiInfo.serverStatus.motdTime) { 
    2055       uiInfo.serverStatus.motdTime = uiInfo.uiDC.realTime + 10; 
    2056       if (uiInfo.serverStatus.motdPaintX <= rect->x + 2) { 
    2057         if (uiInfo.serverStatus.motdOffset < uiInfo.serverStatus.motdLen) { 
    2058           uiInfo.serverStatus.motdPaintX += Text_Width(&uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], scale, 1) - 1; 
    2059           uiInfo.serverStatus.motdOffset++; 
    2060         } else { 
    2061           uiInfo.serverStatus.motdOffset = 0; 
    2062           if (uiInfo.serverStatus.motdPaintX2 >= 0) { 
    2063             uiInfo.serverStatus.motdPaintX = uiInfo.serverStatus.motdPaintX2; 
    2064           } else { 
    2065             uiInfo.serverStatus.motdPaintX = rect->x + rect->w - 2; 
    2066           } 
    2067           uiInfo.serverStatus.motdPaintX2 = -1; 
    2068         } 
    2069       } else { 
    2070         //serverStatus.motdPaintX--; 
    2071         uiInfo.serverStatus.motdPaintX -= 2; 
    2072         if (uiInfo.serverStatus.motdPaintX2 >= 0) { 
    2073           //serverStatus.motdPaintX2--; 
    2074           uiInfo.serverStatus.motdPaintX2 -= 2; 
    2075         } 
    2076       } 
    2077     } 
    2078  
    2079     maxX = rect->x + rect->w - 2; 
    2080     Text_Paint_Limit(&maxX, uiInfo.serverStatus.motdPaintX, rect->y + rect->h - 3, scale, color, &uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], 0, 0); 
    2081     if (uiInfo.serverStatus.motdPaintX2 >= 0) { 
    2082       float maxX2 = rect->x + rect->w - 2; 
    2083       Text_Paint_Limit(&maxX2, uiInfo.serverStatus.motdPaintX2, rect->y + rect->h - 3, scale, color, uiInfo.serverStatus.motd, 0, uiInfo.serverStatus.motdOffset); 
    2084     } 
    2085     if (uiInfo.serverStatus.motdOffset && maxX > 0) { 
    2086       // if we have an offset ( we are skipping the first part of the string ) and we fit the string 
    2087       if (uiInfo.serverStatus.motdPaintX2 == -1) { 
    2088             uiInfo.serverStatus.motdPaintX2 = rect->x + rect->w - 2; 
    2089       } 
    2090     } else { 
    2091       uiInfo.serverStatus.motdPaintX2 = -1; 
    2092     } 
    2093  
    2094   } 
    2095 } 
    2096  
    2097 static void UI_DrawKeyBindStatus(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    2098   if (Display_KeyBindPending()) { 
    2099     Text_Paint(rect->x, rect->y, scale, color, "Waiting for new key... Press ESCAPE to cancel", 0, 0, textStyle); 
    2100   } else { 
    2101     Text_Paint(rect->x, rect->y, scale, color, "Press ENTER or CLICK to change, Press BACKSPACE to clear", 0, 0, textStyle); 
    2102   } 
    2103 } 
    2104  
    2105 static void UI_DrawGLInfo(rectDef_t *rect, float scale, vec4_t color, int textStyle) { 
    2106   char * eptr; 
    2107   char buff[1024]; 
    2108   const char *lines[64]; 
    2109   int y, numLines, i; 
    2110  
    2111   Text_Paint(rect->x + 2, rect->y, scale, color, va("VENDOR: %s", uiInfo.uiDC.glconfig.vendor_string), 0, 30, textStyle); 
    2112   Text_Paint(rect->x + 2, rect->y + 15, scale, color, va("VERSION: %s: %s", uiInfo.uiDC.glconfig.version_string,uiInfo.uiDC.glconfig.renderer_string), 0, 30, textStyle); 
    2113   Text_Paint(rect->x + 2, rect->y + 30, scale, color, va ("PIXELFORMAT: color(%d-bits) Z(%d-bits) stencil(%d-bits)", uiInfo.uiDC.glconfig.colorBits, uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits), 0, 30, textStyle); 
    2114  
    2115   // build null terminated extension strings 
    2116   // in TA this was not directly crashing, but displaying a nasty broken shader right in the middle 
    2117   // brought down the string size to 1024, there's not much that can be shown on the screen anyway 
    2118   Q_strncpyz(buff, uiInfo.uiDC.glconfig.extensions_string, 1024); 
    2119   eptr = buff; 
    2120   y = rect->y + 45; 
    2121   numLines = 0; 
    2122   while ( y < rect->y + rect->h && *eptr ) 
    2123   { 
    2124     while ( *eptr && *eptr == ' ' ) 
    2125       *eptr++ = '\0'; 
    2126  
    2127     // track start of valid string 
    2128     if (*eptr && *eptr != ' ') { 
    2129       lines[numLines++] = eptr; 
    2130     } 
    2131  
    2132     while ( *eptr && *eptr != ' ' ) 
    2133       eptr++; 
    2134   } 
    2135  
    2136   i = 0; 
    2137   while (i < numLines) { 
    2138     Text_Paint(rect->x + 2, y, scale, color, lines[i++], 0, 20, textStyle); 
    2139     if (i < numLines) { 
    2140       Text_Paint(rect->x + rect->w / 2, y, scale, color, lines[i++], 0, 20, textStyle); 
    2141     } 
    2142     y += 10; 
    2143     if (y > rect->y + rect->h - 11) { 
    2144       break; 
    2145     } 
    2146   } 
    2147  
    2148  
    2149 } 
    2150  
    2151 // FIXME: table drive 
    2152 // 
    2153 static void UI_OwnerDraw( float x, float y, float w, float h, 
    2154                           float text_x, float text_y, int ownerDraw, 
    2155                           int ownerDrawFlags, int align, float special, 
    2156                           float scale, vec4_t color, qhandle_t shader, int textStyle ) 
    2157 { 
    2158   rectDef_t       rect; 
    2159  
    2160   rect.x = x + text_x; 
    2161   rect.y = y + text_y; 
    2162   rect.w = w; 
    2163   rect.h = h; 
    2164  
    2165   switch( ownerDraw ) 
    2166   { 
    2167     case UI_TEAMINFOPANE: 
    2168         UI_DrawInfoPane( &uiInfo.tremTeamList[ uiInfo.tremTeamIndex ], 
    2169           &rect, text_x, text_y, scale, color, textStyle ); 
    2170       break; 
    2171  
    2172     case UI_ACLASSINFOPANE: 
    2173         UI_DrawInfoPane( &uiInfo.alienClassList[ uiInfo.alienClassIndex ], 
    2174           &rect, text_x, text_y, scale, color, textStyle ); 
    2175       break; 
    2176  
    2177     case UI_AUPGRADEINFOPANE: 
    2178         UI_DrawInfoPane( &uiInfo.alienUpgradeList[ uiInfo.alienUpgradeIndex ], 
    2179           &rect, text_x, text_y, scale, color, textStyle ); 
    2180       break; 
    2181  
    2182     case UI_HITEMINFOPANE: 
    2183         UI_DrawInfoPane( &uiInfo.humanItemList[ uiInfo.humanItemIndex ], 
    2184           &rect, text_x, text_y, scale, color, textStyle ); 
    2185       break; 
    2186  
    2187     case UI_HBUYINFOPANE: 
    2188         UI_DrawInfoPane( &uiInfo.humanArmouryBuyList[ uiInfo.humanArmouryBuyIndex ], 
    2189           &rect, text_x, text_y, scale, color, textStyle ); 
    2190       break; 
    2191  
    2192     case UI_HSELLINFOPANE: 
    2193         UI_DrawInfoPane( &uiInfo.humanArmourySellList[ uiInfo.humanArmourySellIndex ], 
    2194           &rect, text_x, text_y, scale, color, textStyle ); 
    2195       break; 
    2196  
    2197     case UI_ABUILDINFOPANE: 
    2198         UI_DrawInfoPane( &uiInfo.alienBuildList[ uiInfo.alienBuildIndex ], 
    2199           &rect, text_x, text_y, scale, color, textStyle ); 
    2200       break; 
    2201  
    2202     case UI_HBUILDINFOPANE: 
    2203         UI_DrawInfoPane( &uiInfo.humanBuildList[ uiInfo.humanBuildIndex ], 
    2204           &rect, text_x, text_y, scale, color, textStyle ); 
    2205       break; 
    2206  
    2207     case UI_HANDICAP: 
    2208       UI_DrawHandicap(&rect, scale, color, textStyle); 
    2209       break; 
    2210     case UI_PLAYERMODEL: 
    2211       UI_DrawPlayerModel(&rect); 
    2212       break; 
    2213     case UI_CLANNAME: 
    2214       UI_DrawClanName(&rect, scale, color, textStyle); 
    2215       break; 
    2216     case UI_CLANLOGO: 
    2217       UI_DrawClanLogo(&rect, scale, color); 
    2218       break; 
    2219     case UI_CLANCINEMATIC: 
    2220       UI_DrawClanCinematic(&rect, scale, color); 
    2221       break; 
    2222     case UI_PREVIEWCINEMATIC: 
    2223       UI_DrawPreviewCinematic(&rect, scale, color); 
    2224       break; 
    2225     case UI_GAMETYPE: 
    2226       UI_DrawGameType(&rect, scale, color, textStyle); 
    2227       break; 
    2228     case UI_NETGAMETYPE: 
    2229       UI_DrawNetGameType(&rect, scale, color, textStyle); 
    2230       break; 
    2231     case UI_JOINGAMETYPE: 
    2232     UI_DrawJoinGameType(&rect, scale, color, textStyle); 
    2233     break; 
    2234     case UI_MAPPREVIEW: 
    2235       UI_DrawMapPreview(&rect, scale, color, qtrue); 
    2236       break; 
    2237     case UI_MAP_TIMETOBEAT: 
    2238       UI_DrawMapTimeToBeat(&rect, scale, color, textStyle); 
    2239       break; 
    2240     case UI_MAPCINEMATIC: 
    2241       UI_DrawMapCinematic(&rect, scale, color, qfalse); 
    2242       break; 
    2243     case UI_STARTMAPCINEMATIC: 
    2244       UI_DrawMapCinematic(&rect, scale, color, qtrue); 
    2245       break; 
    2246     case UI_SKILL: 
    2247       UI_DrawSkill(&rect, scale, color, textStyle); 
    2248       break; 
    2249     case UI_BLUETEAMNAME: 
    2250       UI_DrawTeamName(&rect, scale, color, qtrue, textStyle); 
    2251       break; 
    2252     case UI_REDTEAMNAME: 
    2253       UI_DrawTeamName(&rect, scale, color, qfalse, textStyle); 
    2254       break; 
    2255     case UI_BLUETEAM1: 
    2256     case UI_BLUETEAM2: 
    2257     case UI_BLUETEAM3: 
    2258     case UI_BLUETEAM4: 
    2259     case UI_BLUETEAM5: 
    2260       UI_DrawTeamMember(&rect, scale, color, qtrue, ownerDraw - UI_BLUETEAM1 + 1, textStyle); 
    2261       break; 
    2262     case UI_REDTEAM1: 
    2263     case UI_REDTEAM2: 
    2264     case UI_REDTEAM3: 
    2265     case UI_REDTEAM4: 
    2266     case UI_REDTEAM5: 
    2267       UI_DrawTeamMember(&rect, scale, color, qfalse, ownerDraw - UI_REDTEAM1 + 1, textStyle); 
    2268       break; 
    2269     case UI_NETSOURCE: 
    2270       UI_DrawNetSource(&rect, scale, color, textStyle); 
    2271       break; 
    2272     case UI_NETMAPPREVIEW: 
    2273       UI_DrawNetMapPreview(&rect, scale, color); 
    2274       break; 
    2275     case UI_NETMAPCINEMATIC: 
    2276       UI_DrawNetMapCinematic(&rect, scale, color); 
    2277       break; 
    2278     case UI_NETFILTER: 
    2279       UI_DrawNetFilter(&rect, scale, color, textStyle); 
    2280       break; 
    2281     case UI_TIER: 
    2282       UI_DrawTier(&rect, scale, color, textStyle); 
    2283       break; 
    2284     case UI_OPPONENTMODEL: 
    2285       UI_DrawOpponent(&rect); 
    2286       break; 
    2287     case UI_TIERMAP1: 
    2288       UI_DrawTierMap(&rect, 0); 
    2289       break; 
    2290     case UI_TIERMAP2: 
    2291       UI_DrawTierMap(&rect, 1); 
    2292       break; 
    2293     case UI_TIERMAP3: 
    2294       UI_DrawTierMap(&rect, 2); 
    2295       break; 
    2296     case UI_PLAYERLOGO: 
    2297       UI_DrawPlayerLogo(&rect, color); 
    2298       break; 
    2299     case UI_PLAYERLOGO_METAL: 
    2300       UI_DrawPlayerLogoMetal(&rect, color); 
    2301       break; 
    2302     case UI_PLAYERLOGO_NAME: 
    2303       UI_DrawPlayerLogoName(&rect, color); 
    2304       break; 
    2305     case UI_OPPONENTLOGO: 
    2306       UI_DrawOpponentLogo(&rect, color); 
    2307       break; 
    2308     case UI_OPPONENTLOGO_METAL: 
    2309       UI_DrawOpponentLogoMetal(&rect, color); 
    2310       break; 
    2311     case UI_OPPONENTLOGO_NAME: 
    2312       UI_DrawOpponentLogoName(&rect, color); 
    2313       break; 
    2314     case UI_TIER_MAPNAME: 
    2315       UI_DrawTierMapName(&rect, scale, color, textStyle); 
    2316       break; 
    2317     case UI_TIER_GAMETYPE: 
    2318       UI_DrawTierGameType(&rect, scale, color, textStyle); 
    2319       break; 
    2320     case UI_ALLMAPS_SELECTION: 
    2321       UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qtrue); 
    2322       break; 
    2323     case UI_MAPS_SELECTION: 
    2324       UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qfalse); 
    2325       break; 
    2326     case UI_PLAYERLIST_SELECTION: 
    2327       UI_DrawPlayerListSelection(&rect, scale, color, textStyle); 
    2328       break; 
    2329     case UI_TEAMLIST_SELECTION: 
    2330       UI_DrawTeamListSelection(&rect, scale, color, textStyle); 
    2331       break; 
    2332     case UI_OPPONENT_NAME: 
    2333       UI_DrawOpponentName(&rect, scale, color, textStyle); 
    2334       break; 
    2335     case UI_BOTNAME: 
    2336       UI_DrawBotName(&rect, scale, color, textStyle); 
    2337       break; 
    2338     case UI_BOTSKILL: 
    2339       UI_DrawBotSkill(&rect, scale, color, textStyle); 
    2340       break; 
    2341     case UI_REDBLUE: 
    2342       UI_DrawRedBlue(&rect, scale, color, textStyle); 
    2343       break; 
    2344     case UI_SELECTEDPLAYER: 
    2345       UI_DrawSelectedPlayer(&rect, scale, color, textStyle); 
    2346       break; 
    2347     case UI_SERVERREFRESHDATE: 
    2348       UI_DrawServerRefreshDate(&rect, scale, color, textStyle); 
    2349       break; 
    2350     case UI_SERVERMOTD: 
    2351       UI_DrawServerMOTD(&rect, scale, color); 
    2352       break; 
    2353     case UI_GLINFO: 
    2354       UI_DrawGLInfo(&rect,scale, color, textStyle); 
    2355       break; 
    2356     case UI_KEYBINDSTATUS: 
    2357       UI_DrawKeyBindStatus(&rect,scale, color, textStyle); 
    2358       break; 
    2359     default: 
    2360       break; 
    2361   } 
    2362  
    2363 } 
    2364  
    2365 static qboolean UI_OwnerDrawVisible(int flags) { 
    2366   qboolean vis = qtrue; 
    2367   uiClientState_t cs; 
    2368   pTeam_t         team; 
    2369   char            info[ MAX_INFO_STRING ]; 
    2370  
    2371   trap_GetClientState( &cs ); 
    2372   trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); 
    2373   team = atoi( Info_ValueForKey( info, "t" ) ); 
    2374  
    2375  
    2376   while (flags) { 
    2377  
    2378     if( flags & UI_SHOW_NOTSPECTATING ) 
    2379     { 
    2380       if( team == PTE_NONE ) 
    2381         vis = qfalse; 
    2382  
    2383       flags &= ~UI_SHOW_NOTSPECTATING; 
    2384     } 
    2385  
    2386     if( flags & UI_SHOW_VOTEACTIVE ) 
    2387     { 
    2388       if( !trap_Cvar_VariableValue( "ui_voteActive" ) ) 
    2389         vis = qfalse; 
    2390  
    2391       flags &= ~UI_SHOW_VOTEACTIVE; 
    2392     } 
    2393  
    2394     if( flags & UI_SHOW_CANVOTE ) 
    2395     { 
    2396       if( trap_Cvar_VariableValue( "ui_voteActive" ) ) 
    2397         vis = qfalse; 
    2398  
    2399       flags &= ~UI_SHOW_CANVOTE; 
    2400     } 
    2401  
    2402     if( flags & UI_SHOW_TEAMVOTEACTIVE ) 
    2403     { 
    2404       if( team == PTE_ALIENS ) 
    2405       { 
    2406         if( !trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) ) 
    2407           vis = qfalse; 
    2408       } 
    2409       else if( team == PTE_HUMANS ) 
    2410       { 
    2411         if( !trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) ) 
    2412           vis = qfalse; 
    2413       } 
    2414  
    2415       flags &= ~UI_SHOW_TEAMVOTEACTIVE; 
    2416     } 
    2417  
    2418     if( flags & UI_SHOW_CANTEAMVOTE ) 
    2419     { 
    2420       if( team == PTE_ALIENS ) 
    2421       { 
    2422         if( trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) ) 
    2423           vis = qfalse; 
    2424       } 
    2425       else if( team == PTE_HUMANS ) 
    2426       { 
    2427         if( trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) ) 
    2428           vis = qfalse; 
    2429       } 
    2430  
    2431       flags &= ~UI_SHOW_CANTEAMVOTE; 
    2432     } 
    2433  
    2434     if (flags & UI_SHOW_LEADER) { 
    2435       // these need to show when this client can give orders to a player or a group 
    2436       if (!uiInfo.teamLeader) { 
    2437         vis = qfalse; 
    2438       } else { 
    2439         // if showing yourself 
    2440         if (ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber) { 
    2441           vis = qfalse; 
    2442         } 
    2443       } 
    2444       flags &= ~UI_SHOW_LEADER; 
    2445     } 
    2446     if (flags & UI_SHOW_NOTLEADER) { 
    2447       // these need to show when this client is assigning their own status or they are NOT the leader 
    2448       if (uiInfo.teamLeader) { 
    2449         // if not showing yourself 
    2450         if (!(ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber)) { 
    2451           vis = qfalse; 
    2452         } 
    2453         // these need to show when this client can give orders to a player or a group 
    2454       } 
    2455       flags &= ~UI_SHOW_NOTLEADER; 
    2456     } 
    2457     if (flags & UI_SHOW_FAVORITESERVERS) { 
    2458       // this assumes you only put this type of display flag on something showing in the proper context 
    2459       if (ui_netSource.integer != AS_FAVORITES) { 
    2460         vis = qfalse; 
    2461       } 
    2462       flags &= ~UI_SHOW_FAVORITESERVERS; 
    2463     } 
    2464     if (flags & UI_SHOW_NOTFAVORITESERVERS) { 
    2465       // this assumes you only put this type of display flag on something showing in the proper context 
    2466       if (ui_netSource.integer == AS_FAVORITES) { 
    2467         vis = qfalse; 
    2468       } 
    2469       flags &= ~UI_SHOW_NOTFAVORITESERVERS; 
    2470     } 
    2471     if (flags & UI_SHOW_NEWHIGHSCORE) { 
    2472       if (uiInfo.newHighScoreTime < uiInfo.uiDC.realTime) { 
    2473         vis = qfalse; 
    2474       } else { 
    2475         if (uiInfo.soundHighScore) { 
    2476           if (trap_Cvar_VariableValue("sv_killserver") == 0) { 
    2477             // wait on server to go down before playing sound 
    2478             trap_S_StartLocalSound(uiInfo.newHighScoreSound, CHAN_ANNOUNCER); 
    2479             uiInfo.soundHighScore = qfalse; 
    2480           } 
    2481         } 
    2482       } 
    2483       flags &= ~UI_SHOW_NEWHIGHSCORE; 
    2484     } 
    2485     if (flags & UI_SHOW_NEWBESTTIME) { 
    2486       if (uiInfo.newBestTime < uiInfo.uiDC.realTime) { 
    2487         vis = qfalse; 
    2488       } 
    2489       flags &= ~UI_SHOW_NEWBESTTIME; 
    2490     } 
    2491     if (flags & UI_SHOW_DEMOAVAILABLE) { 
    2492       if (!uiInfo.demoAvailable) { 
    2493         vis = qfalse; 
    2494       } 
    2495       flags &= ~UI_SHOW_DEMOAVAILABLE; 
    2496     } else { 
    2497       flags = 0; 
    2498     } 
    2499   } 
    2500   return vis; 
    2501 } 
    2502  
    2503 static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) { 
    2504   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2505     int h; 
    2506     h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); 
    2507     if (key == K_MOUSE2) { 
    2508       h -= 5; 
    2509     } else { 
    2510       h += 5; 
    2511     } 
    2512     if (h > 100) { 
    2513       h = 5; 
    2514     } else if (h < 0) { 
    2515       h = 100; 
    2516     } 
    2517     trap_Cvar_Set( "handicap", va( "%i", h) ); 
    2518     return qtrue; 
    2519   } 
    2520   return qfalse; 
    2521 } 
    2522  
    2523 static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) { 
    2524   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2525     int i; 
    2526     i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    2527     if (uiInfo.teamList[i].cinematic >= 0) { 
    2528       trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic); 
    2529       uiInfo.teamList[i].cinematic = -1; 
    2530     } 
    2531     if (key == K_MOUSE2) { 
    2532       i--; 
    2533     } else { 
    2534       i++; 
    2535     } 
    2536     if (i >= uiInfo.teamCount) { 
    2537       i = 0; 
    2538     } else if (i < 0) { 
    2539       i = uiInfo.teamCount - 1; 
    2540     } 
    2541     trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName); 
    2542   UI_HeadCountByTeam(); 
    2543   UI_FeederSelection(FEEDER_HEADS, 0); 
    2544   updateModel = qtrue; 
    2545     return qtrue; 
    2546   } 
    2547   return qfalse; 
    2548 } 
    2549  
    2550 static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) { 
    2551   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2552     int oldCount = UI_MapCountByGameType(qtrue); 
    2553  
    2554     // hard coded mess here 
    2555     if (key == K_MOUSE2) { 
    2556       ui_gameType.integer--; 
    2557       if (ui_gameType.integer == 2) { 
    2558         ui_gameType.integer = 1; 
    2559       } else if (ui_gameType.integer < 2) { 
    2560         ui_gameType.integer = uiInfo.numGameTypes - 1; 
    2561       } 
    2562     } else { 
    2563       ui_gameType.integer++; 
    2564       if (ui_gameType.integer >= uiInfo.numGameTypes) { 
    2565         ui_gameType.integer = 1; 
    2566       } else if (ui_gameType.integer == 2) { 
    2567         ui_gameType.integer = 3; 
    2568       } 
    2569     } 
    2570  
    2571     trap_Cvar_Set("ui_Q3Model", "0"); 
    2572  
    2573     trap_Cvar_Set("ui_gameType", va("%d", ui_gameType.integer)); 
    2574     UI_SetCapFragLimits(qtrue); 
    2575     UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum); 
    2576     if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) { 
    2577       trap_Cvar_Set( "ui_currentMap", "0"); 
    2578       Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL); 
    2579     } 
    2580     return qtrue; 
    2581   } 
    2582   return qfalse; 
    2583 } 
    2584  
    2585 static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) { 
    2586   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2587  
    2588     if (key == K_MOUSE2) { 
    2589       ui_netGameType.integer--; 
    2590     } else { 
    2591       ui_netGameType.integer++; 
    2592     } 
    2593  
    2594     if (ui_netGameType.integer < 0) { 
    2595       ui_netGameType.integer = uiInfo.numGameTypes - 1; 
    2596     } else if (ui_netGameType.integer >= uiInfo.numGameTypes) { 
    2597       ui_netGameType.integer = 0; 
    2598     } 
    2599  
    2600     trap_Cvar_Set( "ui_netGameType", va("%d", ui_netGameType.integer)); 
    2601     trap_Cvar_Set( "ui_actualnetGameType", va("%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum)); 
    2602     trap_Cvar_Set( "ui_currentNetMap", "0"); 
    2603     UI_MapCountByGameType(qfalse); 
    2604     Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL); 
    2605     return qtrue; 
    2606   } 
    2607   return qfalse; 
    2608 } 
    2609  
    2610 static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) { 
    2611   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2612  
    2613     if (key == K_MOUSE2) { 
    2614       ui_joinGameType.integer--; 
    2615     } else { 
    2616       ui_joinGameType.integer++; 
    2617     } 
    2618  
    2619     if (ui_joinGameType.integer < 0) { 
    2620       ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1; 
    2621     } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) { 
    2622       ui_joinGameType.integer = 0; 
    2623     } 
    2624  
    2625     trap_Cvar_Set( "ui_joinGameType", va("%d", ui_joinGameType.integer)); 
    2626     UI_BuildServerDisplayList(qtrue); 
    2627     return qtrue; 
    2628   } 
    2629   return qfalse; 
    2630 } 
    2631  
    2632  
    2633  
    2634 static qboolean UI_Skill_HandleKey(int flags, float *special, int key) { 
    2635   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2636     int i = trap_Cvar_VariableValue( "g_spSkill" ); 
    2637  
    2638     if (key == K_MOUSE2) { 
    2639       i--; 
    2640     } else { 
    2641       i++; 
    2642     } 
    2643  
    2644     if (i < 1) { 
    2645       i = numSkillLevels; 
    2646     } else if (i > numSkillLevels) { 
    2647       i = 1; 
    2648     } 
    2649  
    2650     trap_Cvar_Set("g_spSkill", va("%i", i)); 
    2651     return qtrue; 
    2652   } 
    2653   return qfalse; 
    2654 } 
    2655  
    2656 static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) { 
    2657   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2658     int i; 
    2659     i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam")); 
    2660  
    2661     if (key == K_MOUSE2) { 
    2662       i--; 
    2663     } else { 
    2664       i++; 
    2665     } 
    2666  
    2667     if (i >= uiInfo.teamCount) { 
    2668       i = 0; 
    2669     } else if (i < 0) { 
    2670       i = uiInfo.teamCount - 1; 
    2671     } 
    2672  
    2673     trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName); 
    2674  
    2675     return qtrue; 
    2676   } 
    2677   return qfalse; 
    2678 } 
    2679  
    2680 static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) { 
    2681   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2682     // 0 - None 
    2683     // 1 - Human 
    2684     // 2..NumCharacters - Bot 
    2685     char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num); 
    2686     int value = trap_Cvar_VariableValue(cvar); 
    2687  
    2688     if (key == K_MOUSE2) { 
    2689       value--; 
    2690     } else { 
    2691       value++; 
    2692     } 
    2693  
    2694     if( value >= UI_GetNumBots( ) + 2 ) 
    2695       value = 0; 
    2696     else if( value < 0 ) 
    2697       value = UI_GetNumBots( ) + 2 - 1; 
    2698  
    2699     trap_Cvar_Set(cvar, va("%i", value)); 
    2700     return qtrue; 
    2701   } 
    2702   return qfalse; 
    2703 } 
    2704  
    2705 static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) { 
    2706   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2707  
    2708     if (key == K_MOUSE2) { 
    2709       ui_netSource.integer--; 
    2710       if (ui_netSource.integer == AS_MPLAYER) 
    2711         ui_netSource.integer--; 
    2712     } else { 
    2713       ui_netSource.integer++; 
    2714       if (ui_netSource.integer == AS_MPLAYER) 
    2715         ui_netSource.integer++; 
    2716     } 
    2717  
    2718     if (ui_netSource.integer >= numNetSources) { 
    2719       ui_netSource.integer = 0; 
    2720     } else if (ui_netSource.integer < 0) { 
    2721       ui_netSource.integer = numNetSources - 1; 
    2722     } 
    2723  
    2724     UI_BuildServerDisplayList(qtrue); 
    2725     if (ui_netSource.integer != AS_GLOBAL) { 
    2726       UI_StartServerRefresh(qtrue); 
    2727     } 
    2728     trap_Cvar_Set( "ui_netSource", va("%d", ui_netSource.integer)); 
    2729     return qtrue; 
    2730   } 
    2731   return qfalse; 
    2732 } 
    2733  
    2734 static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) { 
    2735   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2736  
    2737     if (key == K_MOUSE2) { 
    2738       ui_serverFilterType.integer--; 
    2739     } else { 
    2740       ui_serverFilterType.integer++; 
    2741     } 
    2742  
    2743     if (ui_serverFilterType.integer >= numServerFilters) { 
    2744       ui_serverFilterType.integer = 0; 
    2745     } else if (ui_serverFilterType.integer < 0) { 
    2746       ui_serverFilterType.integer = numServerFilters - 1; 
    2747     } 
    2748     UI_BuildServerDisplayList(qtrue); 
    2749     return qtrue; 
    2750   } 
    2751   return qfalse; 
    2752 } 
    2753  
    2754 static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) { 
    2755   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2756     if (key == K_MOUSE2) { 
    2757       UI_PriorOpponent(); 
    2758     } else { 
    2759       UI_NextOpponent(); 
    2760     } 
    2761     return qtrue; 
    2762   } 
    2763   return qfalse; 
    2764 } 
    2765  
    2766 static qboolean UI_BotName_HandleKey(int flags, float *special, int key) { 
    2767   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2768     int value = uiInfo.botIndex; 
    2769  
    2770     if (key == K_MOUSE2) { 
    2771       value--; 
    2772     } else { 
    2773       value++; 
    2774     } 
    2775  
    2776  
    2777     if( value >= UI_GetNumBots( ) + 2 ) 
    2778       value = 0; 
    2779     else if( value < 0 ) 
    2780       value = UI_GetNumBots( ) + 2 - 1; 
    2781  
    2782     uiInfo.botIndex = value; 
    2783     return qtrue; 
    2784   } 
    2785   return qfalse; 
    2786 } 
    2787  
    2788 static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) { 
    2789   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2790     if (key == K_MOUSE2) { 
    2791       uiInfo.skillIndex--; 
    2792     } else { 
    2793       uiInfo.skillIndex++; 
    2794     } 
    2795     if (uiInfo.skillIndex >= numSkillLevels) { 
    2796       uiInfo.skillIndex = 0; 
    2797     } else if (uiInfo.skillIndex < 0) { 
    2798       uiInfo.skillIndex = numSkillLevels-1; 
    2799     } 
    2800     return qtrue; 
    2801   } 
    2802   return qfalse; 
    2803 } 
    2804  
    2805 static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) { 
    2806   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2807     uiInfo.redBlue ^= 1; 
    2808     return qtrue; 
    2809   } 
    2810   return qfalse; 
    2811 } 
    2812  
    2813  
    2814  
    2815 static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) { 
    2816   if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) { 
    2817     int selected; 
    2818  
    2819     UI_BuildPlayerList(); 
    2820     if (!uiInfo.teamLeader) { 
    2821       return qfalse; 
    2822     } 
    2823     selected = trap_Cvar_VariableValue("cg_selectedPlayer"); 
    2824  
    2825     if (key == K_MOUSE2) { 
    2826       selected--; 
    2827     } else { 
    2828       selected++; 
    2829     } 
    2830  
    2831     if (selected > uiInfo.myTeamCount) { 
    2832       selected = 0; 
    2833     } else if (selected < 0) { 
    2834       selected = uiInfo.myTeamCount; 
    2835     } 
    2836  
    2837     if (selected == uiInfo.myTeamCount) { 
    2838       trap_Cvar_Set( "cg_selectedPlayerName", "Everyone"); 
    2839     } else { 
    2840       trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]); 
    2841     } 
    2842     trap_Cvar_Set( "cg_selectedPlayer", va("%d", selected)); 
    2843   } 
    2844   return qfalse; 
    2845 } 
    2846  
    2847  
    2848 static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) { 
    2849   switch (ownerDraw) { 
    2850     case UI_HANDICAP: 
    2851       return UI_Handicap_HandleKey(flags, special, key); 
    2852       break; 
    2853     case UI_CLANNAME: 
    2854       return UI_ClanName_HandleKey(flags, special, key); 
    2855       break; 
    2856     case UI_GAMETYPE: 
    2857       return UI_GameType_HandleKey(flags, special, key, qtrue); 
    2858       break; 
    2859     case UI_NETGAMETYPE: 
    2860       return UI_NetGameType_HandleKey(flags, special, key); 
    2861       break; 
    2862     case UI_JOINGAMETYPE: 
    2863       return UI_JoinGameType_HandleKey(flags, special, key); 
    2864       break; 
    2865     case UI_SKILL: 
    2866       return UI_Skill_HandleKey(flags, special, key); 
    2867       break; 
    2868     case UI_BLUETEAMNAME: 
    2869       return UI_TeamName_HandleKey(flags, special, key, qtrue); 
    2870       break; 
    2871     case UI_REDTEAMNAME: 
    2872       return UI_TeamName_HandleKey(flags, special, key, qfalse); 
    2873       break; 
    2874     case UI_BLUETEAM1: 
    2875     case UI_BLUETEAM2: 
    2876     case UI_BLUETEAM3: 
    2877     case UI_BLUETEAM4: 
    2878     case UI_BLUETEAM5: 
    2879       UI_TeamMember_HandleKey(flags, special, key, qtrue, ownerDraw - UI_BLUETEAM1 + 1); 
    2880       break; 
    2881     case UI_REDTEAM1: 
    2882     case UI_REDTEAM2: 
    2883     case UI_REDTEAM3: 
    2884     case UI_REDTEAM4: 
    2885     case UI_REDTEAM5: 
    2886       UI_TeamMember_HandleKey(flags, special, key, qfalse, ownerDraw - UI_REDTEAM1 + 1); 
    2887       break; 
    2888     case UI_NETSOURCE: 
    2889       UI_NetSource_HandleKey(flags, special, key); 
    2890       break; 
    2891     case UI_NETFILTER: 
    2892       UI_NetFilter_HandleKey(flags, special, key); 
    2893       break; 
    2894     case UI_OPPONENT_NAME: 
    2895       UI_OpponentName_HandleKey(flags, special, key); 
    2896       break; 
    2897     case UI_BOTNAME: 
    2898       return UI_BotName_HandleKey(flags, special, key); 
    2899       break; 
    2900     case UI_BOTSKILL: 
    2901       return UI_BotSkill_HandleKey(flags, special, key); 
    2902       break; 
    2903     case UI_REDBLUE: 
    2904       UI_RedBlue_HandleKey(flags, special, key); 
    2905       break; 
    2906     case UI_SELECTEDPLAYER: 
    2907       UI_SelectedPlayer_HandleKey(flags, special, key); 
    2908       break; 
    2909     default: 
    2910       break; 
    2911   } 
    2912  
    2913   return qfalse; 
    2914 } 
    2915  
    2916  
    2917 static float UI_GetValue(int ownerDraw) { 
    2918   return 0; 
    2919 } 
    2920  
    2921 /* 
    2922 ================= 
    2923 UI_ServersQsortCompare 
    2924 ================= 
    2925 */ 
    2926 static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ) { 
    2927   return trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, uiInfo.serverStatus.sortDir, *(int*)arg1, *(int*)arg2); 
    2928 } 
    2929  
    2930  
    2931 /* 
    2932 ================= 
    2933 UI_ServersSort 
    2934 ================= 
    2935 */ 
    2936 void UI_ServersSort(int column, qboolean force) { 
    2937  
    2938   if ( !force ) { 
    2939     if ( uiInfo.serverStatus.sortKey == column ) { 
    2940       return; 
    2941     } 
    2942   } 
    2943  
    2944   uiInfo.serverStatus.sortKey = column; 
    2945   qsort( &uiInfo.serverStatus.displayServers[0], uiInfo.serverStatus.numDisplayServers, sizeof(int), UI_ServersQsortCompare); 
    2946 } 
    2947  
    2948  
    2949 /* 
    2950 =============== 
    2951 UI_GetCurrentAlienStage 
    2952 =============== 
    2953 */ 
    2954 static stage_t UI_GetCurrentAlienStage( void ) 
    2955 { 
    2956   char    buffer[ MAX_TOKEN_CHARS ]; 
    2957   stage_t stage, dummy; 
    2958  
    2959   trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) ); 
    2960   sscanf( buffer, "%d %d", (int *)&stage , (int *)&dummy ); 
    2961  
    2962   return stage; 
    2963 } 
    2964  
    2965 /* 
    2966 =============== 
    2967 UI_GetCurrentHumanStage 
    2968 =============== 
    2969 */ 
    2970 static stage_t UI_GetCurrentHumanStage( void ) 
    2971 { 
    2972   char    buffer[ MAX_TOKEN_CHARS ]; 
    2973   stage_t stage, dummy; 
    2974  
    2975   trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) ); 
    2976   sscanf( buffer, "%d %d", (int *)&dummy, (int *)&stage ); 
    2977  
    2978   return stage; 
    2979 } 
    2980  
    2981 /* 
    2982 =============== 
    2983 UI_LoadTeams 
    2984 =============== 
    2985 */ 
    2986 static void UI_LoadTeams( void ) 
    2987 { 
    2988   uiInfo.tremTeamCount = 4; 
    2989  
    2990   uiInfo.tremTeamList[ 0 ].text = String_Alloc( "Aliens" ); 
    2991   uiInfo.tremTeamList[ 0 ].cmd = String_Alloc( "cmd team aliens\n" ); 
    2992   uiInfo.tremTeamList[ 0 ].type = INFOTYPE_TEXT; 
    2993   uiInfo.tremTeamList[ 0 ].v.text = 
    2994     "The Alien Team\n\n" 
    2995     "The Aliens' strengths are in movement and the ability to " 
    2996     "quickly construct new bases quickly. They possess a range " 
    2997     "of abilities including basic melee attacks, movement-" 
    2998     "crippling poisons and more."; 
    2999  
    3000   uiInfo.tremTeamList[ 1 ].text = String_Alloc( "Humans" ); 
    3001   uiInfo.tremTeamList[ 1 ].cmd = String_Alloc( "cmd team humans\n" ); 
    3002   uiInfo.tremTeamList[ 1 ].type = INFOTYPE_TEXT; 
    3003   uiInfo.tremTeamList[ 1 ].v.text = 
    3004      "The Human Team\n\n" 
    3005      "The humans are the masters of technology. Although their " 
    3006      "bases take long to construct, their automated defense " 
    3007      "ensures they stay built. A wide range of upgrades and " 
    3008      "weapons are available to the humans, each contributing " 
    3009      "to eradicate the alien threat."; 
    3010  
    3011   uiInfo.tremTeamList[ 2 ].text = String_Alloc( "Spectate" ); 
    3012   uiInfo.tremTeamList[ 2 ].cmd = String_Alloc( "cmd team spectate\n" ); 
    3013   uiInfo.tremTeamList[ 2 ].type = INFOTYPE_TEXT; 
    3014   uiInfo.tremTeamList[ 2 ].v.text = "Watch the game without playing."; 
    3015  
    3016   uiInfo.tremTeamList[ 3 ].text = String_Alloc( "Auto select" ); 
    3017   uiInfo.tremTeamList[ 3 ].cmd = String_Alloc( "cmd team auto\n" ); 
    3018   uiInfo.tremTeamList[ 3 ].type = INFOTYPE_TEXT; 
    3019   uiInfo.tremTeamList[ 3 ].v.text = "Join the team with the least players."; 
    3020 } 
    3021  
    3022 /* 
    3023 =============== 
    3024 UI_AddClass 
    3025 =============== 
    3026 */ 
    3027 static void UI_AddClass( pClass_t class ) 
    3028 { 
    3029   uiInfo.alienClassList[ uiInfo.alienClassCount ].text = 
    3030     String_Alloc( BG_FindHumanNameForClassNum( class ) ); 
    3031   uiInfo.alienClassList[ uiInfo.alienClassCount ].cmd = 
    3032     String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( class ) ) ); 
    3033   uiInfo.alienClassList[ uiInfo.alienClassCount ].type = INFOTYPE_CLASS; 
    3034   uiInfo.alienClassList[ uiInfo.alienClassCount ].v.pclass = class; 
    3035  
    3036   uiInfo.alienClassCount++; 
    3037 } 
    3038  
    3039 /* 
    3040 =============== 
    3041 UI_LoadAlienClasses 
    3042 =============== 
    3043 */ 
    3044 static void UI_LoadAlienClasses( void ) 
    3045 { 
    3046   uiInfo.alienClassCount = 0; 
    3047  
    3048   if( BG_ClassIsAllowed( PCL_ALIEN_LEVEL0 ) ) 
    3049     UI_AddClass( PCL_ALIEN_LEVEL0 ); 
    3050  
    3051   if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0_UPG ) && 
    3052       BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, UI_GetCurrentAlienStage( ) ) ) 
    3053     UI_AddClass( PCL_ALIEN_BUILDER0_UPG ); 
    3054   else if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) ) 
    3055     UI_AddClass( PCL_ALIEN_BUILDER0 ); 
    3056 } 
    3057  
    3058 /* 
    3059 =============== 
    3060 UI_AddItem 
    3061 =============== 
    3062 */ 
    3063 static void UI_AddItem( weapon_t weapon ) 
    3064 { 
    3065   uiInfo.humanItemList[ uiInfo.humanItemCount ].text = 
    3066     String_Alloc( BG_FindHumanNameForWeapon( weapon ) ); 
    3067   uiInfo.humanItemList[ uiInfo.humanItemCount ].cmd = 
    3068     String_Alloc( va( "cmd class %s\n", BG_FindNameForWeapon( weapon ) ) ); 
    3069   uiInfo.humanItemList[ uiInfo.humanItemCount ].type = INFOTYPE_WEAPON; 
    3070   uiInfo.humanItemList[ uiInfo.humanItemCount ].v.weapon = weapon; 
    3071  
    3072   uiInfo.humanItemCount++; 
    3073 } 
    3074  
    3075 /* 
    3076 =============== 
    3077 UI_LoadHumanItems 
    3078 =============== 
    3079 */ 
    3080 static void UI_LoadHumanItems( void ) 
    3081 { 
    3082   uiInfo.humanItemCount = 0; 
    3083  
    3084   if( BG_WeaponIsAllowed( WP_MACHINEGUN ) ) 
    3085     UI_AddItem( WP_MACHINEGUN ); 
    3086  
    3087   if( BG_WeaponIsAllowed( WP_HBUILD2 ) && 
    3088       BG_FindStagesForWeapon( WP_HBUILD2, UI_GetCurrentHumanStage( ) ) ) 
    3089     UI_AddItem( WP_HBUILD2 ); 
    3090   else if( BG_WeaponIsAllowed( WP_HBUILD ) ) 
    3091     UI_AddItem( WP_HBUILD ); 
    3092 } 
    3093  
    3094 /* 
    3095 =============== 
    3096 UI_ParseCarriageList 
    3097 =============== 
    3098 */ 
    3099 static void UI_ParseCarriageList( int *weapons, int *upgrades ) 
    3100 { 
    3101   int  i; 
    3102   char carriageCvar[ MAX_TOKEN_CHARS ]; 
    3103   char *iterator; 
    3104   char buffer[ MAX_TOKEN_CHARS ]; 
    3105   char *bufPointer; 
    3106  
    3107   trap_Cvar_VariableStringBuffer( "ui_carriage", carriageCvar, sizeof( carriageCvar ) ); 
    3108   iterator = carriageCvar; 
    3109  
    3110   if( weapons ) 
    3111     *weapons = 0; 
    3112  
    3113   if( upgrades ) 
    3114     *upgrades = 0; 
    3115  
    3116   //simple parser to give rise to weapon/upgrade list 
    3117   while( iterator && iterator[ 0 ] != '$' ) 
    3118   { 
    3119     bufPointer = buffer; 
    3120  
    3121     if( iterator[ 0 ] == 'W' ) 
    3122     { 
    3123       iterator++; 
    3124  
    3125       while( iterator[ 0 ] != ' ' ) 
    3126         *bufPointer++ = *iterator++; 
    3127  
    3128       *bufPointer++ = '\n'; 
    3129  
    3130       i = atoi( buffer ); 
    3131  
    3132       if( weapons ) 
    3133         *weapons |= ( 1 << i ); 
    3134     } 
    3135     else if( iterator[ 0 ] == 'U' ) 
    3136     { 
    3137       iterator++; 
    3138  
    3139       while( iterator[ 0 ] != ' ' ) 
    3140         *bufPointer++ = *iterator++; 
    3141  
    3142       *bufPointer++ = '\n'; 
    3143  
    3144       i = atoi( buffer ); 
    3145  
    3146       if( upgrades ) 
    3147         *upgrades |= ( 1 << i ); 
    3148     } 
    3149  
    3150     iterator++; 
    3151   } 
    3152 } 
    3153  
    3154 /* 
    3155 =============== 
    3156 UI_LoadHumanArmouryBuys 
    3157 =============== 
    3158 */ 
    3159 static void UI_LoadHumanArmouryBuys( void ) 
    3160 { 
    3161   int i, j = 0; 
    3162   stage_t stage = UI_GetCurrentHumanStage( ); 
    3163   int weapons, upgrades; 
    3164   int slots = 0; 
    3165  
    3166   UI_ParseCarriageList( &weapons, &upgrades ); 
    3167  
    3168   for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
    3169   { 
    3170     if( weapons & ( 1 << i ) ) 
    3171       slots |= BG_FindSlotsForWeapon( i ); 
    3172   } 
    3173  
    3174   for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
    3175   { 
    3176     if( upgrades & ( 1 << i ) ) 
    3177       slots |= BG_FindSlotsForUpgrade( i ); 
    3178   } 
    3179  
    3180   uiInfo.humanArmouryBuyCount = 0; 
    3181  
    3182   for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
    3183   { 
    3184     if( BG_FindTeamForWeapon( i ) == WUT_HUMANS && 
    3185         BG_FindPurchasableForWeapon( i ) && 
    3186         BG_FindStagesForWeapon( i, stage ) && 
    3187         BG_WeaponIsAllowed( i ) && 
    3188         !( BG_FindSlotsForWeapon( i ) & slots ) && 
    3189         !( weapons & ( 1 << i ) ) ) 
    3190     { 
    3191       uiInfo.humanArmouryBuyList[ j ].text = 
    3192         String_Alloc( BG_FindHumanNameForWeapon( i ) ); 
    3193       uiInfo.humanArmouryBuyList[ j ].cmd = 
    3194         String_Alloc( va( "cmd buy %s retrigger\n", BG_FindNameForWeapon( i ) ) ); 
    3195       uiInfo.humanArmouryBuyList[ j ].type = INFOTYPE_WEAPON; 
    3196       uiInfo.humanArmouryBuyList[ j ].v.weapon = i; 
    3197  
    3198       j++; 
    3199  
    3200       uiInfo.humanArmouryBuyCount++; 
    3201     } 
    3202   } 
    3203  
    3204   for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
    3205   { 
    3206     if( BG_FindTeamForUpgrade( i ) == WUT_HUMANS && 
    3207         BG_FindPurchasableForUpgrade( i ) && 
    3208         BG_FindStagesForUpgrade( i, stage ) && 
    3209         BG_UpgradeIsAllowed( i ) && 
    3210         !( BG_FindSlotsForUpgrade( i ) & slots ) && 
    3211         !( upgrades & ( 1 << i ) ) ) 
    3212     { 
    3213       uiInfo.humanArmouryBuyList[ j ].text = 
    3214         String_Alloc( BG_FindHumanNameForUpgrade( i ) ); 
    3215       uiInfo.humanArmouryBuyList[ j ].cmd = 
    3216         String_Alloc( va( "cmd buy %s retrigger\n", BG_FindNameForUpgrade( i ) ) ); 
    3217       uiInfo.humanArmouryBuyList[ j ].type = INFOTYPE_UPGRADE; 
    3218       uiInfo.humanArmouryBuyList[ j ].v.upgrade = i; 
    3219  
    3220       j++; 
    3221  
    3222       uiInfo.humanArmouryBuyCount++; 
    3223     } 
    3224   } 
    3225 } 
    3226  
    3227 /* 
    3228 =============== 
    3229 UI_LoadHumanArmourySells 
    3230 =============== 
    3231 */ 
    3232 static void UI_LoadHumanArmourySells( void ) 
    3233 { 
    3234   int weapons, upgrades; 
    3235   int i, j = 0; 
    3236  
    3237   uiInfo.humanArmourySellCount = 0; 
    3238   UI_ParseCarriageList( &weapons, &upgrades ); 
    3239  
    3240   for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
    3241   { 
    3242     if( weapons & ( 1 << i ) ) 
    3243     { 
    3244       uiInfo.humanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForWeapon( i ) ); 
    3245       uiInfo.humanArmourySellList[ j ].cmd = 
    3246         String_Alloc( va( "cmd sell %s retrigger\n", BG_FindNameForWeapon( i ) ) ); 
    3247       uiInfo.humanArmourySellList[ j ].type = INFOTYPE_WEAPON; 
    3248       uiInfo.humanArmourySellList[ j ].v.weapon = i; 
    3249  
    3250       j++; 
    3251  
    3252       uiInfo.humanArmourySellCount++; 
    3253     } 
    3254   } 
    3255  
    3256   for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
    3257   { 
    3258     if( upgrades & ( 1 << i ) ) 
    3259     { 
    3260       uiInfo.humanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForUpgrade( i ) ); 
    3261       uiInfo.humanArmourySellList[ j ].cmd = 
    3262         String_Alloc( va( "cmd sell %s retrigger\n", BG_FindNameForUpgrade( i ) ) ); 
    3263       uiInfo.humanArmourySellList[ j ].type = INFOTYPE_UPGRADE; 
    3264       uiInfo.humanArmourySellList[ j ].v.upgrade = i; 
    3265  
    3266       j++; 
    3267  
    3268       uiInfo.humanArmourySellCount++; 
    3269     } 
    3270   } 
    3271 } 
    3272  
    3273 /* 
    3274 =============== 
    3275 UI_LoadAlienUpgrades 
    3276 =============== 
    3277 */ 
    3278 static void UI_LoadAlienUpgrades( void ) 
    3279 { 
    3280   int     i, j = 0; 
    3281   int     class, credits; 
    3282   char    ui_currentClass[ MAX_STRING_CHARS ]; 
    3283   stage_t stage = UI_GetCurrentAlienStage( ); 
    3284  
    3285   trap_Cvar_VariableStringBuffer( "ui_currentClass", ui_currentClass, MAX_STRING_CHARS ); 
    3286   sscanf( ui_currentClass, "%d %d", &class, &credits ); 
    3287  
    3288   uiInfo.alienUpgradeCount = 0; 
    3289  
    3290   for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) 
    3291   { 
    3292     if( BG_ClassCanEvolveFromTo( class, i, credits, 0 ) >= 0 && 
    3293         BG_FindStagesForClass( i, stage ) && 
    3294         BG_ClassIsAllowed( i ) ) 
    3295     { 
    3296       uiInfo.alienUpgradeList[ j ].text = String_Alloc( BG_FindHumanNameForClassNum( i ) ); 
    3297       uiInfo.alienUpgradeList[ j ].cmd = 
    3298         String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( i ) ) ); 
    3299       uiInfo.alienUpgradeList[ j ].type = INFOTYPE_CLASS; 
    3300       uiInfo.alienUpgradeList[ j ].v.pclass = i; 
    3301  
    3302       j++; 
    3303  
    3304       uiInfo.alienUpgradeCount++; 
    3305     } 
    3306   } 
    3307 } 
    3308  
    3309 /* 
    3310 =============== 
    3311 UI_LoadAlienBuilds 
    3312 =============== 
    3313 */ 
    3314 static void UI_LoadAlienBuilds( void ) 
    3315 { 
    3316   int     weapons; 
    3317   int     i, j = 0; 
    3318   stage_t stage; 
    3319  
    3320   UI_ParseCarriageList( &weapons, NULL ); 
    3321   stage = UI_GetCurrentAlienStage( ); 
    3322  
    3323   uiInfo.alienBuildCount = 0; 
    3324  
    3325   for( i = BA_NONE +1; i < BA_NUM_BUILDABLES; i++ ) 
    3326   { 
    3327     if( BG_FindTeamForBuildable( i ) == BIT_ALIENS && 
    3328         BG_FindBuildWeaponForBuildable( i ) & weapons && 
    3329         BG_FindStagesForBuildable( i, stage ) && 
    3330         BG_BuildableIsAllowed( i ) ) 
    3331     { 
    3332       uiInfo.alienBuildList[ j ].text = 
    3333         String_Alloc( BG_FindHumanNameForBuildable( i ) ); 
    3334       uiInfo.alienBuildList[ j ].cmd = 
    3335         String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) ); 
    3336       uiInfo.alienBuildList[ j ].type = INFOTYPE_BUILDABLE; 
    3337       uiInfo.alienBuildList[ j ].v.buildable = i; 
    3338  
    3339       j++; 
    3340  
    3341       uiInfo.alienBuildCount++; 
    3342     } 
    3343   } 
    3344 } 
    3345  
    3346 /* 
    3347 =============== 
    3348 UI_LoadHumanBuilds 
    3349 =============== 
    3350 */ 
    3351 static void UI_LoadHumanBuilds( void ) 
    3352 { 
    3353   int     weapons; 
    3354   int     i, j = 0; 
    3355   stage_t stage; 
    3356  
    3357   UI_ParseCarriageList( &weapons, NULL ); 
    3358   stage = UI_GetCurrentHumanStage( ); 
    3359  
    3360   uiInfo.humanBuildCount = 0; 
    3361  
    3362   for( i = BA_NONE +1; i < BA_NUM_BUILDABLES; i++ ) 
    3363   { 
    3364     if( BG_FindTeamForBuildable( i ) == BIT_HUMANS && 
    3365         BG_FindBuildWeaponForBuildable( i ) & weapons && 
    3366         BG_FindStagesForBuildable( i, stage ) && 
    3367         BG_BuildableIsAllowed( i ) ) 
    3368     { 
    3369       uiInfo.humanBuildList[ j ].text = 
    3370         String_Alloc( BG_FindHumanNameForBuildable( i ) ); 
    3371       uiInfo.humanBuildList[ j ].cmd = 
    3372         String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) ); 
    3373       uiInfo.humanBuildList[ j ].type = INFOTYPE_BUILDABLE; 
    3374       uiInfo.humanBuildList[ j ].v.buildable = i; 
    3375  
    3376       j++; 
    3377  
    3378       uiInfo.humanBuildCount++; 
    3379     } 
    3380   } 
    3381 } 
    3382  
    3383 /* 
    3384 =============== 
    3385 UI_LoadMods 
    3386 =============== 
    3387 */ 
    3388 static void UI_LoadMods( void ) { 
    3389   int   numdirs; 
    3390   char  dirlist[2048]; 
    3391   char  *dirptr; 
    3392   char  *descptr; 
    3393   int   i; 
    3394   int   dirlen; 
    3395  
    3396   uiInfo.modCount = 0; 
    3397   numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) ); 
    3398   dirptr  = dirlist; 
    3399   for( i = 0; i < numdirs; i++ ) { 
    3400     dirlen = strlen( dirptr ) + 1; 
    3401     descptr = dirptr + dirlen; 
    3402     uiInfo.modList[uiInfo.modCount].modName = String_Alloc(dirptr); 
    3403     uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc(descptr); 
    3404     dirptr += dirlen + strlen(descptr) + 1; 
    3405     uiInfo.modCount++; 
    3406     if (uiInfo.modCount >= MAX_MODS) { 
    3407       break; 
    3408     } 
    3409   } 
    3410  
    3411 } 
    3412  
    3413  
    3414 /* 
    3415 =============== 
    3416 UI_LoadMovies 
    3417 =============== 
    3418 */ 
    3419 static void UI_LoadMovies( void ) { 
    3420   char  movielist[4096]; 
    3421   char  *moviename; 
    3422   int   i, len; 
    3423  
    3424   uiInfo.movieCount = trap_FS_GetFileList( "video", "roq", movielist, 4096 ); 
    3425  
    3426   if (uiInfo.movieCount) { 
    3427     if (uiInfo.movieCount > MAX_MOVIES) { 
    3428       uiInfo.movieCount = MAX_MOVIES; 
    3429     } 
    3430     moviename = movielist; 
    3431     for ( i = 0; i < uiInfo.movieCount; i++ ) { 
    3432       len = strlen( moviename ); 
    3433       if (!Q_stricmp(moviename +  len - 4,".roq")) { 
    3434         moviename[len-4] = '\0'; 
    3435       } 
    3436       Q_strupr(moviename); 
    3437       uiInfo.movieList[i] = String_Alloc(moviename); 
    3438       moviename += len + 1; 
    3439     } 
    3440   } 
    3441  
    3442 } 
    3443  
    3444  
    3445  
    3446 /* 
    3447 =============== 
    3448 UI_LoadDemos 
    3449 =============== 
    3450 */ 
    3451 static void UI_LoadDemos( void ) { 
    3452   char  demolist[4096]; 
    3453   char demoExt[32]; 
    3454   char  *demoname; 
    3455   int   i, len; 
    3456  
    3457   Com_sprintf(demoExt, sizeof(demoExt), "dm_%d", (int)trap_Cvar_VariableValue("protocol")); 
    3458  
    3459   uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 ); 
    3460  
    3461   Com_sprintf(demoExt, sizeof(demoExt), ".dm_%d", (int)trap_Cvar_VariableValue("protocol")); 
    3462  
    3463   if (uiInfo.demoCount) { 
    3464     if (uiInfo.demoCount > MAX_DEMOS) { 
    3465       uiInfo.demoCount = MAX_DEMOS; 
    3466     } 
    3467     demoname = demolist; 
    3468     for ( i = 0; i < uiInfo.demoCount; i++ ) { 
    3469       len = strlen( demoname ); 
    3470       if (!Q_stricmp(demoname +  len - strlen(demoExt), demoExt)) { 
    3471         demoname[len-strlen(demoExt)] = '\0'; 
    3472       } 
    3473       Q_strupr(demoname); 
    3474       uiInfo.demoList[i] = String_Alloc(demoname); 
    3475       demoname += len + 1; 
    3476     } 
    3477   } 
    3478  
    3479 } 
    3480  
    3481  
    3482 static qboolean UI_SetNextMap(int actual, int index) { 
    3483   int i; 
    3484   for (i = actual + 1; i < uiInfo.mapCount; i++) { 
    3485     if (uiInfo.mapList[i].active) { 
    3486       Menu_SetFeederSelection(NULL, FEEDER_MAPS, index + 1, "skirmish"); 
    3487       return qtrue; 
    3488     } 
    3489   } 
    3490   return qfalse; 
    3491 } 
    3492  
    3493  
    3494 static void UI_StartSkirmish(qboolean next) { 
    3495   int i, k, g, delay, temp; 
    3496   float skill; 
    3497   char buff[MAX_STRING_CHARS]; 
    3498  
    3499   if (next) { 
    3500     int actual; 
    3501     int index = trap_Cvar_VariableValue("ui_mapIndex"); 
    3502     UI_MapCountByGameType(qtrue); 
    3503     UI_SelectedMap(index, &actual); 
    3504     if (UI_SetNextMap(actual, index)) { 
    3505     } else { 
    3506       UI_GameType_HandleKey(0, NULL, K_MOUSE1, qfalse); 
    3507       UI_MapCountByGameType(qtrue); 
    3508       Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, "skirmish"); 
    3509     } 
    3510   } 
    3511  
    3512   g = uiInfo.gameTypes[ui_gameType.integer].gtEnum; 
    3513   trap_Cvar_SetValue( "g_gametype", g ); 
    3514   trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName) ); 
    3515   skill = trap_Cvar_VariableValue( "g_spSkill" ); 
    3516   trap_Cvar_Set("ui_scoreMap", uiInfo.mapList[ui_currentMap.integer].mapName); 
    3517  
    3518   k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); 
    3519  
    3520   trap_Cvar_Set("ui_singlePlayerActive", "1"); 
    3521  
    3522   // set up sp overrides, will be replaced on postgame 
    3523   temp = trap_Cvar_VariableValue( "capturelimit" ); 
    3524   trap_Cvar_Set("ui_saveCaptureLimit", va("%i", temp)); 
    3525   temp = trap_Cvar_VariableValue( "fraglimit" ); 
    3526   trap_Cvar_Set("ui_saveFragLimit", va("%i", temp)); 
    3527  
    3528   UI_SetCapFragLimits(qfalse); 
    3529  
    3530   temp = trap_Cvar_VariableValue( "cg_drawTimer" ); 
    3531   trap_Cvar_Set("ui_drawTimer", va("%i", temp)); 
    3532   temp = trap_Cvar_VariableValue( "g_doWarmup" ); 
    3533   trap_Cvar_Set("ui_doWarmup", va("%i", temp)); 
    3534   temp = trap_Cvar_VariableValue( "g_friendlyFire" ); 
    3535   trap_Cvar_Set("ui_friendlyFire", va("%i", temp)); 
    3536   temp = trap_Cvar_VariableValue( "sv_maxClients" ); 
    3537   trap_Cvar_Set("ui_maxClients", va("%i", temp)); 
    3538   temp = trap_Cvar_VariableValue( "g_warmup" ); 
    3539   trap_Cvar_Set("ui_Warmup", va("%i", temp)); 
    3540   temp = trap_Cvar_VariableValue( "sv_pure" ); 
    3541   trap_Cvar_Set("ui_pure", va("%i", temp)); 
    3542  
    3543   trap_Cvar_Set("cg_cameraOrbit", "0"); 
    3544   trap_Cvar_Set("cg_thirdPerson", "0"); 
    3545   trap_Cvar_Set("cg_drawTimer", "1"); 
    3546   trap_Cvar_Set("g_doWarmup", "1"); 
    3547   trap_Cvar_Set("g_warmup", "15"); 
    3548   trap_Cvar_Set("sv_pure", "0"); 
    3549   trap_Cvar_Set("g_friendlyFire", "0"); 
    3550   trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName")); 
    3551   trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName")); 
    3552  
    3553   if (trap_Cvar_VariableValue("ui_recordSPDemo")) { 
    3554     Com_sprintf(buff, MAX_STRING_CHARS, "%s_%i", uiInfo.mapList[ui_currentMap.integer].mapLoadName, g); 
    3555     trap_Cvar_Set("ui_recordSPDemoName", buff); 
    3556   } 
    3557  
    3558   delay = 500; 
    3559  
    3560   { 
    3561     temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2; 
    3562     trap_Cvar_Set("sv_maxClients", va("%d", temp)); 
    3563     for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers; i++) { 
    3564       Com_sprintf( buff, sizeof(buff), "addbot %s %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, "", delay, uiInfo.teamList[k].teamMembers[i]); 
    3565       trap_Cmd_ExecuteText( EXEC_APPEND, buff ); 
    3566       delay += 500; 
    3567     } 
    3568     k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    3569     for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers-1; i++) { 
    3570       Com_sprintf( buff, sizeof(buff), "addbot %s %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, "", delay, uiInfo.teamList[k].teamMembers[i]); 
    3571       trap_Cmd_ExecuteText( EXEC_APPEND, buff ); 
    3572       delay += 500; 
    3573     } 
    3574   } 
    3575 } 
    3576  
    3577 static void UI_Update(const char *name) { 
    3578   int val = trap_Cvar_VariableValue(name); 
    3579  
    3580   if (Q_stricmp(name, "ui_SetName") == 0) { 
    3581     trap_Cvar_Set( "name", UI_Cvar_VariableString("ui_Name")); 
    3582   } else if (Q_stricmp(name, "ui_setRate") == 0) { 
    3583     float rate = trap_Cvar_VariableValue("rate"); 
    3584     if (rate >= 5000) { 
    3585       trap_Cvar_Set("cl_maxpackets", "30"); 
    3586       trap_Cvar_Set("cl_packetdup", "1"); 
    3587     } else if (rate >= 4000) { 
    3588       trap_Cvar_Set("cl_maxpackets", "15"); 
    3589       trap_Cvar_Set("cl_packetdup", "2");   // favor less prediction errors when there's packet loss 
    3590     } else { 
    3591       trap_Cvar_Set("cl_maxpackets", "15"); 
    3592       trap_Cvar_Set("cl_packetdup", "1");   // favor lower bandwidth 
    3593     } 
    3594   } else if (Q_stricmp(name, "ui_GetName") == 0) { 
    3595     trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString("name")); 
    3596   } else if (Q_stricmp(name, "r_colorbits") == 0) { 
    3597     switch (val) { 
    3598       case 0: 
    3599         trap_Cvar_SetValue( "r_depthbits", 0 ); 
    3600         trap_Cvar_SetValue( "r_stencilbits", 0 ); 
    3601       break; 
    3602       case 16: 
    3603         trap_Cvar_SetValue( "r_depthbits", 16 ); 
    3604         trap_Cvar_SetValue( "r_stencilbits", 0 ); 
    3605       break; 
    3606       case 32: 
    3607         trap_Cvar_SetValue( "r_depthbits", 24 ); 
    3608       break; 
    3609     } 
    3610   } else if (Q_stricmp(name, "r_lodbias") == 0) { 
    3611     switch (val) { 
    3612       case 0: 
    3613         trap_Cvar_SetValue( "r_subdivisions", 4 ); 
    3614       break; 
    3615       case 1: 
    3616         trap_Cvar_SetValue( "r_subdivisions", 12 ); 
    3617       break; 
    3618       case 2: 
    3619         trap_Cvar_SetValue( "r_subdivisions", 20 ); 
    3620       break; 
    3621     } 
    3622   } else if (Q_stricmp(name, "ui_glCustom") == 0) { 
    3623     switch (val) { 
    3624       case 0: // high quality 
    3625         trap_Cvar_SetValue( "r_fullScreen", 1 ); 
    3626         trap_Cvar_SetValue( "r_subdivisions", 4 ); 
    3627         trap_Cvar_SetValue( "r_vertexlight", 0 ); 
    3628         trap_Cvar_SetValue( "r_lodbias", 0 ); 
    3629         trap_Cvar_SetValue( "r_colorbits", 32 ); 
    3630         trap_Cvar_SetValue( "r_depthbits", 24 ); 
    3631         trap_Cvar_SetValue( "r_picmip", 0 ); 
    3632         trap_Cvar_SetValue( "r_mode", 4 ); 
    3633         trap_Cvar_SetValue( "r_texturebits", 32 ); 
    3634         trap_Cvar_SetValue( "r_fastSky", 0 ); 
    3635         trap_Cvar_SetValue( "r_inGameVideo", 1 ); 
    3636         trap_Cvar_SetValue( "cg_shadows", 1 ); 
    3637         trap_Cvar_SetValue( "cg_brassTime", 2500 ); 
    3638         trap_Cvar_SetValue( "cg_bounceParticles", 1 ); 
    3639         trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); 
    3640       break; 
    3641       case 1: // normal 
    3642         trap_Cvar_SetValue( "r_fullScreen", 1 ); 
    3643         trap_Cvar_SetValue( "r_subdivisions", 12 ); 
    3644         trap_Cvar_SetValue( "r_vertexlight", 0 ); 
    3645         trap_Cvar_SetValue( "r_lodbias", 0 ); 
    3646         trap_Cvar_SetValue( "r_colorbits", 0 ); 
    3647         trap_Cvar_SetValue( "r_depthbits", 24 ); 
    3648         trap_Cvar_SetValue( "r_picmip", 1 ); 
    3649         trap_Cvar_SetValue( "r_mode", 3 ); 
    3650         trap_Cvar_SetValue( "r_texturebits", 0 ); 
    3651         trap_Cvar_SetValue( "r_fastSky", 0 ); 
    3652         trap_Cvar_SetValue( "r_inGameVideo", 1 ); 
    3653         trap_Cvar_SetValue( "cg_brassTime", 2500 ); 
    3654         trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); 
    3655         trap_Cvar_SetValue( "cg_shadows", 0 ); 
    3656         trap_Cvar_SetValue( "cg_bounceParticles", 0 ); 
    3657       break; 
    3658       case 2: // fast 
    3659         trap_Cvar_SetValue( "r_fullScreen", 1 ); 
    3660         trap_Cvar_SetValue( "r_subdivisions", 8 ); 
    3661         trap_Cvar_SetValue( "r_vertexlight", 0 ); 
    3662         trap_Cvar_SetValue( "r_lodbias", 1 ); 
    3663         trap_Cvar_SetValue( "r_colorbits", 0 ); 
    3664         trap_Cvar_SetValue( "r_depthbits", 0 ); 
    3665         trap_Cvar_SetValue( "r_picmip", 1 ); 
    3666         trap_Cvar_SetValue( "r_mode", 3 ); 
    3667         trap_Cvar_SetValue( "r_texturebits", 0 ); 
    3668         trap_Cvar_SetValue( "cg_shadows", 0 ); 
    3669         trap_Cvar_SetValue( "r_fastSky", 1 ); 
    3670         trap_Cvar_SetValue( "r_inGameVideo", 0 ); 
    3671         trap_Cvar_SetValue( "cg_brassTime", 0 ); 
    3672         trap_Cvar_SetValue( "cg_bounceParticles", 0 ); 
    3673         trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" ); 
    3674       break; 
    3675       case 3: // fastest 
    3676         trap_Cvar_SetValue( "r_fullScreen", 1 ); 
    3677         trap_Cvar_SetValue( "r_subdivisions", 20 ); 
    3678         trap_Cvar_SetValue( "r_vertexlight", 1 ); 
    3679         trap_Cvar_SetValue( "r_lodbias", 2 ); 
    3680         trap_Cvar_SetValue( "r_colorbits", 16 ); 
    3681         trap_Cvar_SetValue( "r_depthbits", 16 ); 
    3682         trap_Cvar_SetValue( "r_mode", 3 ); 
    3683         trap_Cvar_SetValue( "r_picmip", 2 ); 
    3684         trap_Cvar_SetValue( "r_texturebits", 16 ); 
    3685         trap_Cvar_SetValue( "cg_shadows", 0 ); 
    3686         trap_Cvar_SetValue( "cg_brassTime", 0 ); 
    3687         trap_Cvar_SetValue( "r_fastSky", 1 ); 
    3688         trap_Cvar_SetValue( "r_inGameVideo", 0 ); 
    3689         trap_Cvar_SetValue( "cg_bounceParticles", 0 ); 
    3690         trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" ); 
    3691       break; 
    3692     } 
    3693   } else if (Q_stricmp(name, "ui_mousePitch") == 0) { 
    3694     if (val == 0) { 
    3695       trap_Cvar_SetValue( "m_pitch", 0.022f ); 
    3696     } else { 
    3697       trap_Cvar_SetValue( "m_pitch", -0.022f ); 
    3698     } 
    3699   } 
    3700 } 
    3701  
    3702 static void UI_RunMenuScript(char **args) { 
    3703   const char *name, *name2; 
    3704   char buff[1024]; 
    3705   const char *cmd; 
    3706  
    3707   if (String_Parse(args, &name)) { 
    3708     if (Q_stricmp(name, "StartServer") == 0) { 
    3709       int i, clients, oldclients; 
    3710       float skill; 
    3711       trap_Cvar_Set("cg_thirdPerson", "0"); 
    3712       trap_Cvar_Set("cg_cameraOrbit", "0"); 
    3713       trap_Cvar_Set("ui_singlePlayerActive", "0"); 
    3714       trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, ui_dedicated.integer ) ); 
    3715       trap_Cvar_SetValue( "g_gametype", Com_Clamp( 0, 8, uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) ); 
    3716       trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName")); 
    3717       trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName")); 
    3718       trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) ); 
    3719       skill = trap_Cvar_VariableValue( "g_spSkill" ); 
    3720       // set max clients based on spots 
    3721       oldclients = trap_Cvar_VariableValue( "sv_maxClients" ); 
    3722       clients = 0; 
    3723       for (i = 0; i < PLAYERS_PER_TEAM; i++) { 
    3724         int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1)); 
    3725         if (bot >= 0) { 
    3726           clients++; 
    3727         } 
    3728         bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1)); 
    3729         if (bot >= 0) { 
    3730           clients++; 
    3731         } 
    3732       } 
    3733       if (clients == 0) { 
    3734         clients = 8; 
    3735       } 
    3736  
    3737       if (oldclients > clients) { 
    3738         clients = oldclients; 
    3739       } 
    3740  
    3741       trap_Cvar_Set("sv_maxClients", va("%d",clients)); 
    3742  
    3743       for (i = 0; i < PLAYERS_PER_TEAM; i++) { 
    3744         int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1)); 
    3745         if (bot > 1) { 
    3746           Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); 
    3747           trap_Cmd_ExecuteText( EXEC_APPEND, buff ); 
    3748         } 
    3749         bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1)); 
    3750         if (bot > 1) { 
    3751           Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill); 
    3752           trap_Cmd_ExecuteText( EXEC_APPEND, buff ); 
    3753         } 
    3754       } 
    3755     } else if (Q_stricmp(name, "updateSPMenu") == 0) { 
    3756       UI_SetCapFragLimits(qtrue); 
    3757       UI_MapCountByGameType(qtrue); 
    3758       ui_mapIndex.integer = UI_GetIndexFromSelection(ui_currentMap.integer); 
    3759       trap_Cvar_Set("ui_mapIndex", va("%d", ui_mapIndex.integer)); 
    3760       Menu_SetFeederSelection(NULL, FEEDER_MAPS, ui_mapIndex.integer, "skirmish"); 
    3761       UI_GameType_HandleKey(0, NULL, K_MOUSE1, qfalse); 
    3762       UI_GameType_HandleKey(0, NULL, K_MOUSE2, qfalse); 
    3763     } else if (Q_stricmp(name, "resetDefaults") == 0) { 
    3764       trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n"); 
    3765       trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n"); 
    3766       Controls_SetDefaults(); 
    3767       trap_Cvar_Set("com_introPlayed", "1" ); 
    3768       trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); 
    3769     } else if (Q_stricmp(name, "loadArenas") == 0) { 
    3770       UI_LoadArenas(); 
    3771       UI_MapCountByGameType(qfalse); 
    3772       Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, "createserver"); 
    3773     } else if (Q_stricmp(name, "loadServerInfo") == 0) { 
    3774       UI_ServerInfo(); 
    3775     } else if (Q_stricmp(name, "saveControls") == 0) { 
    3776       Controls_SetConfig(qtrue); 
    3777     } else if (Q_stricmp(name, "loadControls") == 0) { 
    3778       Controls_GetConfig(); 
    3779     } else if (Q_stricmp(name, "clearError") == 0) { 
    3780       trap_Cvar_Set("com_errorMessage", ""); 
    3781     } else if (Q_stricmp(name, "loadGameInfo") == 0) { 
    3782 /*      UI_ParseGameInfo("gameinfo.txt"); 
    3783       UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);*/ 
    3784     } else if (Q_stricmp(name, "resetScores") == 0) { 
    3785       UI_ClearScores(); 
    3786     } else if (Q_stricmp(name, "RefreshServers") == 0) { 
    3787       UI_StartServerRefresh(qtrue); 
    3788       UI_BuildServerDisplayList(qtrue); 
    3789     } else if (Q_stricmp(name, "InitServerList") == 0) { 
    3790       int time = trap_RealTime( NULL ); 
    3791       int last; 
    3792       int sortColumn; 
    3793  
    3794       // set up default sorting 
    3795       if(!uiInfo.serverStatus.sorted && Int_Parse(args, &sortColumn)) 
    3796       { 
    3797         uiInfo.serverStatus.sortKey = sortColumn; 
    3798         uiInfo.serverStatus.sortDir = 0; 
    3799       } 
    3800  
    3801       // refresh if older than 3 days or if list is empty 
    3802       last = atoi( UI_Cvar_VariableString( va( "ui_lastServerRefresh_%i_time", 
    3803         ui_netSource.integer ) ) ); 
    3804       if( trap_LAN_GetServerCount( ui_netSource.integer ) < 1 || 
    3805         ( time - last ) > 3600 ) 
    3806       { 
    3807         UI_StartServerRefresh(qtrue); 
    3808         UI_BuildServerDisplayList(qtrue); 
    3809       } 
    3810     } else if (Q_stricmp(name, "RefreshFilter") == 0) { 
    3811       UI_StartServerRefresh(qfalse); 
    3812       UI_BuildServerDisplayList(qtrue); 
    3813     } else if (Q_stricmp(name, "RunSPDemo") == 0) { 
    3814       if (uiInfo.demoAvailable) { 
    3815         trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s_%i\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum)); 
    3816       } 
    3817     } else if (Q_stricmp(name, "LoadDemos") == 0) { 
    3818       UI_LoadDemos(); 
    3819     } else if (Q_stricmp(name, "LoadMovies") == 0) { 
    3820       UI_LoadMovies(); 
    3821     } else if (Q_stricmp(name, "LoadMods") == 0) { 
    3822       UI_LoadMods(); 
    3823     } 
    3824     else if( Q_stricmp( name, "LoadTeams" ) == 0 ) 
    3825       UI_LoadTeams( ); 
    3826     else if( Q_stricmp( name, "JoinTeam" ) == 0 ) 
    3827     { 
    3828       if( ( cmd = uiInfo.tremTeamList[ uiInfo.tremTeamIndex ].cmd ) ) 
    3829         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3830     } 
    3831     else if( Q_stricmp( name, "LoadHumanItems" ) == 0 ) 
    3832       UI_LoadHumanItems( ); 
    3833     else if( Q_stricmp( name, "SpawnWithHumanItem" ) == 0 ) 
    3834     { 
    3835       if( ( cmd = uiInfo.humanItemList[ uiInfo.humanItemIndex ].cmd ) ) 
    3836         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3837     } 
    3838     else if( Q_stricmp( name, "LoadAlienClasses" ) == 0 ) 
    3839       UI_LoadAlienClasses( ); 
    3840     else if( Q_stricmp( name, "SpawnAsAlienClass" ) == 0 ) 
    3841     { 
    3842       if( ( cmd = uiInfo.alienClassList[ uiInfo.alienClassIndex ].cmd ) ) 
    3843         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3844     } 
    3845     else if( Q_stricmp( name, "LoadHumanArmouryBuys" ) == 0 ) 
    3846       UI_LoadHumanArmouryBuys( ); 
    3847     else if( Q_stricmp( name, "BuyFromArmoury" ) == 0 ) 
    3848     { 
    3849       if( ( cmd = uiInfo.humanArmouryBuyList[ uiInfo.humanArmouryBuyIndex ].cmd ) ) 
    3850         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3851     } 
    3852     else if( Q_stricmp( name, "LoadHumanArmourySells" ) == 0 ) 
    3853       UI_LoadHumanArmourySells( ); 
    3854     else if( Q_stricmp( name, "SellToArmoury" ) == 0 ) 
    3855     { 
    3856       if( ( cmd = uiInfo.humanArmourySellList[ uiInfo.humanArmourySellIndex ].cmd ) ) 
    3857         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3858     } 
    3859     else if( Q_stricmp( name, "LoadAlienUpgrades" ) == 0 ) 
    3860     { 
    3861       UI_LoadAlienUpgrades( ); 
    3862  
    3863       //disallow the menu if it would be empty 
    3864       if( uiInfo.alienUpgradeCount <= 0 ) 
    3865         Menus_CloseAll( ); 
    3866     } 
    3867     else if( Q_stricmp( name, "UpgradeToNewClass" ) == 0 ) 
    3868     { 
    3869       if( ( cmd = uiInfo.alienUpgradeList[ uiInfo.alienUpgradeIndex ].cmd ) ) 
    3870         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3871     } 
    3872     else if( Q_stricmp( name, "LoadAlienBuilds" ) == 0 ) 
    3873       UI_LoadAlienBuilds( ); 
    3874     else if( Q_stricmp( name, "BuildAlienBuildable" ) == 0 ) 
    3875     { 
    3876       if( ( cmd = uiInfo.alienBuildList[ uiInfo.alienBuildIndex ].cmd ) ) 
    3877         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3878     } 
    3879     else if( Q_stricmp( name, "LoadHumanBuilds" ) == 0 ) 
    3880       UI_LoadHumanBuilds( ); 
    3881     else if( Q_stricmp( name, "BuildHumanBuildable" ) == 0 ) 
    3882     { 
    3883       if( ( cmd = uiInfo.humanBuildList[ uiInfo.humanBuildIndex ].cmd ) ) 
    3884         trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
    3885     } 
    3886     else if( Q_stricmp( name, "PTRCRestore" ) == 0 ) 
    3887     { 
    3888       int           len; 
    3889       char          text[ 16 ]; 
    3890       fileHandle_t  f; 
    3891       char          command[ 32 ]; 
    3892  
    3893       // load the file 
    3894       len = trap_FS_FOpenFile( "ptrc.cfg", &f, FS_READ ); 
    3895  
    3896       if( len > 0 && ( len < sizeof( text ) - 1 ) ) 
    3897       { 
    3898         trap_FS_Read( text, len, f ); 
    3899         text[ len ] = 0; 
    3900         trap_FS_FCloseFile( f ); 
    3901  
    3902         Com_sprintf( command, 32, "ptrcrestore %s", text ); 
    3903  
    3904         trap_Cmd_ExecuteText( EXEC_APPEND, command ); 
    3905       } 
    3906     } 
    3907     else if (Q_stricmp(name, "playMovie") == 0) { 
    3908       if (uiInfo.previewMovie >= 0) { 
    3909         trap_CIN_StopCinematic(uiInfo.previewMovie); 
    3910       } 
    3911       trap_Cmd_ExecuteText( EXEC_APPEND, va("cinematic %s.roq 2\n", uiInfo.movieList[uiInfo.movieIndex])); 
    3912     } else if (Q_stricmp(name, "RunMod") == 0) { 
    3913       trap_Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName); 
    3914       trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); 
    3915     } else if (Q_stricmp(name, "RunDemo") == 0) { 
    3916       trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s\n", uiInfo.demoList[uiInfo.demoIndex])); 
    3917     } else if (Q_stricmp(name, "Tremulous") == 0) { 
    3918       trap_Cvar_Set( "fs_game", ""); 
    3919       trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); 
    3920     } else if (Q_stricmp(name, "closeJoin") == 0) { 
    3921       if (uiInfo.serverStatus.refreshActive) { 
    3922         UI_StopServerRefresh(); 
    3923         uiInfo.serverStatus.nextDisplayRefresh = 0; 
    3924         uiInfo.nextServerStatusRefresh = 0; 
    3925         uiInfo.nextFindPlayerRefresh = 0; 
    3926         UI_BuildServerDisplayList(qtrue); 
    3927       } else { 
    3928         Menus_CloseByName("joinserver"); 
    3929         Menus_OpenByName("main"); 
    3930       } 
    3931     } else if (Q_stricmp(name, "StopRefresh") == 0) { 
    3932       UI_StopServerRefresh(); 
    3933       uiInfo.serverStatus.nextDisplayRefresh = 0; 
    3934       uiInfo.nextServerStatusRefresh = 0; 
    3935       uiInfo.nextFindPlayerRefresh = 0; 
    3936     } else if (Q_stricmp(name, "UpdateFilter") == 0) { 
    3937       if (ui_netSource.integer == AS_LOCAL) { 
    3938         UI_StartServerRefresh(qtrue); 
    3939       } 
    3940       UI_BuildServerDisplayList(qtrue); 
    3941       UI_FeederSelection(FEEDER_SERVERS, 0); 
    3942     } else if (Q_stricmp(name, "ServerStatus") == 0) { 
    3943       trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], uiInfo.serverStatusAddress, sizeof(uiInfo.serverStatusAddress)); 
    3944       UI_BuildServerStatus(qtrue); 
    3945     } else if (Q_stricmp(name, "FoundPlayerServerStatus") == 0) { 
    3946       Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress)); 
    3947       UI_BuildServerStatus(qtrue); 
    3948       Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL); 
    3949     } else if (Q_stricmp(name, "FindPlayer") == 0) { 
    3950       UI_BuildFindPlayerList(qtrue); 
    3951       // clear the displayed server status info 
    3952       uiInfo.serverStatusInfo.numLines = 0; 
    3953       Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL); 
    3954     } else if (Q_stricmp(name, "JoinServer") == 0) { 
    3955       trap_Cvar_Set("cg_thirdPerson", "0"); 
    3956       trap_Cvar_Set("cg_cameraOrbit", "0"); 
    3957       trap_Cvar_Set("ui_singlePlayerActive", "0"); 
    3958       if (uiInfo.serverStatus.currentServer >= 0 && uiInfo.serverStatus.currentServer < uiInfo.serverStatus.numDisplayServers) { 
    3959         trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, 1024); 
    3960         trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) ); 
    3961       } 
    3962     } else if (Q_stricmp(name, "FoundPlayerJoinServer") == 0) { 
    3963       trap_Cvar_Set("ui_singlePlayerActive", "0"); 
    3964       if (uiInfo.currentFoundPlayerServer >= 0 && uiInfo.currentFoundPlayerServer < uiInfo.numFoundPlayerServers) { 
    3965         trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer] ) ); 
    3966       } 
    3967     } else if (Q_stricmp(name, "Quit") == 0) { 
    3968       trap_Cvar_Set("ui_singlePlayerActive", "0"); 
    3969       trap_Cmd_ExecuteText( EXEC_NOW, "quit"); 
    3970     } else if (Q_stricmp(name, "Controls") == 0) { 
    3971       trap_Cvar_Set( "cl_paused", "1" ); 
    3972       trap_Key_SetCatcher( KEYCATCH_UI ); 
    3973       Menus_CloseAll(); 
    3974       Menus_ActivateByName("setup_menu2"); 
    3975     } else if (Q_stricmp(name, "Leave") == 0) { 
    3976       trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); 
    3977       trap_Key_SetCatcher( KEYCATCH_UI ); 
    3978       Menus_CloseAll(); 
    3979       Menus_ActivateByName("main"); 
    3980     } else if (Q_stricmp(name, "ServerSort") == 0) { 
    3981       int sortColumn; 
    3982       if (Int_Parse(args, &sortColumn)) { 
    3983         // if same column we're already sorting on then flip the direction 
    3984         if (sortColumn == uiInfo.serverStatus.sortKey) { 
    3985           uiInfo.serverStatus.sortDir = !uiInfo.serverStatus.sortDir; 
    3986         } 
    3987         // make sure we sort again 
    3988         UI_ServersSort(sortColumn, qtrue); 
    3989         uiInfo.serverStatus.sorted = qtrue; 
    3990       } 
    3991     } else if (Q_stricmp(name, "nextSkirmish") == 0) { 
    3992       UI_StartSkirmish(qtrue); 
    3993     } else if (Q_stricmp(name, "SkirmishStart") == 0) { 
    3994       UI_StartSkirmish(qfalse); 
    3995     } else if (Q_stricmp(name, "closeingame") == 0) { 
    3996       trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
    3997       trap_Key_ClearStates(); 
    3998       trap_Cvar_Set( "cl_paused", "0" ); 
    3999       Menus_CloseAll(); 
    4000     } else if (Q_stricmp(name, "voteMap") == 0) { 
    4001       if (ui_currentNetMap.integer >=0 && ui_currentNetMap.integer < uiInfo.mapCount) { 
    4002         trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote map %s\n",uiInfo.mapList[ui_currentNetMap.integer].mapLoadName) ); 
    4003       } 
    4004     } 
    4005     else if( Q_stricmp( name, "voteKick" ) == 0 ) 
    4006     { 
    4007       if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) 
    4008       { 
    4009         trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote kick %d\n", 
    4010               uiInfo.clientNums[ uiInfo.playerIndex ] ) ); 
    4011       } 
    4012     } 
    4013     else if( Q_stricmp( name, "voteMute" ) == 0 ) 
    4014     { 
    4015       if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) 
    4016       { 
    4017         trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote mute %d\n", 
    4018               uiInfo.clientNums[ uiInfo.playerIndex ] ) ); 
    4019       } 
    4020     } 
    4021     else if( Q_stricmp( name, "voteUnMute" ) == 0 ) 
    4022     { 
    4023       if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) 
    4024       { 
    4025         trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote unmute %d\n", 
    4026               uiInfo.clientNums[ uiInfo.playerIndex ] ) ); 
    4027       } 
    4028     } 
    4029     else if( Q_stricmp( name, "voteTeamKick" ) == 0 ) 
    4030     { 
    4031       if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount ) 
    4032       { 
    4033         trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote kick %d\n", 
    4034               uiInfo.teamClientNums[ uiInfo.teamIndex ] ) ); 
    4035       } 
    4036     } 
    4037     else if( Q_stricmp( name, "voteTeamDenyBuild" ) == 0 ) 
    4038     { 
    4039       if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount ) 
    4040       { 
    4041         trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote denybuild %d\n", 
    4042               uiInfo.teamClientNums[ uiInfo.teamIndex ] ) ); 
    4043       } 
    4044     } 
    4045     else if( Q_stricmp( name, "voteTeamAllowBuild" ) == 0 ) 
    4046     { 
    4047       if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount ) 
    4048       { 
    4049         trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote allowbuild %d\n", 
    4050               uiInfo.teamClientNums[ uiInfo.teamIndex ] ) ); 
    4051       } 
    4052     } 
    4053     else if (Q_stricmp(name, "addFavorite") == 0) { 
    4054       if (ui_netSource.integer != AS_FAVORITES) { 
    4055         char name[MAX_NAME_LENGTH]; 
    4056         char addr[MAX_NAME_LENGTH]; 
    4057         int res; 
    4058  
    4059         trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS); 
    4060         name[0] = addr[0] = '\0'; 
    4061         Q_strncpyz(name,  Info_ValueForKey(buff, "hostname"), MAX_NAME_LENGTH); 
    4062         Q_strncpyz(addr,  Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH); 
    4063         if (strlen(name) > 0 && strlen(addr) > 0) { 
    4064           res = trap_LAN_AddServer(AS_FAVORITES, name, addr); 
    4065           if (res == 0) { 
    4066             // server already in the list 
    4067             Com_Printf("Favorite already in list\n"); 
    4068           } 
    4069           else if (res == -1) { 
    4070             // list full 
    4071             Com_Printf("Favorite list full\n"); 
    4072           } 
    4073           else { 
    4074             // successfully added 
    4075             Com_Printf("Added favorite server %s\n", addr); 
    4076           } 
    4077         } 
    4078       } 
    4079     } else if (Q_stricmp(name, "deleteFavorite") == 0) { 
    4080       if (ui_netSource.integer == AS_FAVORITES) { 
    4081         char addr[MAX_NAME_LENGTH]; 
    4082         trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS); 
    4083         addr[0] = '\0'; 
    4084         Q_strncpyz(addr,  Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH); 
    4085         if (strlen(addr) > 0) { 
    4086           trap_LAN_RemoveServer(AS_FAVORITES, addr); 
    4087         } 
    4088       } 
    4089     } else if (Q_stricmp(name, "createFavorite") == 0) { 
    4090       if (ui_netSource.integer == AS_FAVORITES) { 
    4091         char name[MAX_NAME_LENGTH]; 
    4092         char addr[MAX_NAME_LENGTH]; 
    4093         int res; 
    4094  
    4095         name[0] = addr[0] = '\0'; 
    4096         Q_strncpyz(name,  UI_Cvar_VariableString("ui_favoriteName"), MAX_NAME_LENGTH); 
    4097         Q_strncpyz(addr,  UI_Cvar_VariableString("ui_favoriteAddress"), MAX_NAME_LENGTH); 
    4098         if (strlen(name) > 0 && strlen(addr) > 0) { 
    4099           res = trap_LAN_AddServer(AS_FAVORITES, name, addr); 
    4100           if (res == 0) { 
    4101             // server already in the list 
    4102             Com_Printf("Favorite already in list\n"); 
    4103           } 
    4104           else if (res == -1) { 
    4105             // list full 
    4106             Com_Printf("Favorite list full\n"); 
    4107           } 
    4108           else { 
    4109             // successfully added 
    4110             Com_Printf("Added favorite server %s\n", addr); 
    4111           } 
    4112         } 
    4113       } 
    4114     } else if (Q_stricmp(name, "orders") == 0) { 
    4115       const char *orders; 
    4116       if (String_Parse(args, &orders)) { 
    4117         int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer"); 
    4118         if (selectedPlayer < uiInfo.myTeamCount) { 
    4119           strcpy(buff, orders); 
    4120           trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) ); 
    4121           trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); 
    4122         } else { 
    4123           int i; 
    4124           for (i = 0; i < uiInfo.myTeamCount; i++) { 
    4125             if (Q_stricmp(UI_Cvar_VariableString("name"), uiInfo.teamNames[i]) == 0) { 
    4126               continue; 
    4127             } 
    4128             strcpy(buff, orders); 
    4129             trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamNames[i]) ); 
    4130             trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); 
    4131           } 
    4132         } 
    4133         trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
    4134         trap_Key_ClearStates(); 
    4135         trap_Cvar_Set( "cl_paused", "0" ); 
    4136         Menus_CloseAll(); 
    4137       } 
    4138     } else if (Q_stricmp(name, "voiceOrdersTeam") == 0) { 
    4139       const char *orders; 
    4140       if (String_Parse(args, &orders)) { 
    4141         int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer"); 
    4142         if (selectedPlayer == uiInfo.myTeamCount) { 
    4143           trap_Cmd_ExecuteText( EXEC_APPEND, orders ); 
    4144           trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); 
    4145         } 
    4146         trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
    4147         trap_Key_ClearStates(); 
    4148         trap_Cvar_Set( "cl_paused", "0" ); 
    4149         Menus_CloseAll(); 
    4150       } 
    4151     } else if (Q_stricmp(name, "voiceOrders") == 0) { 
    4152       const char *orders; 
    4153       if (String_Parse(args, &orders)) { 
    4154         int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer"); 
    4155         if (selectedPlayer < uiInfo.myTeamCount) { 
    4156           strcpy(buff, orders); 
    4157           trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) ); 
    4158           trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); 
    4159         } 
    4160         trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
    4161         trap_Key_ClearStates(); 
    4162         trap_Cvar_Set( "cl_paused", "0" ); 
    4163         Menus_CloseAll(); 
    4164       } 
    4165     } else if (Q_stricmp(name, "glCustom") == 0) { 
    4166       trap_Cvar_Set("ui_glCustom", "4"); 
    4167     } else if (Q_stricmp(name, "update") == 0) { 
    4168       if (String_Parse(args, &name2)) 
    4169         UI_Update(name2); 
    4170     } else if (Q_stricmp(name, "InitIgnoreList") == 0) { 
    4171       UI_BuildPlayerList(); 
    4172     } else if (Q_stricmp(name, "ToggleIgnore") == 0) { 
    4173       if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount ) 
    4174       { 
    4175         if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    4176           uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ) 
    4177         { 
    4178           BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    4179             uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
    4180           trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n",  
    4181             uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
    4182         } 
    4183         else 
    4184         { 
    4185           BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    4186             uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
    4187           trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n",  
    4188             uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
    4189         } 
    4190       } 
    4191     } else if (Q_stricmp(name, "IgnorePlayer") == 0) { 
    4192       if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount ) 
    4193       { 
    4194         if( !BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    4195           uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ) 
    4196         { 
    4197           BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    4198             uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
    4199           trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n",  
    4200             uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
    4201         } 
    4202       } 
    4203     } else if (Q_stricmp(name, "UnIgnorePlayer") == 0) { 
    4204       if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount ) 
    4205       { 
    4206         if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    4207           uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ) 
    4208         { 
    4209           BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    4210             uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
    4211           trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n",  
    4212             uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
    4213         } 
    4214       } 
    4215     } else if (Q_stricmp(name, "setPbClStatus") == 0) { 
    4216       int stat; 
    4217       if ( Int_Parse( args, &stat ) ) 
    4218         trap_SetPbClStatus( stat ); 
    4219     } 
    4220     else { 
    4221       Com_Printf("unknown UI script %s\n", name); 
    4222     } 
    4223   } 
    4224 } 
    4225  
    4226 static void UI_GetTeamColor(vec4_t *color) { 
    4227 } 
    4228  
    4229 /* 
    4230 ================== 
    4231 UI_MapCountByGameType 
    4232 ================== 
    4233 */ 
    4234 static int UI_MapCountByGameType(qboolean singlePlayer) { 
    4235   int i, c, game; 
    4236   c = 0; 
    4237   game = singlePlayer ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : uiInfo.gameTypes[ui_netGameType.integer].gtEnum; 
    4238  
    4239   for (i = 0; i < uiInfo.mapCount; i++) { 
    4240     uiInfo.mapList[i].active = qfalse; 
    4241     if ( uiInfo.mapList[i].typeBits & (1 << game)) { 
    4242       if (singlePlayer) { 
    4243         if (!(uiInfo.mapList[i].typeBits & (1 << 2))) { 
    4244           continue; 
    4245         } 
    4246       } 
    4247       c++; 
    4248       uiInfo.mapList[i].active = qtrue; 
    4249     } 
    4250   } 
    4251   return c; 
    4252 } 
    4253  
    4254 qboolean UI_hasSkinForBase(const char *base, const char *team) { 
    4255   char  test[1024]; 
    4256  
    4257   Com_sprintf( test, sizeof( test ), "models/players/%s/%s/lower_default.skin", base, team ); 
    4258  
    4259   if (trap_FS_FOpenFile(test, NULL, FS_READ)) { 
    4260     return qtrue; 
    4261   } 
    4262   Com_sprintf( test, sizeof( test ), "models/players/characters/%s/%s/lower_default.skin", base, team ); 
    4263  
    4264   if (trap_FS_FOpenFile(test, NULL, FS_READ)) { 
    4265     return qtrue; 
    4266   } 
    4267   return qfalse; 
    4268 } 
    4269  
    4270 /* 
    4271 ================== 
    4272 UI_MapCountByTeam 
    4273 ================== 
    4274 */ 
    4275 static int UI_HeadCountByTeam( void ) { 
    4276   static int init = 0; 
    4277   int i, j, k, c, tIndex; 
    4278  
    4279   c = 0; 
    4280   if (!init) { 
    4281     for (i = 0; i < uiInfo.characterCount; i++) { 
    4282       uiInfo.characterList[i].reference = 0; 
    4283       for (j = 0; j < uiInfo.teamCount; j++) { 
    4284         if (UI_hasSkinForBase(uiInfo.characterList[i].base, uiInfo.teamList[j].teamName)) { 
    4285           uiInfo.characterList[i].reference |= (1<<j); 
    4286         } 
    4287       } 
    4288     } 
    4289     init = 1; 
    4290   } 
    4291  
    4292   tIndex = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    4293  
    4294   // do names 
    4295   for (i = 0; i < uiInfo.characterCount; i++) { 
    4296     uiInfo.characterList[i].active = qfalse; 
    4297     for(j = 0; j < TEAM_MEMBERS; j++) { 
    4298       if (uiInfo.teamList[tIndex].teamMembers[j] != NULL) { 
    4299         if (uiInfo.characterList[i].reference&(1<<tIndex)) {// && Q_stricmp(uiInfo.teamList[tIndex].teamMembers[j], uiInfo.characterList[i].name)==0) { 
    4300           uiInfo.characterList[i].active = qtrue; 
    4301           c++; 
    4302           break; 
    4303         } 
    4304       } 
    4305     } 
    4306   } 
    4307  
    4308   // and then aliases 
    4309   for(j = 0; j < TEAM_MEMBERS; j++) { 
    4310     for(k = 0; k < uiInfo.aliasCount; k++) { 
    4311       if (uiInfo.aliasList[k].name != NULL) { 
    4312         if (Q_stricmp(uiInfo.teamList[tIndex].teamMembers[j], uiInfo.aliasList[k].name)==0) { 
    4313           for (i = 0; i < uiInfo.characterCount; i++) { 
    4314             if (uiInfo.characterList[i].headImage != -1 && uiInfo.characterList[i].reference&(1<<tIndex) && Q_stricmp(uiInfo.aliasList[k].ai, uiInfo.characterList[i].name)==0) { 
    4315               if (uiInfo.characterList[i].active == qfalse) { 
    4316                 uiInfo.characterList[i].active = qtrue; 
    4317                 c++; 
    4318               } 
    4319               break; 
    4320             } 
    4321           } 
    4322         } 
    4323       } 
    4324     } 
    4325   } 
    4326   return c; 
    4327234} 
    4328235 
     
    4332239================== 
    4333240*/ 
    4334 static void UI_InsertServerIntoDisplayList(int num, int position) { 
     241static void UI_InsertServerIntoDisplayList( int num, int position ) 
     242{ 
    4335243  int i; 
    4336244 
    4337   if (position < 0 || position > uiInfo.serverStatus.numDisplayServers ) { 
     245  if( position < 0 || position > uiInfo.serverStatus.numDisplayServers ) 
    4338246    return; 
    4339   } 
     247 
    4340248  // 
    4341249  uiInfo.serverStatus.numDisplayServers++; 
    4342   for (i = uiInfo.serverStatus.numDisplayServers; i > position; i--) { 
     250 
     251  for( i = uiInfo.serverStatus.numDisplayServers; i > position; i-- ) 
    4343252    uiInfo.serverStatus.displayServers[i] = uiInfo.serverStatus.displayServers[i-1]; 
    4344   } 
     253 
    4345254  uiInfo.serverStatus.displayServers[position] = num; 
    4346255} 
     
    4351260================== 
    4352261*/ 
    4353 static void UI_RemoveServerFromDisplayList(int num) { 
     262static void UI_RemoveServerFromDisplayList( int num ) 
     263{ 
    4354264  int i, j; 
    4355265 
    4356   for (i = 0; i < uiInfo.serverStatus.numDisplayServers; i++) { 
    4357     if (uiInfo.serverStatus.displayServers[i] == num) { 
     266  for( i = 0; i < uiInfo.serverStatus.numDisplayServers; i++ ) 
     267  { 
     268    if( uiInfo.serverStatus.displayServers[i] == num ) 
     269    { 
    4358270      uiInfo.serverStatus.numDisplayServers--; 
    4359       for (j = i; j < uiInfo.serverStatus.numDisplayServers; j++) { 
     271 
     272      for( j = i; j < uiInfo.serverStatus.numDisplayServers; j++ ) 
    4360273        uiInfo.serverStatus.displayServers[j] = uiInfo.serverStatus.displayServers[j+1]; 
    4361       } 
     274 
    4362275      return; 
    4363276    } 
     
    4370283================== 
    4371284*/ 
    4372 static void UI_BinaryServerInsertion(int num) { 
     285static void UI_BinaryServerInsertion( int num ) 
     286{ 
    4373287  int mid, offset, res, len; 
    4374288 
     
    4378292  offset = 0; 
    4379293  res = 0; 
    4380   while(mid > 0) { 
     294 
     295  while( mid > 0 ) 
     296  { 
    4381297    mid = len >> 1; 
    4382298    // 
    4383299    res = trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, 
    4384           uiInfo.serverStatus.sortDir, num, uiInfo.serverStatus.displayServers[offset+mid]); 
     300                                   uiInfo.serverStatus.sortDir, num, uiInfo.serverStatus.displayServers[offset+mid] ); 
    4385301    // if equal 
    4386     if (res == 0) { 
    4387       UI_InsertServerIntoDisplayList(num, offset+mid); 
     302 
     303    if( res == 0 ) 
     304    { 
     305      UI_InsertServerIntoDisplayList( num, offset + mid ); 
    4388306      return; 
    4389307    } 
     308 
    4390309    // if larger 
    4391     else if (res == 1) { 
     310    else if( res == 1 ) 
     311    { 
    4392312      offset += mid; 
    4393313      len -= mid; 
    4394314    } 
     315 
    4395316    // if smaller 
    4396     else { 
     317    else 
    4397318      len -= mid; 
    4398     } 
    4399   } 
    4400   if (res == 1) { 
     319  } 
     320 
     321  if( res == 1 ) 
    4401322    offset++; 
    4402   } 
    4403   UI_InsertServerIntoDisplayList(num, offset); 
    4404 } 
    4405  
    4406 /* 
    4407 ================== 
    4408 UI_BuildServerDisplayList 
    4409 ================== 
    4410 */ 
    4411 static void UI_BuildServerDisplayList(qboolean force) { 
    4412   int i, count, clients, maxClients, ping, game, len, visible; 
    4413   char info[MAX_STRING_CHARS]; 
    4414   static int numinvisible; 
    4415  
    4416   if (!(force || uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh)) { 
    4417     return; 
    4418   } 
    4419   // if we shouldn't reset 
    4420   if ( force == 2 ) { 
    4421     force = 0; 
    4422   } 
    4423  
    4424   // do motd updates here too 
    4425   trap_Cvar_VariableStringBuffer( "cl_motdString", uiInfo.serverStatus.motd, sizeof(uiInfo.serverStatus.motd) ); 
    4426   len = strlen(uiInfo.serverStatus.motd); 
    4427   if (len != uiInfo.serverStatus.motdLen) { 
    4428     uiInfo.serverStatus.motdLen = len; 
    4429     uiInfo.serverStatus.motdWidth = -1; 
    4430   } 
    4431  
    4432   if (force) { 
    4433     numinvisible = 0; 
    4434     // clear number of displayed servers 
    4435     uiInfo.serverStatus.numDisplayServers = 0; 
    4436     uiInfo.serverStatus.numPlayersOnServers = 0; 
    4437     // set list box index to zero 
    4438     Menu_SetFeederSelection(NULL, FEEDER_SERVERS, 0, NULL); 
    4439     // mark all servers as visible so we store ping updates for them 
    4440     trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue); 
    4441   } 
    4442  
    4443   // get the server count (comes from the master) 
    4444   count = trap_LAN_GetServerCount(ui_netSource.integer); 
    4445   if (count == -1 || (ui_netSource.integer == AS_LOCAL && count == 0) ) { 
    4446     // still waiting on a response from the master 
    4447     uiInfo.serverStatus.numDisplayServers = 0; 
    4448     uiInfo.serverStatus.numPlayersOnServers = 0; 
    4449     uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 500; 
    4450     return; 
    4451   } 
    4452  
    4453   visible = qfalse; 
    4454   for (i = 0; i < count; i++) { 
    4455     // if we already got info for this server 
    4456     if (!trap_LAN_ServerIsVisible(ui_netSource.integer, i)) { 
    4457       continue; 
    4458     } 
    4459     visible = qtrue; 
    4460     // get the ping for this server 
    4461     ping = trap_LAN_GetServerPing(ui_netSource.integer, i); 
    4462     if (ping > 0 || ui_netSource.integer == AS_FAVORITES) { 
    4463  
    4464       trap_LAN_GetServerInfo(ui_netSource.integer, i, info, MAX_STRING_CHARS); 
    4465  
    4466       clients = atoi(Info_ValueForKey(info, "clients")); 
    4467       uiInfo.serverStatus.numPlayersOnServers += clients; 
    4468  
    4469       if (ui_browserShowEmpty.integer == 0) { 
    4470         if (clients == 0) { 
    4471           trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); 
    4472           continue; 
    4473         } 
    4474       } 
    4475  
    4476       if (ui_browserShowFull.integer == 0) { 
    4477         maxClients = atoi(Info_ValueForKey(info, "sv_maxclients")); 
    4478         if (clients == maxClients) { 
    4479           trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); 
    4480           continue; 
    4481         } 
    4482       } 
    4483  
    4484       if (uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum != -1) { 
    4485         game = atoi(Info_ValueForKey(info, "gametype")); 
    4486         if (game != uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum) { 
    4487           trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); 
    4488           continue; 
    4489         } 
    4490       } 
    4491  
    4492       // make sure we never add a favorite server twice 
    4493       if (ui_netSource.integer == AS_FAVORITES) { 
    4494         UI_RemoveServerFromDisplayList(i); 
    4495       } 
    4496       // insert the server into the list 
    4497       UI_BinaryServerInsertion(i); 
    4498       // done with this server 
    4499       if (ping > 0) { 
    4500         trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); 
    4501         numinvisible++; 
    4502       } 
    4503     } 
    4504   } 
    4505  
    4506   uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime; 
    4507  
    4508   // if there were no servers visible for ping updates 
    4509   if (!visible) { 
    4510 //    UI_StopServerRefresh(); 
    4511 //    uiInfo.serverStatus.nextDisplayRefresh = 0; 
    4512   } 
     323 
     324  UI_InsertServerIntoDisplayList( num, offset ); 
    4513325} 
    4514326 
     
    4516328{ 
    4517329  char *name, *altName; 
    4518 } serverStatusCvar_t; 
     330} 
     331 
     332serverStatusCvar_t; 
    4519333 
    4520334serverStatusCvar_t serverStatusCvars[] = { 
    4521   {"sv_hostname", "Name"}, 
    4522   {"Address", ""}, 
    4523   {"gamename", "Game name"}, 
    4524   {"g_gametype", "Game type"}, 
    4525   {"mapname", "Map"}, 
    4526   {"version", ""}, 
    4527   {"protocol", ""}, 
    4528   {"timelimit", ""}, 
    4529   {"fraglimit", ""}, 
    4530   {NULL, NULL} 
    4531 }; 
     335      {"sv_hostname", "Name"}, 
     336      {"Address", ""}, 
     337      {"gamename", "Game name"}, 
     338      {"mapname", "Map"}, 
     339      {"version", ""}, 
     340      {"protocol", ""}, 
     341      {"timelimit", ""}, 
     342      {NULL, NULL} 
     343    }; 
    4532344 
    4533345/* 
     
    4536348================== 
    4537349*/ 
    4538 static void UI_SortServerStatusInfo( serverStatusInfo_t *info ) { 
     350static void UI_SortServerStatusInfo( serverStatusInfo_t *info ) 
     351{ 
    4539352  int i, j, index; 
    4540353  char *tmp1, *tmp2; 
    4541354 
    4542   // FIXME: if "gamename" == "baseq3" or "missionpack" then 
    4543   // replace the gametype number by FFA, CTF etc. 
    4544   // 
    4545355  index = 0; 
    4546   for (i = 0; serverStatusCvars[i].name; i++) { 
    4547     for (j = 0; j < info->numLines; j++) { 
    4548       if ( !info->lines[j][1] || info->lines[j][1][0] ) { 
     356 
     357  for( i = 0; serverStatusCvars[i].name; i++ ) 
     358  { 
     359    for( j = 0; j < info->numLines; j++ ) 
     360    { 
     361      if( !info->lines[j][1] || info->lines[j][1][0] ) 
    4549362        continue; 
    4550       } 
    4551       if ( !Q_stricmp(serverStatusCvars[i].name, info->lines[j][0]) ) { 
     363 
     364      if( !Q_stricmp( serverStatusCvars[i].name, info->lines[j][0] ) ) 
     365      { 
    4552366        // swap lines 
    4553367        tmp1 = info->lines[index][0]; 
     
    4558372        info->lines[j][3] = tmp2; 
    4559373        // 
    4560         if ( strlen(serverStatusCvars[i].altName) ) { 
     374 
     375        if( strlen( serverStatusCvars[i].altName ) ) 
    4561376          info->lines[index][0] = serverStatusCvars[i].altName; 
    4562         } 
     377 
    4563378        index++; 
    4564379      } 
     
    4572387================== 
    4573388*/ 
    4574 static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) { 
    4575   char *p, *score, *ping, *name; 
     389static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) 
     390{ 
     391  char * p, *score, *ping, *name; 
    4576392  int i, len; 
    4577393 
    4578   if (!info) { 
    4579     trap_LAN_ServerStatus( serverAddress, NULL, 0); 
     394  if( !info ) 
     395  { 
     396    trap_LAN_ServerStatus( serverAddress, NULL, 0 ); 
    4580397    return qfalse; 
    4581398  } 
    4582   memset(info, 0, sizeof(*info)); 
    4583   if ( trap_LAN_ServerStatus( serverAddress, info->text, sizeof(info->text)) ) { 
    4584     Q_strncpyz(info->address, serverAddress, sizeof(info->address)); 
     399 
     400  memset( info, 0, sizeof( *info ) ); 
     401 
     402  if( trap_LAN_ServerStatus( serverAddress, info->text, sizeof( info->text ) ) ) 
     403  { 
     404    Q_strncpyz( info->address, serverAddress, sizeof( info->address ) ); 
    4585405    p = info->text; 
    4586406    info->numLines = 0; 
     
    4591411    info->numLines++; 
    4592412    // get the cvars 
    4593     while (p && *p) { 
    4594       p = strchr(p, '\\'); 
    4595       if (!p) break; 
     413 
     414    while( p && *p ) 
     415    { 
     416      p = strchr( p, '\\' ); 
     417 
     418      if( !p ) break; 
     419 
    4596420      *p++ = '\0'; 
    4597       if (*p == '\\') 
     421 
     422      if( *p == '\\' ) 
    4598423        break; 
     424 
    4599425      info->lines[info->numLines][0] = p; 
    4600426      info->lines[info->numLines][1] = ""; 
    4601427      info->lines[info->numLines][2] = ""; 
    4602       p = strchr(p, '\\'); 
    4603       if (!p) break; 
     428 
     429      p = strchr( p, '\\' ); 
     430 
     431      if( !p ) break; 
     432 
    4604433      *p++ = '\0'; 
     434 
    4605435      info->lines[info->numLines][3] = p; 
    4606  
    4607436      info->numLines++; 
    4608       if (info->numLines >= MAX_SERVERSTATUS_LINES) 
     437 
     438      if( info->numLines >= MAX_SERVERSTATUS_LINES ) 
    4609439        break; 
    4610440    } 
     441 
    4611442    // get the player list 
    4612     if (info->numLines < MAX_SERVERSTATUS_LINES-3) { 
     443    if( info->numLines < MAX_SERVERSTATUS_LINES - 3 ) 
     444    { 
    4613445      // empty line 
    4614446      info->lines[info->numLines][0] = ""; 
     
    4626458      i = 0; 
    4627459      len = 0; 
    4628       while (p && *p) { 
    4629         if (*p == '\\') 
    4630           *p++ = '\0'; 
    4631         if (!p) 
     460 
     461      while( p && *p ) 
     462      { 
     463        if( *p == '\\' ) 
     464          * p++ = '\0'; 
     465 
     466        if( !p ) 
    4632467          break; 
     468 
    4633469        score = p; 
    4634         p = strchr(p, ' '); 
    4635         if (!p) 
     470 
     471        p = strchr( p, ' ' ); 
     472 
     473        if( !p ) 
    4636474          break; 
     475 
    4637476        *p++ = '\0'; 
     477 
    4638478        ping = p; 
    4639         p = strchr(p, ' '); 
    4640         if (!p) 
     479 
     480        p = strchr( p, ' ' ); 
     481 
     482        if( !p ) 
    4641483          break; 
     484 
    4642485        *p++ = '\0'; 
     486 
    4643487        name = p; 
    4644         Com_sprintf(&info->pings[len], sizeof(info->pings)-len, "%d", i); 
     488 
     489        Com_sprintf( &info->pings[len], sizeof( info->pings ) - len, "%d", i ); 
     490 
    4645491        info->lines[info->numLines][0] = &info->pings[len]; 
    4646         len += strlen(&info->pings[len]) + 1; 
     492 
     493        len += strlen( &info->pings[len] ) + 1; 
     494 
    4647495        info->lines[info->numLines][1] = score; 
    4648496        info->lines[info->numLines][2] = ping; 
    4649497        info->lines[info->numLines][3] = name; 
    4650498        info->numLines++; 
    4651         if (info->numLines >= MAX_SERVERSTATUS_LINES) 
     499 
     500        if( info->numLines >= MAX_SERVERSTATUS_LINES ) 
    4652501          break; 
    4653         p = strchr(p, '\\'); 
    4654         if (!p) 
     502 
     503        p = strchr( p, '\\' ); 
     504 
     505        if( !p ) 
    4655506          break; 
     507 
    4656508        *p++ = '\0'; 
     509 
    4657510        // 
    4658511        i++; 
    4659512      } 
    4660513    } 
     514 
    4661515    UI_SortServerStatusInfo( info ); 
    4662516    return qtrue; 
    4663517  } 
     518 
    4664519  return qfalse; 
    4665520} 
     
    4670525================== 
    4671526*/ 
    4672 static char *stristr(char *str, char *charset) { 
     527static char *stristr( char *str, char *charset ) 
     528{ 
    4673529  int i; 
    4674530 
    4675   while(*str) { 
    4676     for (i = 0; charset[i] && str[i]; i++) { 
    4677       if (toupper(charset[i]) != toupper(str[i])) break; 
    4678     } 
    4679     if (!charset[i]) return str; 
     531  while( *str ) 
     532  { 
     533    for( i = 0; charset[i] && str[i]; i++ ) 
     534      if( toupper( charset[i] ) != toupper( str[i] ) ) break; 
     535 
     536    if( !charset[i] ) return str; 
     537 
    4680538    str++; 
    4681539  } 
     540 
    4682541  return NULL; 
    4683542} 
     
    4688547================== 
    4689548*/ 
    4690 static void UI_BuildFindPlayerList(qboolean force) { 
     549static void UI_FeederSelection( float feederID, int index ); 
     550 
     551static void UI_BuildFindPlayerList( qboolean force ) 
     552{ 
    4691553  static int numFound, numTimeOuts; 
    4692   int i, j, resend; 
     554  int i, j, k, resend; 
    4693555  serverStatusInfo_t info; 
    4694556  char name[MAX_NAME_LENGTH+2]; 
    4695557  char infoString[MAX_STRING_CHARS]; 
    4696  
    4697   if (!force) { 
    4698     if (!uiInfo.nextFindPlayerRefresh || uiInfo.nextFindPlayerRefresh > uiInfo.uiDC.realTime) { 
     558  qboolean duplicate; 
     559 
     560  if( !force ) 
     561  { 
     562    if( !uiInfo.nextFindPlayerRefresh || uiInfo.nextFindPlayerRefresh > uiInfo.uiDC.realTime ) 
    4699563      return; 
    4700     } 
    4701   } 
    4702   else { 
    4703     memset(&uiInfo.pendingServerStatus, 0, sizeof(uiInfo.pendingServerStatus)); 
     564  } 
     565  else 
     566  { 
     567    memset( &uiInfo.pendingServerStatus, 0, sizeof( uiInfo.pendingServerStatus ) ); 
    4704568    uiInfo.numFoundPlayerServers = 0; 
    4705569    uiInfo.currentFoundPlayerServer = 0; 
    4706     trap_Cvar_VariableStringBuffer( "ui_findPlayer", uiInfo.findPlayerName, sizeof(uiInfo.findPlayerName)); 
    4707     Q_CleanStr(uiInfo.findPlayerName); 
     570    trap_Cvar_VariableStringBuffer( "ui_findPlayer", uiInfo.findPlayerName, sizeof( uiInfo.findPlayerName ) ); 
     571    Q_CleanStr( uiInfo.findPlayerName ); 
    4708572    // should have a string of some length 
    4709     if (!strlen(uiInfo.findPlayerName)) { 
     573 
     574    if( !strlen( uiInfo.findPlayerName ) ) 
     575    { 
    4710576      uiInfo.nextFindPlayerRefresh = 0; 
    4711577      return; 
    4712578    } 
     579 
    4713580    // set resend time 
    4714581    resend = ui_serverStatusTimeOut.integer / 2 - 10; 
    4715     if (resend < 50) { 
     582 
     583    if( resend < 50 ) 
    4716584      resend = 50; 
    4717     } 
    4718     trap_Cvar_Set("cl_serverStatusResendTime", va("%d", resend)); 
     585 
     586    trap_Cvar_Set( "cl_serverStatusResendTime", va( "%d", resend ) ); 
    4719587    // reset all server status requests 
    4720     trap_LAN_ServerStatus( NULL, NULL, 0); 
     588    trap_LAN_ServerStatus( NULL, NULL, 0 ); 
    4721589    // 
    4722590    uiInfo.numFoundPlayerServers = 1; 
    4723     Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
    4724             sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]), 
    4725               "searching %d...", uiInfo.pendingServerStatus.num); 
     591    Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
     592                 sizeof( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1] ), 
     593                 "searching %d...", uiInfo.pendingServerStatus.num ); 
    4726594    numFound = 0; 
    4727595    numTimeOuts++; 
    4728596  } 
    4729   for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) { 
     597 
     598  for( i = 0; i < MAX_SERVERSTATUSREQUESTS; i++ ) 
     599  { 
    4730600    // if this pending server is valid 
    4731     if (uiInfo.pendingServerStatus.server[i].valid) { 
     601 
     602    if( uiInfo.pendingServerStatus.server[i].valid ) 
     603    { 
    4732604      // try to get the server status for this server 
    4733       if (UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, &info ) ) { 
     605 
     606      if( UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, &info ) ) 
     607      { 
    4734608        // 
    4735609        numFound++; 
    4736610        // parse through the server status lines 
    4737         for (j = 0; j < info.numLines; j++) { 
     611 
     612        for( j = 0; j < info.numLines; j++ ) 
     613        { 
    4738614          // should have ping info 
    4739           if ( !info.lines[j][2] || !info.lines[j][2][0] ) { 
     615 
     616          if( !info.lines[j][2] || !info.lines[j][2][0] ) 
    4740617            continue; 
     618 
     619          // clean string first 
     620          Q_strncpyz( name, info.lines[j][3], sizeof( name ) ); 
     621 
     622          Q_CleanStr( name ); 
     623 
     624          duplicate = qfalse; 
     625 
     626          for( k = 0; k < uiInfo.numFoundPlayerServers - 1; k++ ) 
     627          { 
     628            if( Q_strncmp( uiInfo.foundPlayerServerAddresses[ k ], 
     629                           uiInfo.pendingServerStatus.server[ i ].adrstr, 
     630                           MAX_ADDRESSLENGTH ) == 0 ) 
     631              duplicate = qtrue; 
    4741632          } 
    4742           // clean string first 
    4743           Q_strncpyz(name, info.lines[j][3], sizeof(name)); 
    4744           Q_CleanStr(name); 
     633 
    4745634          // if the player name is a substring 
    4746           if (stristr(name, uiInfo.findPlayerName)) { 
     635          if( stristr( name, uiInfo.findPlayerName ) && !duplicate ) 
     636          { 
    4747637            // add to found server list if we have space (always leave space for a line with the number found) 
    4748             if (uiInfo.numFoundPlayerServers < MAX_FOUNDPLAYER_SERVERS-1) { 
     638 
     639            if( uiInfo.numFoundPlayerServers < MAX_FOUNDPLAYER_SERVERS - 1 ) 
     640            { 
    4749641              // 
    4750               Q_strncpyz(uiInfo.foundPlayerServerAddresses[uiInfo.numFoundPlayerServers-1], 
    4751                     uiInfo.pendingServerStatus.server[i].adrstr, 
    4752                       sizeof(uiInfo.foundPlayerServerAddresses[0])); 
    4753               Q_strncpyz(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
    4754                     uiInfo.pendingServerStatus.server[i].name, 
    4755                       sizeof(uiInfo.foundPlayerServerNames[0])); 
     642              Q_strncpyz( uiInfo.foundPlayerServerAddresses[uiInfo.numFoundPlayerServers-1], 
     643                          uiInfo.pendingServerStatus.server[i].adrstr, 
     644                          sizeof( uiInfo.foundPlayerServerAddresses[0] ) ); 
     645              Q_strncpyz( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
     646                          uiInfo.pendingServerStatus.server[i].name, 
     647                          sizeof( uiInfo.foundPlayerServerNames[0] ) ); 
    4756648              uiInfo.numFoundPlayerServers++; 
    4757649            } 
    4758             else { 
     650            else 
     651            { 
    4759652              // can't add any more so we're done 
    4760653              uiInfo.pendingServerStatus.num = uiInfo.serverStatus.numDisplayServers; 
     
    4762655          } 
    4763656        } 
    4764         Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
    4765                 sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]), 
    4766                   "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound); 
     657 
     658        Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
     659                     sizeof( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1] ), 
     660                     "searching %d/%d...", numFound, uiInfo.pendingServerStatus.num ); 
    4767661        // retrieved the server status so reuse this spot 
    4768662        uiInfo.pendingServerStatus.server[i].valid = qfalse; 
    4769663      } 
    4770664    } 
     665 
    4771666    // if empty pending slot or timed out 
    4772     if (!uiInfo.pendingServerStatus.server[i].valid || 
    4773       uiInfo.pendingServerStatus.server[i].startTime < uiInfo.uiDC.realTime - ui_serverStatusTimeOut.integer) { 
    4774       if (uiInfo.pendingServerStatus.server[i].valid) { 
     667    if( !uiInfo.pendingServerStatus.server[i].valid || 
     668         uiInfo.pendingServerStatus.server[i].startTime < uiInfo.uiDC.realTime - ui_serverStatusTimeOut.integer ) 
     669    { 
     670      if( uiInfo.pendingServerStatus.server[i].valid ) 
    4775671        numTimeOuts++; 
    4776       } 
     672 
    4777673      // reset server status request for this address 
    4778674      UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, NULL ); 
     675 
    4779676      // reuse pending slot 
    4780677      uiInfo.pendingServerStatus.server[i].valid = qfalse; 
     678 
    4781679      // if we didn't try to get the status of all servers in the main browser yet 
    4782       if (uiInfo.pendingServerStatus.num < uiInfo.serverStatus.numDisplayServers) { 
     680      if( uiInfo.pendingServerStatus.num < uiInfo.serverStatus.numDisplayServers ) 
     681      { 
    4783682        uiInfo.pendingServerStatus.server[i].startTime = uiInfo.uiDC.realTime; 
    4784         trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], 
    4785               uiInfo.pendingServerStatus.server[i].adrstr, sizeof(uiInfo.pendingServerStatus.server[i].adrstr)); 
    4786         trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], infoString, sizeof(infoString)); 
    4787         Q_strncpyz(uiInfo.pendingServerStatus.server[i].name, Info_ValueForKey(infoString, "hostname"), sizeof(uiInfo.pendingServerStatus.server[0].name)); 
     683        trap_LAN_GetServerAddressString( ui_netSource.integer, 
     684                                         uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], 
     685                                         uiInfo.pendingServerStatus.server[i].adrstr, 
     686                                         sizeof( uiInfo.pendingServerStatus.server[i].adrstr ) ); 
     687 
     688        trap_LAN_GetServerInfo( ui_netSource.integer, 
     689                                uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], 
     690                                infoString, sizeof( infoString ) ); 
     691 
     692        Q_strncpyz( uiInfo.pendingServerStatus.server[i].name, 
     693                    Info_ValueForKey( infoString, "hostname" ), 
     694                    sizeof( uiInfo.pendingServerStatus.server[0].name ) ); 
     695 
    4788696        uiInfo.pendingServerStatus.server[i].valid = qtrue; 
    4789697        uiInfo.pendingServerStatus.num++; 
    4790         Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
    4791                 sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]), 
    4792                   "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound); 
    4793       } 
    4794     } 
    4795   } 
    4796   for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) { 
    4797     if (uiInfo.pendingServerStatus.server[i].valid) { 
     698        Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
     699                     sizeof( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1] ), 
     700                     "searching %d/%d...", numFound, uiInfo.pendingServerStatus.num ); 
     701      } 
     702    } 
     703  } 
     704 
     705  for( i = 0; i < MAX_SERVERSTATUSREQUESTS; i++ ) 
     706  { 
     707    if( uiInfo.pendingServerStatus.server[i].valid ) 
    4798708      break; 
    4799     } 
    4800   } 
     709  } 
     710 
    4801711  // if still trying to retrieve server status info 
    4802   if (i < MAX_SERVERSTATUSREQUESTS) { 
     712  if( i < MAX_SERVERSTATUSREQUESTS ) 
    4803713    uiInfo.nextFindPlayerRefresh = uiInfo.uiDC.realTime + 25; 
    4804   } 
    4805   else { 
     714  else 
     715  { 
    4806716    // add a line that shows the number of servers found 
    4807     if (!uiInfo.numFoundPlayerServers) { 
    4808       Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]), "no servers found"); 
    4809     } 
    4810     else { 
    4811       Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]), 
    4812             "%d server%s found with player %s", uiInfo.numFoundPlayerServers-1, 
    4813             uiInfo.numFoundPlayerServers == 2 ? "":"s", uiInfo.findPlayerName); 
    4814     } 
     717 
     718    if( !uiInfo.numFoundPlayerServers ) 
     719    { 
     720      Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
     721                   sizeof( uiInfo.foundPlayerServerAddresses[0] ), "no servers found" ); 
     722    } 
     723    else 
     724    { 
     725      Com_sprintf( uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], 
     726                   sizeof( uiInfo.foundPlayerServerAddresses[0] ), 
     727                   "%d server%s found with player %s", uiInfo.numFoundPlayerServers - 1, 
     728                   uiInfo.numFoundPlayerServers == 2 ? "" : "s", uiInfo.findPlayerName ); 
     729    } 
     730 
    4815731    uiInfo.nextFindPlayerRefresh = 0; 
    4816732    // show the server status info for the selected server 
    4817     UI_FeederSelection(FEEDER_FINDPLAYER, uiInfo.currentFoundPlayerServer); 
     733    UI_FeederSelection( FEEDER_FINDPLAYER, uiInfo.currentFoundPlayerServer ); 
    4818734  } 
    4819735} 
     
    4824740================== 
    4825741*/ 
    4826 static void UI_BuildServerStatus(qboolean force) { 
    4827  
    4828   if (uiInfo.nextFindPlayerRefresh) { 
     742static void UI_BuildServerStatus( qboolean force ) 
     743{ 
     744  if( uiInfo.nextFindPlayerRefresh ) 
    4829745    return; 
    4830   } 
    4831   if (!force) { 
    4832     if (!uiInfo.nextServerStatusRefresh || uiInfo.nextServerStatusRefresh > uiInfo.uiDC.realTime) { 
     746 
     747  if( !force ) 
     748  { 
     749    if( !uiInfo.nextServerStatusRefresh || uiInfo.nextServerStatusRefresh > uiInfo.uiDC.realTime ) 
    4833750      return; 
    4834     } 
    4835   } 
    4836   else { 
    4837     Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL); 
     751  } 
     752  else 
     753  { 
     754    Menu_SetFeederSelection( NULL, FEEDER_SERVERSTATUS, 0, NULL ); 
    4838755    uiInfo.serverStatusInfo.numLines = 0; 
    4839756    // reset all server status requests 
    4840     trap_LAN_ServerStatus( NULL, NULL, 0); 
    4841   } 
    4842   if (uiInfo.serverStatus.currentServer < 0 || uiInfo.serverStatus.currentServer > uiInfo.serverStatus.numDisplayServers || uiInfo.serverStatus.numDisplayServers == 0) { 
     757    trap_LAN_ServerStatus( NULL, NULL, 0 ); 
     758  } 
     759 
     760  if( uiInfo.serverStatus.currentServer < 0 || 
     761      uiInfo.serverStatus.currentServer > uiInfo.serverStatus.numDisplayServers || 
     762      uiInfo.serverStatus.numDisplayServers == 0 ) 
    4843763    return; 
    4844   } 
    4845   if (UI_GetServerStatusInfo( uiInfo.serverStatusAddress, &uiInfo.serverStatusInfo ) ) { 
     764 
     765  if( UI_GetServerStatusInfo( uiInfo.serverStatusAddress, &uiInfo.serverStatusInfo ) ) 
     766  { 
    4846767    uiInfo.nextServerStatusRefresh = 0; 
    4847768    UI_GetServerStatusInfo( uiInfo.serverStatusAddress, NULL ); 
    4848769  } 
    4849   else { 
     770  else 
    4850771    uiInfo.nextServerStatusRefresh = uiInfo.uiDC.realTime + 500; 
     772} 
     773 
     774/* 
     775================== 
     776UI_BuildServerDisplayList 
     777================== 
     778*/ 
     779static void UI_BuildServerDisplayList( qboolean force ) 
     780{ 
     781  int i, count, clients, maxClients, ping, len, visible; 
     782  char info[MAX_STRING_CHARS]; 
     783  static int numinvisible; 
     784 
     785  if( !( force || uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh ) ) 
     786    return; 
     787 
     788  // if we shouldn't reset 
     789  if( force == 2 ) 
     790    force = 0; 
     791 
     792  // do motd updates here too 
     793  trap_Cvar_VariableStringBuffer( "cl_motdString", uiInfo.serverStatus.motd, sizeof( uiInfo.serverStatus.motd ) ); 
     794 
     795  len = strlen( uiInfo.serverStatus.motd ); 
     796 
     797  if( len != uiInfo.serverStatus.motdLen ) 
     798  { 
     799    uiInfo.serverStatus.motdLen = len; 
     800    uiInfo.serverStatus.motdWidth = -1; 
     801  } 
     802 
     803  if( force ) 
     804  { 
     805    numinvisible = 0; 
     806    // clear number of displayed servers 
     807    uiInfo.serverStatus.numDisplayServers = 0; 
     808    uiInfo.serverStatus.numPlayersOnServers = 0; 
     809    // set list box index to zero 
     810    Menu_SetFeederSelection( NULL, FEEDER_SERVERS, 0, NULL ); 
     811    // mark all servers as visible so we store ping updates for them 
     812    trap_LAN_MarkServerVisible( ui_netSource.integer, -1, qtrue ); 
     813  } 
     814 
     815  // get the server count (comes from the master) 
     816  count = trap_LAN_GetServerCount( ui_netSource.integer ); 
     817 
     818  if( count == -1 || ( ui_netSource.integer == AS_LOCAL && count == 0 ) ) 
     819  { 
     820    // still waiting on a response from the master 
     821    uiInfo.serverStatus.numDisplayServers = 0; 
     822    uiInfo.serverStatus.numPlayersOnServers = 0; 
     823    uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 500; 
     824    return; 
     825  } 
     826 
     827  visible = qfalse; 
     828 
     829  for( i = 0; i < count; i++ ) 
     830  { 
     831    // if we already got info for this server 
     832 
     833    if( !trap_LAN_ServerIsVisible( ui_netSource.integer, i ) ) 
     834      continue; 
     835 
     836    visible = qtrue; 
     837    // get the ping for this server 
     838    ping = trap_LAN_GetServerPing( ui_netSource.integer, i ); 
     839 
     840    if( ping > 0 || ui_netSource.integer == AS_FAVORITES ) 
     841    { 
     842      trap_LAN_GetServerInfo( ui_netSource.integer, i, info, MAX_STRING_CHARS ); 
     843 
     844      clients = atoi( Info_ValueForKey( info, "clients" ) ); 
     845      uiInfo.serverStatus.numPlayersOnServers += clients; 
     846 
     847      if( ui_browserShowEmpty.integer == 0 ) 
     848      { 
     849        if( clients == 0 ) 
     850        { 
     851          trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); 
     852          continue; 
     853        } 
     854      } 
     855 
     856      if( ui_browserShowFull.integer == 0 ) 
     857      { 
     858        maxClients = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); 
     859 
     860        if( clients == maxClients ) 
     861        { 
     862          trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); 
     863          continue; 
     864        } 
     865      } 
     866 
     867      // make sure we never add a favorite server twice 
     868      if( ui_netSource.integer == AS_FAVORITES ) 
     869        UI_RemoveServerFromDisplayList( i ); 
     870 
     871      // insert the server into the list 
     872      UI_BinaryServerInsertion( i ); 
     873 
     874      // done with this server 
     875      if( ping > 0 ) 
     876      { 
     877        trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); 
     878        numinvisible++; 
     879      } 
     880    } 
     881  } 
     882 
     883  uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime; 
     884 
     885  // if there were no servers visible for ping updates 
     886 
     887  if( !visible ) 
     888  { 
     889//    UI_StopServerRefresh(); 
     890//    uiInfo.serverStatus.nextDisplayRefresh = 0; 
     891  } 
     892} 
     893 
     894 
     895/* 
     896================= 
     897UI_StopServerRefresh 
     898================= 
     899*/ 
     900static void UI_StopServerRefresh( void ) 
     901{ 
     902  int count; 
     903 
     904  if( !uiInfo.serverStatus.refreshActive ) 
     905  { 
     906    // not currently refreshing 
     907    return; 
     908  } 
     909 
     910  uiInfo.serverStatus.refreshActive = qfalse; 
     911  Com_Printf( "%d servers listed in browser with %d players.\n", 
     912              uiInfo.serverStatus.numDisplayServers, 
     913              uiInfo.serverStatus.numPlayersOnServers ); 
     914  count = trap_LAN_GetServerCount( ui_netSource.integer ); 
     915 
     916  if( count - uiInfo.serverStatus.numDisplayServers > 0 ) 
     917  { 
     918    Com_Printf( "%d servers not listed due to packet loss or pings higher than %d\n", 
     919                count - uiInfo.serverStatus.numDisplayServers, 
     920                ( int ) trap_Cvar_VariableValue( "cl_maxPing" ) ); 
     921  } 
     922 
     923} 
     924 
     925/* 
     926================= 
     927UI_DoServerRefresh 
     928================= 
     929*/ 
     930static void UI_DoServerRefresh( void ) 
     931{ 
     932  qboolean wait = qfalse; 
     933 
     934  if( !uiInfo.serverStatus.refreshActive ) 
     935    return; 
     936 
     937  if( ui_netSource.integer != AS_FAVORITES ) 
     938  { 
     939    if( ui_netSource.integer == AS_LOCAL ) 
     940    { 
     941      if( !trap_LAN_GetServerCount( ui_netSource.integer ) ) 
     942        wait = qtrue; 
     943    } 
     944    else 
     945    { 
     946      if( trap_LAN_GetServerCount( ui_netSource.integer ) < 0 ) 
     947        wait = qtrue; 
     948    } 
     949  } 
     950 
     951  if( uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime ) 
     952  { 
     953    if( wait ) 
     954      return; 
     955  } 
     956 
     957  // if still trying to retrieve pings 
     958  if( trap_LAN_UpdateVisiblePings( ui_netSource.integer ) ) 
     959    uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; 
     960  else if( !wait ) 
     961  { 
     962    // get the last servers in the list 
     963    UI_BuildServerDisplayList( 2 ); 
     964    // stop the refresh 
     965    UI_StopServerRefresh(); 
     966  } 
     967 
     968  // 
     969  UI_BuildServerDisplayList( qfalse ); 
     970} 
     971 
     972/* 
     973================= 
     974UI_UpdatePendingPings 
     975================= 
     976*/ 
     977static void UI_UpdatePendingPings( void ) 
     978{ 
     979  trap_LAN_ResetPings( ui_netSource.integer ); 
     980  uiInfo.serverStatus.refreshActive = qtrue; 
     981  uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; 
     982 
     983} 
     984 
     985/* 
     986================= 
     987UI_StartServerRefresh 
     988================= 
     989*/ 
     990static void UI_StartServerRefresh( qboolean full ) 
     991{ 
     992  int   i; 
     993  char  *ptr; 
     994  int   time; 
     995  qtime_t q; 
     996 
     997  time = trap_RealTime( &q ); 
     998  trap_Cvar_Set( va( "ui_lastServerRefresh_%i_time", ui_netSource.integer ), 
     999                 va( "%i", time ) ); 
     1000  trap_Cvar_Set( va( "ui_lastServerRefresh_%i", ui_netSource.integer ), 
     1001                 va( "%s-%i, %i at %i:%02i", MonthAbbrev[q.tm_mon], 
     1002                     q.tm_mday, 1900 + q.tm_year, q.tm_hour, q.tm_min ) ); 
     1003 
     1004  if( !full ) 
     1005  { 
     1006    UI_UpdatePendingPings(); 
     1007    return; 
     1008  } 
     1009 
     1010  uiInfo.serverStatus.refreshActive = qtrue; 
     1011  uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 1000; 
     1012  // clear number of displayed servers 
     1013  uiInfo.serverStatus.numDisplayServers = 0; 
     1014  uiInfo.serverStatus.numPlayersOnServers = 0; 
     1015  // mark all servers as visible so we store ping updates for them 
     1016  trap_LAN_MarkServerVisible( ui_netSource.integer, -1, qtrue ); 
     1017  // reset all the pings 
     1018  trap_LAN_ResetPings( ui_netSource.integer ); 
     1019  // 
     1020 
     1021  if( ui_netSource.integer == AS_LOCAL ) 
     1022  { 
     1023    trap_Cmd_ExecuteText( EXEC_NOW, "localservers\n" ); 
     1024    uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; 
     1025    return; 
     1026  } 
     1027 
     1028  uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000; 
     1029 
     1030  if( ui_netSource.integer == AS_GLOBAL || ui_netSource.integer == AS_MPLAYER ) 
     1031  { 
     1032    if( ui_netSource.integer == AS_GLOBAL ) 
     1033      i = 0; 
     1034    else 
     1035      i = 1; 
     1036 
     1037    ptr = UI_Cvar_VariableString( "debug_protocol" ); 
     1038 
     1039    if( strlen( ptr ) ) 
     1040      trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %s full empty\n", i, ptr ) ); 
     1041    else 
     1042    { 
     1043      trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %d full empty\n", i, 
     1044                            (int)trap_Cvar_VariableValue( "protocol" ) ) ); 
     1045    } 
     1046  } 
     1047} 
     1048 
     1049int frameCount = 0; 
     1050int startTime; 
     1051 
     1052#define UI_FPS_FRAMES 4 
     1053void UI_Refresh( int realtime ) 
     1054{ 
     1055  static int index; 
     1056  static int  previousTimes[UI_FPS_FRAMES]; 
     1057 
     1058  //if( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { 
     1059  //  return; 
     1060  //} 
     1061 
     1062  uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime; 
     1063  uiInfo.uiDC.realTime = realtime; 
     1064 
     1065  previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime; 
     1066  index++; 
     1067 
     1068  if( index > UI_FPS_FRAMES ) 
     1069  { 
     1070    int i, total; 
     1071    // average multiple frames together to smooth changes out a bit 
     1072    total = 0; 
     1073 
     1074    for( i = 0 ; i < UI_FPS_FRAMES ; i++ ) 
     1075      total += previousTimes[i]; 
     1076 
     1077    if( !total ) 
     1078      total = 1; 
     1079 
     1080    uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total; 
     1081  } 
     1082 
     1083  UI_UpdateCvars(); 
     1084 
     1085  if( Menu_Count() > 0 ) 
     1086  { 
     1087    // paint all the menus 
     1088    Menu_PaintAll(); 
     1089    // refresh server browser list 
     1090    UI_DoServerRefresh(); 
     1091    // refresh server status 
     1092    UI_BuildServerStatus( qfalse ); 
     1093    // refresh find player list 
     1094    UI_BuildFindPlayerList( qfalse ); 
     1095  } 
     1096 
     1097  // draw cursor 
     1098  UI_SetColor( NULL ); 
     1099 
     1100  if( Menu_Count( ) > 0 && !trap_Cvar_VariableValue( "ui_hideCursor" ) ) 
     1101  { 
     1102    UI_DrawHandlePic( uiInfo.uiDC.cursorx - ( 16.0f * uiInfo.uiDC.aspectScale ), uiInfo.uiDC.cursory - 16.0f, 
     1103                      32.0f * uiInfo.uiDC.aspectScale, 32.0f, uiInfo.uiDC.Assets.cursor ); 
     1104  } 
     1105} 
     1106 
     1107/* 
     1108================= 
     1109UI_Shutdown 
     1110================= 
     1111*/ 
     1112void UI_Shutdown( void ) 
     1113{ 
     1114  trap_LAN_SaveCachedServers(); 
     1115} 
     1116 
     1117qboolean Asset_Parse( int handle ) 
     1118{ 
     1119  pc_token_t token; 
     1120  const char *tempStr; 
     1121 
     1122  if( !trap_Parse_ReadToken( handle, &token ) ) 
     1123    return qfalse; 
     1124 
     1125  if( Q_stricmp( token.string, "{" ) != 0 ) 
     1126    return qfalse; 
     1127 
     1128  while( 1 ) 
     1129  { 
     1130    memset( &token, 0, sizeof( pc_token_t ) ); 
     1131 
     1132    if( !trap_Parse_ReadToken( handle, &token ) ) 
     1133      return qfalse; 
     1134 
     1135    if( Q_stricmp( token.string, "}" ) == 0 ) 
     1136      return qtrue; 
     1137 
     1138    // font 
     1139    if( Q_stricmp( token.string, "font" ) == 0 ) 
     1140    { 
     1141      int pointSize; 
     1142 
     1143      if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) 
     1144        return qfalse; 
     1145 
     1146      trap_R_RegisterFont( tempStr, pointSize, &uiInfo.uiDC.Assets.textFont ); 
     1147      uiInfo.uiDC.Assets.fontRegistered = qtrue; 
     1148      continue; 
     1149    } 
     1150 
     1151    if( Q_stricmp( token.string, "smallFont" ) == 0 ) 
     1152    { 
     1153      int pointSize; 
     1154 
     1155      if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) 
     1156        return qfalse; 
     1157 
     1158      trap_R_RegisterFont( tempStr, pointSize, &uiInfo.uiDC.Assets.smallFont ); 
     1159      continue; 
     1160    } 
     1161 
     1162    if( Q_stricmp( token.string, "bigFont" ) == 0 ) 
     1163    { 
     1164      int pointSize; 
     1165 
     1166      if( !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) 
     1167        return qfalse; 
     1168 
     1169      trap_R_RegisterFont( tempStr, pointSize, &uiInfo.uiDC.Assets.bigFont ); 
     1170      continue; 
     1171    } 
     1172 
     1173 
     1174    // gradientbar 
     1175    if( Q_stricmp( token.string, "gradientbar" ) == 0 ) 
     1176    { 
     1177      if( !PC_String_Parse( handle, &tempStr ) ) 
     1178        return qfalse; 
     1179 
     1180      uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( tempStr ); 
     1181      continue; 
     1182    } 
     1183 
     1184    // enterMenuSound 
     1185    if( Q_stricmp( token.string, "menuEnterSound" ) == 0 ) 
     1186    { 
     1187      if( !PC_String_Parse( handle, &tempStr ) ) 
     1188        return qfalse; 
     1189 
     1190      uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse ); 
     1191      continue; 
     1192    } 
     1193 
     1194    // exitMenuSound 
     1195    if( Q_stricmp( token.string, "menuExitSound" ) == 0 ) 
     1196    { 
     1197      if( !PC_String_Parse( handle, &tempStr ) ) 
     1198        return qfalse; 
     1199 
     1200      uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse ); 
     1201      continue; 
     1202    } 
     1203 
     1204    // itemFocusSound 
     1205    if( Q_stricmp( token.string, "itemFocusSound" ) == 0 ) 
     1206    { 
     1207      if( !PC_String_Parse( handle, &tempStr ) ) 
     1208        return qfalse; 
     1209 
     1210      uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse ); 
     1211      continue; 
     1212    } 
     1213 
     1214    // menuBuzzSound 
     1215    if( Q_stricmp( token.string, "menuBuzzSound" ) == 0 ) 
     1216    { 
     1217      if( !PC_String_Parse( handle, &tempStr ) ) 
     1218        return qfalse; 
     1219 
     1220      uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse ); 
     1221      continue; 
     1222    } 
     1223 
     1224    if( Q_stricmp( token.string, "cursor" ) == 0 ) 
     1225    { 
     1226      if( !PC_String_Parse( handle, &uiInfo.uiDC.Assets.cursorStr ) ) 
     1227        return qfalse; 
     1228 
     1229      uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr ); 
     1230      continue; 
     1231    } 
     1232 
     1233    if( Q_stricmp( token.string, "fadeClamp" ) == 0 ) 
     1234    { 
     1235      if( !PC_Float_Parse( handle, &uiInfo.uiDC.Assets.fadeClamp ) ) 
     1236        return qfalse; 
     1237 
     1238      continue; 
     1239    } 
     1240 
     1241    if( Q_stricmp( token.string, "fadeCycle" ) == 0 ) 
     1242    { 
     1243      if( !PC_Int_Parse( handle, &uiInfo.uiDC.Assets.fadeCycle ) ) 
     1244        return qfalse; 
     1245 
     1246      continue; 
     1247    } 
     1248 
     1249    if( Q_stricmp( token.string, "fadeAmount" ) == 0 ) 
     1250    { 
     1251      if( !PC_Float_Parse( handle, &uiInfo.uiDC.Assets.fadeAmount ) ) 
     1252        return qfalse; 
     1253 
     1254      continue; 
     1255    } 
     1256 
     1257    if( Q_stricmp( token.string, "shadowX" ) == 0 ) 
     1258    { 
     1259      if( !PC_Float_Parse( handle, &uiInfo.uiDC.Assets.shadowX ) ) 
     1260        return qfalse; 
     1261 
     1262      continue; 
     1263    } 
     1264 
     1265    if( Q_stricmp( token.string, "shadowY" ) == 0 ) 
     1266    { 
     1267      if( !PC_Float_Parse( handle, &uiInfo.uiDC.Assets.shadowY ) ) 
     1268        return qfalse; 
     1269 
     1270      continue; 
     1271    } 
     1272 
     1273    if( Q_stricmp( token.string, "shadowColor" ) == 0 ) 
     1274    { 
     1275      if( !PC_Color_Parse( handle, &uiInfo.uiDC.Assets.shadowColor ) ) 
     1276        return qfalse; 
     1277 
     1278      uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3]; 
     1279      continue; 
     1280    } 
     1281 
     1282  } 
     1283 
     1284  return qfalse; 
     1285} 
     1286 
     1287void UI_Report( void ) 
     1288{ 
     1289  String_Report(); 
     1290} 
     1291 
     1292void UI_ParseMenu( const char *menuFile ) 
     1293{ 
     1294  int handle; 
     1295  pc_token_t token; 
     1296 
     1297  handle = trap_Parse_LoadSource( menuFile ); 
     1298 
     1299  if( !handle ) 
     1300    return; 
     1301 
     1302  while( 1 ) 
     1303  { 
     1304    memset( &token, 0, sizeof( pc_token_t ) ); 
     1305 
     1306    if( !trap_Parse_ReadToken( handle, &token ) ) 
     1307      break; 
     1308 
     1309    //if( Q_stricmp( token, "{" ) ) { 
     1310    //  Com_Printf( "Missing { in menu file\n" ); 
     1311    //  break; 
     1312    //} 
     1313 
     1314    //if( menuCount == MAX_MENUS ) { 
     1315    //  Com_Printf( "Too many menus!\n" ); 
     1316    //  break; 
     1317    //} 
     1318 
     1319    if( token.string[0] == '}' ) 
     1320      break; 
     1321 
     1322    if( Q_stricmp( token.string, "assetGlobalDef" ) == 0 ) 
     1323    { 
     1324      if( Asset_Parse( handle ) ) 
     1325        continue; 
     1326      else 
     1327        break; 
     1328    } 
     1329 
     1330    if( Q_stricmp( token.string, "menudef" ) == 0 ) 
     1331    { 
     1332      // start a new menu 
     1333      Menu_New( handle ); 
     1334    } 
     1335  } 
     1336 
     1337  trap_Parse_FreeSource( handle ); 
     1338} 
     1339 
     1340qboolean Load_Menu( int handle ) 
     1341{ 
     1342  pc_token_t token; 
     1343 
     1344  if( !trap_Parse_ReadToken( handle, &token ) ) 
     1345    return qfalse; 
     1346 
     1347  if( token.string[0] != '{' ) 
     1348    return qfalse; 
     1349 
     1350  while( 1 ) 
     1351  { 
     1352    if( !trap_Parse_ReadToken( handle, &token ) ) 
     1353      return qfalse; 
     1354 
     1355    if( token.string[0] == 0 ) 
     1356      return qfalse; 
     1357 
     1358    if( token.string[0] == '}' ) 
     1359      return qtrue; 
     1360 
     1361    UI_ParseMenu( token.string ); 
     1362  } 
     1363 
     1364  return qfalse; 
     1365} 
     1366 
     1367void UI_LoadMenus( const char *menuFile, qboolean reset ) 
     1368{ 
     1369  pc_token_t token; 
     1370  int handle; 
     1371  int start; 
     1372 
     1373  start = trap_Milliseconds(); 
     1374 
     1375  handle = trap_Parse_LoadSource( menuFile ); 
     1376 
     1377  if( !handle ) 
     1378    trap_Error( va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n" ) ); 
     1379 
     1380  if( reset ) 
     1381    Menu_Reset(); 
     1382 
     1383  while( 1 ) 
     1384  { 
     1385    if( !trap_Parse_ReadToken( handle, &token ) ) 
     1386      break; 
     1387 
     1388    if( token.string[0] == 0 || token.string[0] == '}' ) 
     1389      break; 
     1390 
     1391    if( token.string[0] == '}' ) 
     1392      break; 
     1393 
     1394    if( Q_stricmp( token.string, "loadmenu" ) == 0 ) 
     1395    { 
     1396      if( Load_Menu( handle ) ) 
     1397        continue; 
     1398      else 
     1399        break; 
     1400    } 
     1401  } 
     1402 
     1403  Com_Printf( "UI menu load time = %d milli seconds\n", trap_Milliseconds() - start ); 
     1404 
     1405  trap_Parse_FreeSource( handle ); 
     1406} 
     1407 
     1408void UI_Load( void ) 
     1409{ 
     1410  char lastName[1024]; 
     1411  menuDef_t *menu = Menu_GetFocused(); 
     1412 
     1413  if( menu && menu->window.name ) 
     1414    strcpy( lastName, menu->window.name ); 
     1415 
     1416  String_Init(); 
     1417 
     1418  UI_LoadMenus( "ui/menus.txt", qtrue ); 
     1419  UI_LoadMenus( "ui/ingame.txt", qfalse ); 
     1420  UI_LoadMenus( "ui/tremulous.txt", qfalse ); 
     1421  Menus_CloseAll(); 
     1422  Menus_ActivateByName( lastName ); 
     1423 
     1424} 
     1425 
     1426/* 
     1427=============== 
     1428UI_DrawInfoPane 
     1429=============== 
     1430*/ 
     1431static void UI_DrawInfoPane( menuItem_t *item, rectDef_t *rect, float text_x, float text_y, 
     1432                             float scale, int textalign, int textvalign, vec4_t color, int textStyle ) 
     1433{ 
     1434  int         value = 0; 
     1435  const char  *s = ""; 
     1436  char        *string = ""; 
     1437 
     1438  int         class, credits; 
     1439  char        ui_currentClass[ MAX_STRING_CHARS ]; 
     1440 
     1441  trap_Cvar_VariableStringBuffer( "ui_currentClass", ui_currentClass, MAX_STRING_CHARS ); 
     1442 
     1443  sscanf( ui_currentClass, "%d %d", &class, &credits ); 
     1444 
     1445  switch( item->type ) 
     1446  { 
     1447    case INFOTYPE_TEXT: 
     1448      s = item->v.text; 
     1449      break; 
     1450 
     1451    case INFOTYPE_CLASS: 
     1452      value = BG_ClassCanEvolveFromTo( class, item->v.pclass, credits, 0 ); 
     1453 
     1454      if( value < 1 ) 
     1455      { 
     1456        s = va( "%s\n\n%s", 
     1457                BG_FindHumanNameForClassNum( item->v.pclass ), 
     1458                BG_FindInfoForClassNum( item->v.pclass ) ); 
     1459      } 
     1460      else 
     1461      { 
     1462        s = va( "%s\n\n%s\n\nKills: %d", 
     1463                BG_FindHumanNameForClassNum( item->v.pclass ), 
     1464                BG_FindInfoForClassNum( item->v.pclass ), 
     1465                value ); 
     1466      } 
     1467 
     1468      break; 
     1469 
     1470    case INFOTYPE_WEAPON: 
     1471      value = BG_FindPriceForWeapon( item->v.weapon ); 
     1472 
     1473      if( value == 0 ) 
     1474      { 
     1475        s = va( "%s\n\n%s\n\nCredits: Free", 
     1476                BG_FindHumanNameForWeapon( item->v.weapon ), 
     1477                BG_FindInfoForWeapon( item->v.weapon ) ); 
     1478      } 
     1479      else 
     1480      { 
     1481        s = va( "%s\n\n%s\n\nCredits: %d", 
     1482                BG_FindHumanNameForWeapon( item->v.weapon ), 
     1483                BG_FindInfoForWeapon( item->v.weapon ), 
     1484                value ); 
     1485      } 
     1486 
     1487      break; 
     1488 
     1489    case INFOTYPE_UPGRADE: 
     1490      value = BG_FindPriceForUpgrade( item->v.upgrade ); 
     1491 
     1492      if( value == 0 ) 
     1493      { 
     1494        s = va( "%s\n\n%s\n\nCredits: Free", 
     1495                BG_FindHumanNameForUpgrade( item->v.upgrade ), 
     1496                BG_FindInfoForUpgrade( item->v.upgrade ) ); 
     1497      } 
     1498      else 
     1499      { 
     1500        s = va( "%s\n\n%s\n\nCredits: %d", 
     1501                BG_FindHumanNameForUpgrade( item->v.upgrade ), 
     1502                BG_FindInfoForUpgrade( item->v.upgrade ), 
     1503                value ); 
     1504      } 
     1505 
     1506      break; 
     1507 
     1508    case INFOTYPE_BUILDABLE: 
     1509      value = BG_FindBuildPointsForBuildable( item->v.buildable ); 
     1510 
     1511      switch( BG_FindTeamForBuildable( item->v.buildable ) ) 
     1512      { 
     1513        case BIT_ALIENS: 
     1514          string = "Sentience"; 
     1515          break; 
     1516 
     1517        case BIT_HUMANS: 
     1518          string = "Power"; 
     1519          break; 
     1520 
     1521        default: 
     1522          break; 
     1523      } 
     1524 
     1525      if( value == 0 ) 
     1526      { 
     1527        s = va( "%s\n\n%s", 
     1528                BG_FindHumanNameForBuildable( item->v.buildable ), 
     1529                BG_FindInfoForBuildable( item->v.buildable ) ); 
     1530      } 
     1531      else 
     1532      { 
     1533        s = va( "%s\n\n%s\n\n%s: %d", 
     1534                BG_FindHumanNameForBuildable( item->v.buildable ), 
     1535                BG_FindInfoForBuildable( item->v.buildable ), 
     1536                string, value ); 
     1537      } 
     1538 
     1539      break; 
     1540  } 
     1541 
     1542  UI_DrawTextBlock( rect, text_x, text_y, color, scale, 
     1543                    textalign, textvalign, textStyle, s ); 
     1544} 
     1545 
     1546 
     1547static void UI_DrawServerMapPreview( rectDef_t *rect, float scale, vec4_t color ) 
     1548{ 
     1549  if( uiInfo.serverStatus.currentServerCinematic >= 0 ) 
     1550  { 
     1551    trap_CIN_RunCinematic( uiInfo.serverStatus.currentServerCinematic ); 
     1552    trap_CIN_SetExtents( uiInfo.serverStatus.currentServerCinematic, rect->x, rect->y, rect->w, rect->h ); 
     1553    trap_CIN_DrawCinematic( uiInfo.serverStatus.currentServerCinematic ); 
     1554  } 
     1555  else if( uiInfo.serverStatus.currentServerPreview > 0 ) 
     1556    UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.serverStatus.currentServerPreview ); 
     1557  else 
     1558    UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip( "gfx/2d/load_screen" ) ); 
     1559} 
     1560 
     1561static void UI_DrawSelectedMapPreview( rectDef_t *rect, float scale, vec4_t color ) 
     1562{ 
     1563  int map = ui_selectedMap.integer; 
     1564 
     1565  if( map < 0 || map > uiInfo.mapCount ) 
     1566  { 
     1567    ui_selectedMap.integer = 0; 
     1568    trap_Cvar_Set( "ui_selectedMap", "0" ); 
     1569    map = 0; 
     1570  } 
     1571 
     1572  if( uiInfo.mapList[map].cinematic >= -1 ) 
     1573  { 
     1574    if( uiInfo.mapList[map].cinematic == -1 ) 
     1575      uiInfo.mapList[map].cinematic = trap_CIN_PlayCinematic( va( "%s.roq", uiInfo.mapList[map].mapLoadName ), 
     1576                                                              0, 0, 0, 0, ( CIN_loop | CIN_silent ) ); 
     1577 
     1578    if( uiInfo.mapList[map].cinematic >= 0 ) 
     1579    { 
     1580      trap_CIN_RunCinematic( uiInfo.mapList[map].cinematic ); 
     1581      trap_CIN_SetExtents( uiInfo.mapList[map].cinematic, rect->x, rect->y, rect->w, rect->h ); 
     1582      trap_CIN_DrawCinematic( uiInfo.mapList[map].cinematic ); 
     1583    } 
     1584    else 
     1585      uiInfo.mapList[map].cinematic = -2; 
     1586  } 
     1587  else 
     1588  { 
     1589    if( uiInfo.mapList[map].levelShot == -1 ) 
     1590      uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip( uiInfo.mapList[map].imageName ); 
     1591 
     1592    if( uiInfo.mapList[map].levelShot > 0 ) 
     1593      UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.mapList[map].levelShot ); 
     1594    else 
     1595      UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip( "gfx/2d/load_screen" ) ); 
     1596  } 
     1597} 
     1598 
     1599static void UI_DrawSelectedMapName( rectDef_t *rect, float scale, vec4_t color, int textStyle ) 
     1600{ 
     1601  int map = ui_selectedMap.integer; 
     1602 
     1603  if( map >= 0 && map < uiInfo.mapCount ) 
     1604    UI_Text_Paint( rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle ); 
     1605} 
     1606 
     1607static const char *UI_OwnerDrawText( int ownerDraw ) 
     1608{ 
     1609  const char * s = NULL; 
     1610 
     1611  switch( ownerDraw ) 
     1612  { 
     1613    case UI_NETSOURCE: 
     1614      if( ui_netSource.integer < 0 || ui_netSource.integer >= numNetSources ) 
     1615        ui_netSource.integer = 0; 
     1616 
     1617      s = netSources[ui_netSource.integer]; 
     1618      break; 
     1619 
     1620    case UI_KEYBINDSTATUS: 
     1621      if( Display_KeyBindPending() ) 
     1622        s = "Waiting for new key... Press ESCAPE to cancel"; 
     1623      else 
     1624        s = "Press ENTER or CLICK to change, Press BACKSPACE to clear"; 
     1625 
     1626      break; 
     1627 
     1628    case UI_SERVERREFRESHDATE: 
     1629      if( uiInfo.serverStatus.refreshActive ) 
     1630      { 
     1631#define MAX_DOTS 5 
     1632        int numServers = trap_LAN_GetServerCount( ui_netSource.integer ); 
     1633        int numDots = ( uiInfo.uiDC.realTime / 500 ) % ( MAX_DOTS + 1 ); 
     1634        char dots[ MAX_DOTS + 1 ]; 
     1635        int i; 
     1636 
     1637        for( i = 0; i < numDots; i++ ) 
     1638          dots[ i ] = '.'; 
     1639 
     1640        dots[ i ] = '\0'; 
     1641 
     1642        s = numServers < 0 ? va( "Waiting for response%s", dots ) : 
     1643            va( "Getting info for %d servers (ESC to cancel)%s", numServers, dots ); 
     1644      } 
     1645      else 
     1646        s = va( "Refresh Time: %s", UI_Cvar_VariableString( va( "ui_lastServerRefresh_%i", ui_netSource.integer ) ) ); 
     1647 
     1648      break; 
     1649 
     1650    case UI_SERVERMOTD: 
     1651      s = uiInfo.serverStatus.motd; 
     1652      break; 
     1653 
     1654    default: 
     1655      break; 
     1656  } 
     1657 
     1658  return s; 
     1659} 
     1660 
     1661static int UI_OwnerDrawWidth( int ownerDraw, float scale ) 
     1662{ 
     1663  const char * s = NULL; 
     1664 
     1665  switch( ownerDraw ) 
     1666  { 
     1667    case UI_NETSOURCE: 
     1668    case UI_KEYBINDSTATUS: 
     1669    case UI_SERVERREFRESHDATE: 
     1670    case UI_SERVERMOTD: 
     1671      s = UI_OwnerDrawText( ownerDraw ); 
     1672      break; 
     1673 
     1674    default: 
     1675      break; 
     1676  } 
     1677 
     1678  if( s ) 
     1679    return UI_Text_Width( s, scale, 0 ); 
     1680 
     1681  return 0; 
     1682} 
     1683 
     1684/* 
     1685=============== 
     1686UI_BuildPlayerList 
     1687=============== 
     1688*/ 
     1689static void UI_BuildPlayerList( void ) 
     1690{ 
     1691  uiClientState_t cs; 
     1692  int   n, count, team, team2, playerTeamNumber; 
     1693  char  info[MAX_INFO_STRING]; 
     1694 
     1695  trap_GetClientState( &cs ); 
     1696  trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); 
     1697  uiInfo.playerNumber = cs.clientNum; 
     1698  team = atoi( Info_ValueForKey( info, "t" ) ); 
     1699  trap_GetConfigString( CS_SERVERINFO, info, sizeof( info ) ); 
     1700  count = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); 
     1701  uiInfo.playerCount = 0; 
     1702  uiInfo.myTeamCount = 0; 
     1703  uiInfo.myPlayerIndex = 0; 
     1704  playerTeamNumber = 0; 
     1705 
     1706  for( n = 0; n < count; n++ ) 
     1707  { 
     1708    trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); 
     1709 
     1710    if( info[0] ) 
     1711    { 
     1712      BG_ClientListParse( &uiInfo.ignoreList[ uiInfo.playerCount ], 
     1713                          Info_ValueForKey( info, "ig" ) ); 
     1714      Q_strncpyz( uiInfo.rawPlayerNames[uiInfo.playerCount], 
     1715                  Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
     1716      Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], 
     1717                  Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
     1718      Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] ); 
     1719      uiInfo.clientNums[uiInfo.playerCount] = n; 
     1720 
     1721      if( n == uiInfo.playerNumber ) 
     1722        uiInfo.myPlayerIndex = uiInfo.playerCount; 
     1723 
     1724      uiInfo.playerCount++; 
     1725 
     1726      team2 = atoi( Info_ValueForKey( info, "t" ) ); 
     1727 
     1728      if( team2 == team ) 
     1729      { 
     1730        Q_strncpyz( uiInfo.rawTeamNames[uiInfo.myTeamCount], 
     1731                    Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
     1732        Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount], 
     1733                    Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH ); 
     1734        Q_CleanStr( uiInfo.teamNames[uiInfo.myTeamCount] ); 
     1735        uiInfo.teamClientNums[uiInfo.myTeamCount] = n; 
     1736 
     1737        if( uiInfo.playerNumber == n ) 
     1738          playerTeamNumber = uiInfo.myTeamCount; 
     1739 
     1740        uiInfo.myTeamCount++; 
     1741      } 
     1742    } 
     1743  } 
     1744} 
     1745 
     1746static void UI_DrawGLInfo( rectDef_t *rect, float scale, int textalign, int textvalign, 
     1747                           vec4_t color, int textStyle, float text_x, float text_y ) 
     1748{ 
     1749  char      buffer[ 4096 ]; 
     1750 
     1751  Com_sprintf( buffer, sizeof( buffer ), "VENDOR: %s\nVERSION: %s\n" 
     1752               "PIXELFORMAT: color(%d-bits) Z(%d-bits) stencil(%d-bits)\n%s", 
     1753               uiInfo.uiDC.glconfig.vendor_string, uiInfo.uiDC.glconfig.renderer_string, 
     1754               uiInfo.uiDC.glconfig.colorBits, uiInfo.uiDC.glconfig.depthBits, 
     1755               uiInfo.uiDC.glconfig.stencilBits, uiInfo.uiDC.glconfig.extensions_string ); 
     1756 
     1757  UI_DrawTextBlock( rect, text_x, text_y, color, scale, 
     1758                    textalign, textvalign, textStyle, buffer ); 
     1759} 
     1760 
     1761// FIXME: table drive 
     1762// 
     1763static void UI_OwnerDraw( float x, float y, float w, float h, 
     1764                          float text_x, float text_y, int ownerDraw, 
     1765                          int ownerDrawFlags, int align, 
     1766                          int textalign, int textvalign, float special, 
     1767                          float scale, vec4_t color, qhandle_t shader, int textStyle ) 
     1768{ 
     1769  rectDef_t       rect; 
     1770 
     1771  rect.x = x; 
     1772  rect.y = y; 
     1773  rect.w = w; 
     1774  rect.h = h; 
     1775 
     1776  switch( ownerDraw ) 
     1777  { 
     1778    case UI_TEAMINFOPANE: 
     1779      UI_DrawInfoPane( &uiInfo.teamList[ uiInfo.teamIndex ], 
     1780                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1781      break; 
     1782 
     1783    case UI_ACLASSINFOPANE: 
     1784      UI_DrawInfoPane( &uiInfo.alienClassList[ uiInfo.alienClassIndex ], 
     1785                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1786      break; 
     1787 
     1788    case UI_AUPGRADEINFOPANE: 
     1789      UI_DrawInfoPane( &uiInfo.alienUpgradeList[ uiInfo.alienUpgradeIndex ], 
     1790                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1791      break; 
     1792 
     1793    case UI_HITEMINFOPANE: 
     1794      UI_DrawInfoPane( &uiInfo.humanItemList[ uiInfo.humanItemIndex ], 
     1795                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1796      break; 
     1797 
     1798    case UI_HBUYINFOPANE: 
     1799      UI_DrawInfoPane( &uiInfo.humanArmouryBuyList[ uiInfo.humanArmouryBuyIndex ], 
     1800                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1801      break; 
     1802 
     1803    case UI_HSELLINFOPANE: 
     1804      UI_DrawInfoPane( &uiInfo.humanArmourySellList[ uiInfo.humanArmourySellIndex ], 
     1805                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1806      break; 
     1807 
     1808    case UI_ABUILDINFOPANE: 
     1809      UI_DrawInfoPane( &uiInfo.alienBuildList[ uiInfo.alienBuildIndex ], 
     1810                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1811      break; 
     1812 
     1813    case UI_HBUILDINFOPANE: 
     1814      UI_DrawInfoPane( &uiInfo.humanBuildList[ uiInfo.humanBuildIndex ], 
     1815                       &rect, text_x, text_y, scale, textalign, textvalign, color, textStyle ); 
     1816      break; 
     1817 
     1818    case UI_NETMAPPREVIEW: 
     1819      UI_DrawServerMapPreview( &rect, scale, color ); 
     1820      break; 
     1821 
     1822    case UI_SELECTEDMAPPREVIEW: 
     1823      UI_DrawSelectedMapPreview( &rect, scale, color ); 
     1824      break; 
     1825 
     1826    case UI_SELECTEDMAPNAME: 
     1827      UI_DrawSelectedMapName( &rect, scale, color, textStyle ); 
     1828      break; 
     1829 
     1830    case UI_GLINFO: 
     1831      UI_DrawGLInfo( &rect, scale, textalign, textvalign, color, textStyle, text_x, text_y ); 
     1832      break; 
     1833 
     1834    default: 
     1835      break; 
     1836  } 
     1837 
     1838} 
     1839 
     1840static qboolean UI_OwnerDrawVisible( int flags ) 
     1841{ 
     1842  qboolean vis = qtrue; 
     1843  uiClientState_t cs; 
     1844  pTeam_t         team; 
     1845  char            info[ MAX_INFO_STRING ]; 
     1846 
     1847  trap_GetClientState( &cs ); 
     1848  trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); 
     1849  team = atoi( Info_ValueForKey( info, "t" ) ); 
     1850 
     1851 
     1852  while( flags ) 
     1853  { 
     1854    if( flags & UI_SHOW_NOTSPECTATING ) 
     1855    { 
     1856      if( team == PTE_NONE ) 
     1857        vis = qfalse; 
     1858 
     1859      flags &= ~UI_SHOW_NOTSPECTATING; 
     1860    } 
     1861 
     1862    if( flags & UI_SHOW_VOTEACTIVE ) 
     1863    { 
     1864      if( !trap_Cvar_VariableValue( "ui_voteActive" ) ) 
     1865        vis = qfalse; 
     1866 
     1867      flags &= ~UI_SHOW_VOTEACTIVE; 
     1868    } 
     1869 
     1870    if( flags & UI_SHOW_CANVOTE ) 
     1871    { 
     1872      if( trap_Cvar_VariableValue( "ui_voteActive" ) ) 
     1873        vis = qfalse; 
     1874 
     1875      flags &= ~UI_SHOW_CANVOTE; 
     1876    } 
     1877 
     1878    if( flags & UI_SHOW_TEAMVOTEACTIVE ) 
     1879    { 
     1880      if( team == PTE_ALIENS ) 
     1881      { 
     1882        if( !trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) ) 
     1883          vis = qfalse; 
     1884      } 
     1885      else if( team == PTE_HUMANS ) 
     1886      { 
     1887        if( !trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) ) 
     1888          vis = qfalse; 
     1889      } 
     1890 
     1891      flags &= ~UI_SHOW_TEAMVOTEACTIVE; 
     1892    } 
     1893 
     1894    if( flags & UI_SHOW_CANTEAMVOTE ) 
     1895    { 
     1896      if( team == PTE_ALIENS ) 
     1897      { 
     1898        if( trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) ) 
     1899          vis = qfalse; 
     1900      } 
     1901      else if( team == PTE_HUMANS ) 
     1902      { 
     1903        if( trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) ) 
     1904          vis = qfalse; 
     1905      } 
     1906 
     1907      flags &= ~UI_SHOW_CANTEAMVOTE; 
     1908    } 
     1909 
     1910    if( flags & UI_SHOW_FAVORITESERVERS ) 
     1911    { 
     1912      // this assumes you only put this type of display flag on something showing in the proper context 
     1913 
     1914      if( ui_netSource.integer != AS_FAVORITES ) 
     1915        vis = qfalse; 
     1916 
     1917      flags &= ~UI_SHOW_FAVORITESERVERS; 
     1918    } 
     1919 
     1920    if( flags & UI_SHOW_NOTFAVORITESERVERS ) 
     1921    { 
     1922      // this assumes you only put this type of display flag on something showing in the proper context 
     1923 
     1924      if( ui_netSource.integer == AS_FAVORITES ) 
     1925        vis = qfalse; 
     1926 
     1927      flags &= ~UI_SHOW_NOTFAVORITESERVERS; 
     1928    } 
     1929    else 
     1930      flags = 0; 
     1931  } 
     1932 
     1933  return vis; 
     1934} 
     1935 
     1936static qboolean UI_NetSource_HandleKey( int flags, float *special, int key ) 
     1937{ 
     1938  if( key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER ) 
     1939  { 
     1940    if( key == K_MOUSE2 ) 
     1941    { 
     1942      ui_netSource.integer--; 
     1943 
     1944      if( ui_netSource.integer == AS_MPLAYER ) 
     1945        ui_netSource.integer--; 
     1946    } 
     1947    else 
     1948    { 
     1949      ui_netSource.integer++; 
     1950 
     1951      if( ui_netSource.integer == AS_MPLAYER ) 
     1952        ui_netSource.integer++; 
     1953    } 
     1954 
     1955    if( ui_netSource.integer >= numNetSources ) 
     1956      ui_netSource.integer = 0; 
     1957    else if( ui_netSource.integer < 0 ) 
     1958      ui_netSource.integer = numNetSources - 1; 
     1959 
     1960    UI_BuildServerDisplayList( qtrue ); 
     1961 
     1962    if( ui_netSource.integer != AS_GLOBAL ) 
     1963      UI_StartServerRefresh( qtrue ); 
     1964 
     1965    trap_Cvar_Set( "ui_netSource", va( "%d", ui_netSource.integer ) ); 
     1966    return qtrue; 
     1967  } 
     1968 
     1969  return qfalse; 
     1970} 
     1971 
     1972static qboolean UI_OwnerDrawHandleKey( int ownerDraw, int flags, float *special, int key ) 
     1973{ 
     1974  switch( ownerDraw ) 
     1975  { 
     1976    case UI_NETSOURCE: 
     1977      UI_NetSource_HandleKey( flags, special, key ); 
     1978      break; 
     1979 
     1980    default: 
     1981      break; 
     1982  } 
     1983 
     1984  return qfalse; 
     1985} 
     1986 
     1987 
     1988/* 
     1989================= 
     1990UI_ServersQsortCompare 
     1991================= 
     1992*/ 
     1993static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ) 
     1994{ 
     1995  return trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, 
     1996                                  uiInfo.serverStatus.sortDir, *( int* )arg1, *( int* )arg2 ); 
     1997} 
     1998 
     1999 
     2000/* 
     2001================= 
     2002UI_ServersSort 
     2003================= 
     2004*/ 
     2005void UI_ServersSort( int column, qboolean force ) 
     2006{ 
     2007  if( !force ) 
     2008  { 
     2009    if( uiInfo.serverStatus.sortKey == column ) 
     2010      return; 
     2011  } 
     2012 
     2013  uiInfo.serverStatus.sortKey = column; 
     2014  qsort( &uiInfo.serverStatus.displayServers[0], uiInfo.serverStatus.numDisplayServers, 
     2015          sizeof( int ), UI_ServersQsortCompare ); 
     2016} 
     2017 
     2018 
     2019/* 
     2020=============== 
     2021UI_GetCurrentAlienStage 
     2022=============== 
     2023*/ 
     2024static stage_t UI_GetCurrentAlienStage( void ) 
     2025{ 
     2026  char    buffer[ MAX_TOKEN_CHARS ]; 
     2027  stage_t stage, dummy; 
     2028 
     2029  trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) ); 
     2030  sscanf( buffer, "%d %d", ( int * ) & stage , ( int * ) & dummy ); 
     2031 
     2032  return stage; 
     2033} 
     2034 
     2035/* 
     2036=============== 
     2037UI_GetCurrentHumanStage 
     2038=============== 
     2039*/ 
     2040static stage_t UI_GetCurrentHumanStage( void ) 
     2041{ 
     2042  char    buffer[ MAX_TOKEN_CHARS ]; 
     2043  stage_t stage, dummy; 
     2044 
     2045  trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) ); 
     2046  sscanf( buffer, "%d %d", ( int * ) & dummy, ( int * ) & stage ); 
     2047 
     2048  return stage; 
     2049} 
     2050 
     2051/* 
     2052=============== 
     2053UI_LoadTeams 
     2054=============== 
     2055*/ 
     2056static void UI_LoadTeams( void ) 
     2057{ 
     2058  uiInfo.teamCount = 4; 
     2059 
     2060  uiInfo.teamList[ 0 ].text = String_Alloc( "Aliens" ); 
     2061  uiInfo.teamList[ 0 ].cmd = String_Alloc( "cmd team aliens\n" ); 
     2062  uiInfo.teamList[ 0 ].type = INFOTYPE_TEXT; 
     2063  uiInfo.teamList[ 0 ].v.text = 
     2064    "The Alien Team\n\n" 
     2065    "The Aliens' strengths are in movement and the ability to " 
     2066    "quickly construct new bases quickly. They possess a range " 
     2067    "of abilities including basic melee attacks, movement-" 
     2068    "crippling poisons and more."; 
     2069 
     2070  uiInfo.teamList[ 1 ].text = String_Alloc( "Humans" ); 
     2071  uiInfo.teamList[ 1 ].cmd = String_Alloc( "cmd team humans\n" ); 
     2072  uiInfo.teamList[ 1 ].type = INFOTYPE_TEXT; 
     2073  uiInfo.teamList[ 1 ].v.text = 
     2074    "The Human Team\n\n" 
     2075    "The humans are the masters of technology. Although their " 
     2076    "bases take long to construct, their automated defense " 
     2077    "ensures they stay built. A wide range of upgrades and " 
     2078    "weapons are available to the humans, each contributing " 
     2079    "to eradicate the alien threat."; 
     2080 
     2081  uiInfo.teamList[ 2 ].text = String_Alloc( "Spectate" ); 
     2082  uiInfo.teamList[ 2 ].cmd = String_Alloc( "cmd team spectate\n" ); 
     2083  uiInfo.teamList[ 2 ].type = INFOTYPE_TEXT; 
     2084  uiInfo.teamList[ 2 ].v.text = "Watch the game without playing."; 
     2085 
     2086  uiInfo.teamList[ 3 ].text = String_Alloc( "Auto select" ); 
     2087  uiInfo.teamList[ 3 ].cmd = String_Alloc( "cmd team auto\n" ); 
     2088  uiInfo.teamList[ 3 ].type = INFOTYPE_TEXT; 
     2089  uiInfo.teamList[ 3 ].v.text = "Join the team with the least players."; 
     2090} 
     2091 
     2092/* 
     2093=============== 
     2094UI_AddClass 
     2095=============== 
     2096*/ 
     2097 
     2098static void UI_AddClass( pClass_t class ) 
     2099{ 
     2100  uiInfo.alienClassList[ uiInfo.alienClassCount ].text = 
     2101 
     2102    String_Alloc( BG_FindHumanNameForClassNum( class ) ); 
     2103  uiInfo.alienClassList[ uiInfo.alienClassCount ].cmd = 
     2104 
     2105    String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( class ) ) ); 
     2106  uiInfo.alienClassList[ uiInfo.alienClassCount ].type = INFOTYPE_CLASS; 
     2107 
     2108  uiInfo.alienClassList[ uiInfo.alienClassCount ].v.pclass = class; 
     2109 
     2110  uiInfo.alienClassCount++; 
     2111} 
     2112 
     2113/* 
     2114=============== 
     2115UI_LoadAlienClasses 
     2116=============== 
     2117*/ 
     2118static void UI_LoadAlienClasses( void ) 
     2119{ 
     2120  uiInfo.alienClassCount = 0; 
     2121 
     2122  if( BG_ClassIsAllowed( PCL_ALIEN_LEVEL0 ) ) 
     2123    UI_AddClass( PCL_ALIEN_LEVEL0 ); 
     2124 
     2125  if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0_UPG ) && 
     2126      BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, UI_GetCurrentAlienStage( ) ) ) 
     2127    UI_AddClass( PCL_ALIEN_BUILDER0_UPG ); 
     2128  else if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) ) 
     2129    UI_AddClass( PCL_ALIEN_BUILDER0 ); 
     2130} 
     2131 
     2132/* 
     2133=============== 
     2134UI_AddItem 
     2135=============== 
     2136*/ 
     2137static void UI_AddItem( weapon_t weapon ) 
     2138{ 
     2139  uiInfo.humanItemList[ uiInfo.humanItemCount ].text = 
     2140    String_Alloc( BG_FindHumanNameForWeapon( weapon ) ); 
     2141  uiInfo.humanItemList[ uiInfo.humanItemCount ].cmd = 
     2142    String_Alloc( va( "cmd class %s\n", BG_FindNameForWeapon( weapon ) ) ); 
     2143  uiInfo.humanItemList[ uiInfo.humanItemCount ].type = INFOTYPE_WEAPON; 
     2144  uiInfo.humanItemList[ uiInfo.humanItemCount ].v.weapon = weapon; 
     2145 
     2146  uiInfo.humanItemCount++; 
     2147} 
     2148 
     2149/* 
     2150=============== 
     2151UI_LoadHumanItems 
     2152=============== 
     2153*/ 
     2154static void UI_LoadHumanItems( void ) 
     2155{ 
     2156  uiInfo.humanItemCount = 0; 
     2157 
     2158  if( BG_WeaponIsAllowed( WP_MACHINEGUN ) ) 
     2159    UI_AddItem( WP_MACHINEGUN ); 
     2160 
     2161  if( BG_WeaponIsAllowed( WP_HBUILD2 ) && 
     2162      BG_FindStagesForWeapon( WP_HBUILD2, UI_GetCurrentHumanStage( ) ) ) 
     2163    UI_AddItem( WP_HBUILD2 ); 
     2164  else if( BG_WeaponIsAllowed( WP_HBUILD ) ) 
     2165    UI_AddItem( WP_HBUILD ); 
     2166} 
     2167 
     2168/* 
     2169=============== 
     2170UI_ParseCarriageList 
     2171=============== 
     2172*/ 
     2173static void UI_ParseCarriageList( void ) 
     2174{ 
     2175  int  i; 
     2176  char carriageCvar[ MAX_TOKEN_CHARS ]; 
     2177  char *iterator; 
     2178  char buffer[ MAX_TOKEN_CHARS ]; 
     2179  char *bufPointer; 
     2180 
     2181  trap_Cvar_VariableStringBuffer( "ui_carriage", carriageCvar, sizeof( carriageCvar ) ); 
     2182  iterator = carriageCvar; 
     2183 
     2184  uiInfo.weapons = 0; 
     2185  uiInfo.upgrades = 0; 
     2186 
     2187  //simple parser to give rise to weapon/upgrade list 
     2188 
     2189  while( iterator && iterator[ 0 ] != '$' ) 
     2190  { 
     2191    bufPointer = buffer; 
     2192 
     2193    if( iterator[ 0 ] == 'W' ) 
     2194    { 
     2195      iterator++; 
     2196 
     2197      while( iterator[ 0 ] != ' ' ) 
     2198        * bufPointer++ = *iterator++; 
     2199 
     2200      *bufPointer++ = '\n'; 
     2201 
     2202      i = atoi( buffer ); 
     2203 
     2204      uiInfo.weapons |= ( 1 << i ); 
     2205    } 
     2206    else if( iterator[ 0 ] == 'U' ) 
     2207    { 
     2208      iterator++; 
     2209 
     2210      while( iterator[ 0 ] != ' ' ) 
     2211        * bufPointer++ = *iterator++; 
     2212 
     2213      *bufPointer++ = '\n'; 
     2214 
     2215      i = atoi( buffer ); 
     2216 
     2217      uiInfo.upgrades |= ( 1 << i ); 
     2218    } 
     2219 
     2220    iterator++; 
     2221  } 
     2222} 
     2223 
     2224/* 
     2225=============== 
     2226UI_LoadHumanArmouryBuys 
     2227=============== 
     2228*/ 
     2229static void UI_LoadHumanArmouryBuys( void ) 
     2230{ 
     2231  int i, j = 0; 
     2232  stage_t stage = UI_GetCurrentHumanStage( ); 
     2233  int slots = 0; 
     2234 
     2235  UI_ParseCarriageList( ); 
     2236 
     2237  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
     2238  { 
     2239    if( uiInfo.weapons & ( 1 << i ) ) 
     2240      slots |= BG_FindSlotsForWeapon( i ); 
     2241  } 
     2242 
     2243  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
     2244  { 
     2245    if( uiInfo.upgrades & ( 1 << i ) ) 
     2246      slots |= BG_FindSlotsForUpgrade( i ); 
     2247  } 
     2248 
     2249  uiInfo.humanArmouryBuyCount = 0; 
     2250 
     2251  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
     2252  { 
     2253    if( BG_FindTeamForWeapon( i ) == WUT_HUMANS && 
     2254        BG_FindPurchasableForWeapon( i ) && 
     2255        BG_FindStagesForWeapon( i, stage ) && 
     2256        BG_WeaponIsAllowed( i ) && 
     2257        !( BG_FindSlotsForWeapon( i ) & slots ) && 
     2258        !( uiInfo.weapons & ( 1 << i ) ) ) 
     2259    { 
     2260      uiInfo.humanArmouryBuyList[ j ].text = 
     2261        String_Alloc( BG_FindHumanNameForWeapon( i ) ); 
     2262      uiInfo.humanArmouryBuyList[ j ].cmd = 
     2263        String_Alloc( va( "cmd buy %s\n", BG_FindNameForWeapon( i ) ) ); 
     2264      uiInfo.humanArmouryBuyList[ j ].type = INFOTYPE_WEAPON; 
     2265      uiInfo.humanArmouryBuyList[ j ].v.weapon = i; 
     2266 
     2267      j++; 
     2268 
     2269      uiInfo.humanArmouryBuyCount++; 
     2270    } 
     2271  } 
     2272 
     2273  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
     2274  { 
     2275    if( BG_FindTeamForUpgrade( i ) == WUT_HUMANS && 
     2276        BG_FindPurchasableForUpgrade( i ) && 
     2277        BG_FindStagesForUpgrade( i, stage ) && 
     2278        BG_UpgradeIsAllowed( i ) && 
     2279        !( BG_FindSlotsForUpgrade( i ) & slots ) && 
     2280        !( uiInfo.upgrades & ( 1 << i ) ) ) 
     2281    { 
     2282      uiInfo.humanArmouryBuyList[ j ].text = 
     2283        String_Alloc( BG_FindHumanNameForUpgrade( i ) ); 
     2284      uiInfo.humanArmouryBuyList[ j ].cmd = 
     2285        String_Alloc( va( "cmd buy %s\n", BG_FindNameForUpgrade( i ) ) ); 
     2286      uiInfo.humanArmouryBuyList[ j ].type = INFOTYPE_UPGRADE; 
     2287      uiInfo.humanArmouryBuyList[ j ].v.upgrade = i; 
     2288 
     2289      j++; 
     2290 
     2291      uiInfo.humanArmouryBuyCount++; 
     2292    } 
     2293  } 
     2294} 
     2295 
     2296/* 
     2297=============== 
     2298UI_LoadHumanArmourySells 
     2299=============== 
     2300*/ 
     2301static void UI_LoadHumanArmourySells( void ) 
     2302{ 
     2303  int i, j = 0; 
     2304 
     2305  uiInfo.humanArmourySellCount = 0; 
     2306  UI_ParseCarriageList( ); 
     2307 
     2308  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ ) 
     2309  { 
     2310    if( uiInfo.weapons & ( 1 << i ) ) 
     2311    { 
     2312      uiInfo.humanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForWeapon( i ) ); 
     2313      uiInfo.humanArmourySellList[ j ].cmd = 
     2314        String_Alloc( va( "cmd sell %s\n", BG_FindNameForWeapon( i ) ) ); 
     2315      uiInfo.humanArmourySellList[ j ].type = INFOTYPE_WEAPON; 
     2316      uiInfo.humanArmourySellList[ j ].v.weapon = i; 
     2317 
     2318      j++; 
     2319 
     2320      uiInfo.humanArmourySellCount++; 
     2321    } 
     2322  } 
     2323 
     2324  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) 
     2325  { 
     2326    if( uiInfo.upgrades & ( 1 << i ) ) 
     2327    { 
     2328      uiInfo.humanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForUpgrade( i ) ); 
     2329      uiInfo.humanArmourySellList[ j ].cmd = 
     2330        String_Alloc( va( "cmd sell %s\n", BG_FindNameForUpgrade( i ) ) ); 
     2331      uiInfo.humanArmourySellList[ j ].type = INFOTYPE_UPGRADE; 
     2332      uiInfo.humanArmourySellList[ j ].v.upgrade = i; 
     2333 
     2334      j++; 
     2335 
     2336      uiInfo.humanArmourySellCount++; 
     2337    } 
     2338  } 
     2339} 
     2340 
     2341/* 
     2342=============== 
     2343UI_ArmouryRefreshCb 
     2344=============== 
     2345*/ 
     2346static void UI_ArmouryRefreshCb( void *data ) 
     2347{ 
     2348  int oldWeapons  = uiInfo.weapons; 
     2349  int oldUpgrades = uiInfo.upgrades; 
     2350 
     2351  UI_ParseCarriageList( ); 
     2352 
     2353  if( uiInfo.weapons != oldWeapons || uiInfo.upgrades != oldUpgrades ) 
     2354  { 
     2355    UI_LoadHumanArmouryBuys( ); 
     2356    UI_LoadHumanArmourySells( ); 
     2357    UI_RemoveCaptureFunc( ); 
     2358  } 
     2359} 
     2360 
     2361/* 
     2362=============== 
     2363UI_LoadAlienUpgrades 
     2364=============== 
     2365*/ 
     2366static void UI_LoadAlienUpgrades( void ) 
     2367{ 
     2368  int     i, j = 0; 
     2369 
     2370  int     class, credits; 
     2371  char    ui_currentClass[ MAX_STRING_CHARS ]; 
     2372  stage_t stage = UI_GetCurrentAlienStage( ); 
     2373 
     2374  trap_Cvar_VariableStringBuffer( "ui_currentClass", ui_currentClass, MAX_STRING_CHARS ); 
     2375 
     2376  sscanf( ui_currentClass, "%d %d", &class, &credits ); 
     2377 
     2378  uiInfo.alienUpgradeCount = 0; 
     2379 
     2380  for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ ) 
     2381  { 
     2382    if( BG_ClassCanEvolveFromTo( class, i, credits, 0 ) >= 0 && 
     2383        BG_FindStagesForClass( i, stage ) && 
     2384        BG_ClassIsAllowed( i ) ) 
     2385    { 
     2386      uiInfo.alienUpgradeList[ j ].text = String_Alloc( BG_FindHumanNameForClassNum( i ) ); 
     2387      uiInfo.alienUpgradeList[ j ].cmd = 
     2388        String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( i ) ) ); 
     2389      uiInfo.alienUpgradeList[ j ].type = INFOTYPE_CLASS; 
     2390      uiInfo.alienUpgradeList[ j ].v.pclass = i; 
     2391 
     2392      j++; 
     2393 
     2394      uiInfo.alienUpgradeCount++; 
     2395    } 
     2396  } 
     2397} 
     2398 
     2399/* 
     2400=============== 
     2401UI_LoadAlienBuilds 
     2402=============== 
     2403*/ 
     2404static void UI_LoadAlienBuilds( void ) 
     2405{ 
     2406  int     i, j = 0; 
     2407  stage_t stage; 
     2408 
     2409  UI_ParseCarriageList( ); 
     2410  stage = UI_GetCurrentAlienStage( ); 
     2411 
     2412  uiInfo.alienBuildCount = 0; 
     2413 
     2414  for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ ) 
     2415  { 
     2416    if( BG_FindTeamForBuildable( i ) == BIT_ALIENS && 
     2417        BG_FindBuildWeaponForBuildable( i ) & uiInfo.weapons && 
     2418        BG_FindStagesForBuildable( i, stage ) && 
     2419        BG_BuildableIsAllowed( i ) ) 
     2420    { 
     2421      uiInfo.alienBuildList[ j ].text = 
     2422        String_Alloc( BG_FindHumanNameForBuildable( i ) ); 
     2423      uiInfo.alienBuildList[ j ].cmd = 
     2424        String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) ); 
     2425      uiInfo.alienBuildList[ j ].type = INFOTYPE_BUILDABLE; 
     2426      uiInfo.alienBuildList[ j ].v.buildable = i; 
     2427 
     2428      j++; 
     2429 
     2430      uiInfo.alienBuildCount++; 
     2431    } 
     2432  } 
     2433} 
     2434 
     2435/* 
     2436=============== 
     2437UI_LoadHumanBuilds 
     2438=============== 
     2439*/ 
     2440static void UI_LoadHumanBuilds( void ) 
     2441{ 
     2442  int     i, j = 0; 
     2443  stage_t stage; 
     2444 
     2445  UI_ParseCarriageList( ); 
     2446  stage = UI_GetCurrentHumanStage( ); 
     2447 
     2448  uiInfo.humanBuildCount = 0; 
     2449 
     2450  for( i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++ ) 
     2451  { 
     2452    if( BG_FindTeamForBuildable( i ) == BIT_HUMANS && 
     2453        BG_FindBuildWeaponForBuildable( i ) & uiInfo.weapons && 
     2454        BG_FindStagesForBuildable( i, stage ) && 
     2455        BG_BuildableIsAllowed( i ) ) 
     2456    { 
     2457      uiInfo.humanBuildList[ j ].text = 
     2458        String_Alloc( BG_FindHumanNameForBuildable( i ) ); 
     2459      uiInfo.humanBuildList[ j ].cmd = 
     2460        String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) ); 
     2461      uiInfo.humanBuildList[ j ].type = INFOTYPE_BUILDABLE; 
     2462      uiInfo.humanBuildList[ j ].v.buildable = i; 
     2463 
     2464      j++; 
     2465 
     2466      uiInfo.humanBuildCount++; 
     2467    } 
     2468  } 
     2469} 
     2470 
     2471/* 
     2472=============== 
     2473UI_LoadMods 
     2474=============== 
     2475*/ 
     2476static void UI_LoadMods( void ) 
     2477{ 
     2478  int   numdirs; 
     2479  char  dirlist[2048]; 
     2480  char  *dirptr; 
     2481  char  *descptr; 
     2482  int   i; 
     2483  int   dirlen; 
     2484 
     2485  uiInfo.modCount = 0; 
     2486  numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof( dirlist ) ); 
     2487  dirptr  = dirlist; 
     2488 
     2489  for( i = 0; i < numdirs; i++ ) 
     2490  { 
     2491    dirlen = strlen( dirptr ) + 1; 
     2492    descptr = dirptr + dirlen; 
     2493    uiInfo.modList[uiInfo.modCount].modName = String_Alloc( dirptr ); 
     2494    uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc( descptr ); 
     2495    dirptr += dirlen + strlen( descptr ) + 1; 
     2496    uiInfo.modCount++; 
     2497 
     2498    if( uiInfo.modCount >= MAX_MODS ) 
     2499      break; 
     2500  } 
     2501 
     2502} 
     2503 
     2504 
     2505/* 
     2506=============== 
     2507UI_LoadMovies 
     2508=============== 
     2509*/ 
     2510static void UI_LoadMovies( void ) 
     2511{ 
     2512  char  movielist[4096]; 
     2513  char  *moviename; 
     2514  int   i, len; 
     2515 
     2516  uiInfo.movieCount = trap_FS_GetFileList( "video", "roq", movielist, 4096 ); 
     2517 
     2518  if( uiInfo.movieCount ) 
     2519  { 
     2520    if( uiInfo.movieCount > MAX_MOVIES ) 
     2521      uiInfo.movieCount = MAX_MOVIES; 
     2522 
     2523    moviename = movielist; 
     2524 
     2525    for( i = 0; i < uiInfo.movieCount; i++ ) 
     2526    { 
     2527      len = strlen( moviename ); 
     2528 
     2529      if( !Q_stricmp( moviename +  len - 4, ".roq" ) ) 
     2530        moviename[len-4] = '\0'; 
     2531 
     2532      Q_strupr( moviename ); 
     2533      uiInfo.movieList[i] = String_Alloc( moviename ); 
     2534      moviename += len + 1; 
     2535    } 
     2536  } 
     2537 
     2538} 
     2539 
     2540 
     2541 
     2542/* 
     2543=============== 
     2544UI_LoadDemos 
     2545=============== 
     2546*/ 
     2547static void UI_LoadDemos( void ) 
     2548{ 
     2549  char  demolist[4096]; 
     2550  char demoExt[32]; 
     2551  char  *demoname; 
     2552  int   i, len; 
     2553 
     2554  Com_sprintf( demoExt, sizeof( demoExt ), "dm_%d", ( int )trap_Cvar_VariableValue( "protocol" ) ); 
     2555 
     2556  uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 ); 
     2557 
     2558  Com_sprintf( demoExt, sizeof( demoExt ), ".dm_%d", ( int )trap_Cvar_VariableValue( "protocol" ) ); 
     2559 
     2560  if( uiInfo.demoCount ) 
     2561  { 
     2562    if( uiInfo.demoCount > MAX_DEMOS ) 
     2563      uiInfo.demoCount = MAX_DEMOS; 
     2564 
     2565    demoname = demolist; 
     2566 
     2567    for( i = 0; i < uiInfo.demoCount; i++ ) 
     2568    { 
     2569      len = strlen( demoname ); 
     2570 
     2571      if( !Q_stricmp( demoname +  len - strlen( demoExt ), demoExt ) ) 
     2572        demoname[len-strlen( demoExt )] = '\0'; 
     2573 
     2574      Q_strupr( demoname ); 
     2575      uiInfo.demoList[i] = String_Alloc( demoname ); 
     2576      demoname += len + 1; 
     2577    } 
     2578  } 
     2579 
     2580} 
     2581 
     2582static void UI_Update( const char *name ) 
     2583{ 
     2584  int val = trap_Cvar_VariableValue( name ); 
     2585 
     2586  if( Q_stricmp( name, "ui_SetName" ) == 0 ) 
     2587    trap_Cvar_Set( "name", UI_Cvar_VariableString( "ui_Name" ) ); 
     2588  else if( Q_stricmp( name, "ui_setRate" ) == 0 ) 
     2589  { 
     2590    float rate = trap_Cvar_VariableValue( "rate" ); 
     2591 
     2592    if( rate >= 5000 ) 
     2593    { 
     2594      trap_Cvar_Set( "cl_maxpackets", "30" ); 
     2595      trap_Cvar_Set( "cl_packetdup", "1" ); 
     2596    } 
     2597    else if( rate >= 4000 ) 
     2598    { 
     2599      trap_Cvar_Set( "cl_maxpackets", "15" ); 
     2600      trap_Cvar_Set( "cl_packetdup", "2" );   // favor less prediction errors when there's packet loss 
     2601    } 
     2602    else 
     2603    { 
     2604      trap_Cvar_Set( "cl_maxpackets", "15" ); 
     2605      trap_Cvar_Set( "cl_packetdup", "1" );   // favor lower bandwidth 
     2606    } 
     2607  } 
     2608  else if( Q_stricmp( name, "ui_GetName" ) == 0 ) 
     2609    trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString( "name" ) ); 
     2610  else if( Q_stricmp( name, "r_colorbits" ) == 0 ) 
     2611  { 
     2612    switch( val ) 
     2613    { 
     2614      case 0: 
     2615        trap_Cvar_SetValue( "r_depthbits", 0 ); 
     2616        trap_Cvar_SetValue( "r_stencilbits", 0 ); 
     2617        break; 
     2618 
     2619      case 16: 
     2620        trap_Cvar_SetValue( "r_depthbits", 16 ); 
     2621        trap_Cvar_SetValue( "r_stencilbits", 0 ); 
     2622        break; 
     2623 
     2624      case 32: 
     2625        trap_Cvar_SetValue( "r_depthbits", 24 ); 
     2626        break; 
     2627    } 
     2628  } 
     2629  else if( Q_stricmp( name, "r_lodbias" ) == 0 ) 
     2630  { 
     2631    switch( val ) 
     2632    { 
     2633      case 0: 
     2634        trap_Cvar_SetValue( "r_subdivisions", 4 ); 
     2635        break; 
     2636 
     2637      case 1: 
     2638        trap_Cvar_SetValue( "r_subdivisions", 12 ); 
     2639        break; 
     2640 
     2641      case 2: 
     2642        trap_Cvar_SetValue( "r_subdivisions", 20 ); 
     2643        break; 
     2644    } 
     2645  } 
     2646  else if( Q_stricmp( name, "ui_glCustom" ) == 0 ) 
     2647  { 
     2648    switch( val ) 
     2649    { 
     2650      case 0: // high quality 
     2651        trap_Cvar_SetValue( "r_subdivisions", 4 ); 
     2652        trap_Cvar_SetValue( "r_vertexlight", 0 ); 
     2653        trap_Cvar_SetValue( "r_lodbias", 0 ); 
     2654        trap_Cvar_SetValue( "r_colorbits", 32 ); 
     2655        trap_Cvar_SetValue( "r_depthbits", 24 ); 
     2656        trap_Cvar_SetValue( "r_picmip", 0 ); 
     2657        trap_Cvar_SetValue( "r_texturebits", 32 ); 
     2658        trap_Cvar_SetValue( "r_fastSky", 0 ); 
     2659        trap_Cvar_SetValue( "r_inGameVideo", 1 ); 
     2660        trap_Cvar_SetValue( "cg_shadows", 1 ); 
     2661        trap_Cvar_SetValue( "cg_brassTime", 2500 ); 
     2662        trap_Cvar_SetValue( "cg_bounceParticles", 1 ); 
     2663        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); 
     2664        break; 
     2665 
     2666      case 1: // normal 
     2667        trap_Cvar_SetValue( "r_subdivisions", 12 ); 
     2668        trap_Cvar_SetValue( "r_vertexlight", 0 ); 
     2669        trap_Cvar_SetValue( "r_lodbias", 0 ); 
     2670        trap_Cvar_SetValue( "r_colorbits", 0 ); 
     2671        trap_Cvar_SetValue( "r_depthbits", 24 ); 
     2672        trap_Cvar_SetValue( "r_picmip", 1 ); 
     2673        trap_Cvar_SetValue( "r_texturebits", 0 ); 
     2674        trap_Cvar_SetValue( "r_fastSky", 0 ); 
     2675        trap_Cvar_SetValue( "r_inGameVideo", 1 ); 
     2676        trap_Cvar_SetValue( "cg_brassTime", 2500 ); 
     2677        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); 
     2678        trap_Cvar_SetValue( "cg_shadows", 0 ); 
     2679        trap_Cvar_SetValue( "cg_bounceParticles", 0 ); 
     2680        break; 
     2681 
     2682      case 2: // fast 
     2683        trap_Cvar_SetValue( "r_subdivisions", 8 ); 
     2684        trap_Cvar_SetValue( "r_vertexlight", 0 ); 
     2685        trap_Cvar_SetValue( "r_lodbias", 1 ); 
     2686        trap_Cvar_SetValue( "r_colorbits", 0 ); 
     2687        trap_Cvar_SetValue( "r_depthbits", 0 ); 
     2688        trap_Cvar_SetValue( "r_picmip", 1 ); 
     2689        trap_Cvar_SetValue( "r_texturebits", 0 ); 
     2690        trap_Cvar_SetValue( "cg_shadows", 0 ); 
     2691        trap_Cvar_SetValue( "r_fastSky", 1 ); 
     2692        trap_Cvar_SetValue( "r_inGameVideo", 0 ); 
     2693        trap_Cvar_SetValue( "cg_brassTime", 0 ); 
     2694        trap_Cvar_SetValue( "cg_bounceParticles", 0 ); 
     2695        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" ); 
     2696        break; 
     2697 
     2698      case 3: // fastest 
     2699        trap_Cvar_SetValue( "r_subdivisions", 20 ); 
     2700        trap_Cvar_SetValue( "r_vertexlight", 1 ); 
     2701        trap_Cvar_SetValue( "r_lodbias", 2 ); 
     2702        trap_Cvar_SetValue( "r_colorbits", 16 ); 
     2703        trap_Cvar_SetValue( "r_depthbits", 16 ); 
     2704        trap_Cvar_SetValue( "r_picmip", 2 ); 
     2705        trap_Cvar_SetValue( "r_texturebits", 16 ); 
     2706        trap_Cvar_SetValue( "cg_shadows", 0 ); 
     2707        trap_Cvar_SetValue( "cg_brassTime", 0 ); 
     2708        trap_Cvar_SetValue( "r_fastSky", 1 ); 
     2709        trap_Cvar_SetValue( "r_inGameVideo", 0 ); 
     2710        trap_Cvar_SetValue( "cg_bounceParticles", 0 ); 
     2711        trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" ); 
     2712        break; 
     2713    } 
     2714  } 
     2715  else if( Q_stricmp( name, "ui_mousePitch" ) == 0 ) 
     2716  { 
     2717    if( val == 0 ) 
     2718      trap_Cvar_SetValue( "m_pitch", 0.022f ); 
     2719    else 
     2720      trap_Cvar_SetValue( "m_pitch", -0.022f ); 
     2721  } 
     2722} 
     2723 
     2724//FIXME: lookup table 
     2725static void UI_RunMenuScript( char **args ) 
     2726{ 
     2727  const char * name, *name2; 
     2728  char buff[1024]; 
     2729  const char *cmd; 
     2730 
     2731  if( String_Parse( args, &name ) ) 
     2732  { 
     2733    if( Q_stricmp( name, "StartServer" ) == 0 ) 
     2734    { 
     2735      trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, ui_dedicated.integer ) ); 
     2736      trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", 
     2737                            uiInfo.mapList[ui_selectedMap.integer].mapLoadName ) ); 
     2738    } 
     2739    else if( Q_stricmp( name, "resetDefaults" ) == 0 ) 
     2740    { 
     2741      trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n" ); 
     2742      trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n" ); 
     2743      Controls_SetDefaults(); 
     2744      trap_Cvar_Set( "com_introPlayed", "1" ); 
     2745      trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); 
     2746    } 
     2747    else if( Q_stricmp( name, "loadArenas" ) == 0 ) 
     2748    { 
     2749      UI_LoadArenas(); 
     2750      Menu_SetFeederSelection( NULL, FEEDER_MAPS, 0, "createserver" ); 
     2751    } 
     2752    else if( Q_stricmp( name, "loadServerInfo" ) == 0 ) 
     2753      UI_ServerInfo(); 
     2754    else if( Q_stricmp( name, "saveControls" ) == 0 ) 
     2755      Controls_SetConfig( qtrue ); 
     2756    else if( Q_stricmp( name, "loadControls" ) == 0 ) 
     2757      Controls_GetConfig(); 
     2758    else if( Q_stricmp( name, "clearError" ) == 0 ) 
     2759      trap_Cvar_Set( "com_errorMessage", "" ); 
     2760    else if( Q_stricmp( name, "RefreshServers" ) == 0 ) 
     2761    { 
     2762      UI_StartServerRefresh( qtrue ); 
     2763      UI_BuildServerDisplayList( qtrue ); 
     2764    } 
     2765    else if( Q_stricmp( name, "InitServerList" ) == 0 ) 
     2766    { 
     2767      int time = trap_RealTime( NULL ); 
     2768      int last; 
     2769      int sortColumn; 
     2770 
     2771      // set up default sorting 
     2772 
     2773      if( !uiInfo.serverStatus.sorted && Int_Parse( args, &sortColumn ) ) 
     2774      { 
     2775        uiInfo.serverStatus.sortKey = sortColumn; 
     2776        uiInfo.serverStatus.sortDir = 0; 
     2777      } 
     2778 
     2779      // refresh if older than 3 days or if list is empty 
     2780      last = atoi( UI_Cvar_VariableString( va( "ui_lastServerRefresh_%i_time", 
     2781                                           ui_netSource.integer ) ) ); 
     2782 
     2783      if( trap_LAN_GetServerCount( ui_netSource.integer ) < 1 || 
     2784          ( time - last ) > 3600 ) 
     2785      { 
     2786        UI_StartServerRefresh( qtrue ); 
     2787        UI_BuildServerDisplayList( qtrue ); 
     2788      } 
     2789    } 
     2790    else if( Q_stricmp( name, "RefreshFilter" ) == 0 ) 
     2791    { 
     2792      UI_StartServerRefresh( qfalse ); 
     2793      UI_BuildServerDisplayList( qtrue ); 
     2794    } 
     2795    else if( Q_stricmp( name, "LoadDemos" ) == 0 ) 
     2796      UI_LoadDemos(); 
     2797    else if( Q_stricmp( name, "LoadMovies" ) == 0 ) 
     2798      UI_LoadMovies(); 
     2799    else if( Q_stricmp( name, "LoadMods" ) == 0 ) 
     2800      UI_LoadMods(); 
     2801    else if( Q_stricmp( name, "LoadTeams" ) == 0 ) 
     2802      UI_LoadTeams( ); 
     2803    else if( Q_stricmp( name, "JoinTeam" ) == 0 ) 
     2804    { 
     2805      if( ( cmd = uiInfo.teamList[ uiInfo.teamIndex ].cmd ) ) 
     2806        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2807    } 
     2808    else if( Q_stricmp( name, "LoadHumanItems" ) == 0 ) 
     2809      UI_LoadHumanItems( ); 
     2810    else if( Q_stricmp( name, "SpawnWithHumanItem" ) == 0 ) 
     2811    { 
     2812      if( ( cmd = uiInfo.humanItemList[ uiInfo.humanItemIndex ].cmd ) ) 
     2813        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2814    } 
     2815    else if( Q_stricmp( name, "LoadAlienClasses" ) == 0 ) 
     2816      UI_LoadAlienClasses( ); 
     2817    else if( Q_stricmp( name, "SpawnAsAlienClass" ) == 0 ) 
     2818    { 
     2819      if( ( cmd = uiInfo.alienClassList[ uiInfo.alienClassIndex ].cmd ) ) 
     2820        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2821    } 
     2822    else if( Q_stricmp( name, "LoadHumanArmouryBuys" ) == 0 ) 
     2823      UI_LoadHumanArmouryBuys( ); 
     2824    else if( Q_stricmp( name, "BuyFromArmoury" ) == 0 ) 
     2825    { 
     2826      if( ( cmd = uiInfo.humanArmouryBuyList[ uiInfo.humanArmouryBuyIndex ].cmd ) ) 
     2827        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2828 
     2829      UI_InstallCaptureFunc( UI_ArmouryRefreshCb, NULL, 1000 ); 
     2830    } 
     2831    else if( Q_stricmp( name, "LoadHumanArmourySells" ) == 0 ) 
     2832      UI_LoadHumanArmourySells( ); 
     2833    else if( Q_stricmp( name, "SellToArmoury" ) == 0 ) 
     2834    { 
     2835      if( ( cmd = uiInfo.humanArmourySellList[ uiInfo.humanArmourySellIndex ].cmd ) ) 
     2836        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2837 
     2838      UI_InstallCaptureFunc( UI_ArmouryRefreshCb, NULL, 1000 ); 
     2839    } 
     2840    else if( Q_stricmp( name, "LoadAlienUpgrades" ) == 0 ) 
     2841    { 
     2842      UI_LoadAlienUpgrades( ); 
     2843 
     2844      //disallow the menu if it would be empty 
     2845 
     2846      if( uiInfo.alienUpgradeCount <= 0 ) 
     2847        Menus_CloseAll( ); 
     2848    } 
     2849    else if( Q_stricmp( name, "UpgradeToNewClass" ) == 0 ) 
     2850    { 
     2851      if( ( cmd = uiInfo.alienUpgradeList[ uiInfo.alienUpgradeIndex ].cmd ) ) 
     2852        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2853    } 
     2854    else if( Q_stricmp( name, "LoadAlienBuilds" ) == 0 ) 
     2855      UI_LoadAlienBuilds( ); 
     2856    else if( Q_stricmp( name, "BuildAlienBuildable" ) == 0 ) 
     2857    { 
     2858      if( ( cmd = uiInfo.alienBuildList[ uiInfo.alienBuildIndex ].cmd ) ) 
     2859        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2860    } 
     2861    else if( Q_stricmp( name, "LoadHumanBuilds" ) == 0 ) 
     2862      UI_LoadHumanBuilds( ); 
     2863    else if( Q_stricmp( name, "BuildHumanBuildable" ) == 0 ) 
     2864    { 
     2865      if( ( cmd = uiInfo.humanBuildList[ uiInfo.humanBuildIndex ].cmd ) ) 
     2866        trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); 
     2867    } 
     2868    else if( Q_stricmp( name, "PTRCRestore" ) == 0 ) 
     2869    { 
     2870      int           len; 
     2871      char          text[ 16 ]; 
     2872      fileHandle_t  f; 
     2873      char          command[ 32 ]; 
     2874 
     2875      // load the file 
     2876      len = trap_FS_FOpenFile( "ptrc.cfg", &f, FS_READ ); 
     2877 
     2878      if( len > 0 && ( len < sizeof( text ) - 1 ) ) 
     2879      { 
     2880        trap_FS_Read( text, len, f ); 
     2881        text[ len ] = 0; 
     2882        trap_FS_FCloseFile( f ); 
     2883 
     2884        Com_sprintf( command, 32, "ptrcrestore %s", text ); 
     2885 
     2886        trap_Cmd_ExecuteText( EXEC_APPEND, command ); 
     2887      } 
     2888    } 
     2889    else if( Q_stricmp( name, "Say" ) == 0 ) 
     2890    { 
     2891      char buffer[ MAX_CVAR_VALUE_STRING ]; 
     2892      trap_Cvar_VariableStringBuffer( "ui_sayBuffer", buffer, sizeof( buffer ) ); 
     2893 
     2894      if( uiInfo.chatTargetClientNum != -1 ) 
     2895        trap_Cmd_ExecuteText( EXEC_APPEND, va( "tell %i \"%s\"\n", uiInfo.chatTargetClientNum, buffer  ) ); 
     2896      else if( uiInfo.chatTeam ) 
     2897        trap_Cmd_ExecuteText( EXEC_APPEND, va( "say_team \"%s\"\n", buffer ) ); 
     2898      else 
     2899        trap_Cmd_ExecuteText( EXEC_APPEND, va( "say \"%s\"\n", buffer ) ); 
     2900    } 
     2901    else if( Q_stricmp( name, "playMovie" ) == 0 ) 
     2902    { 
     2903      if( uiInfo.previewMovie >= 0 ) 
     2904        trap_CIN_StopCinematic( uiInfo.previewMovie ); 
     2905 
     2906      trap_Cmd_ExecuteText( EXEC_APPEND, va( "cinematic %s.roq 2\n", uiInfo.movieList[uiInfo.movieIndex] ) ); 
     2907    } 
     2908    else if( Q_stricmp( name, "RunMod" ) == 0 ) 
     2909    { 
     2910      trap_Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName ); 
     2911      trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); 
     2912    } 
     2913    else if( Q_stricmp( name, "RunDemo" ) == 0 ) 
     2914      trap_Cmd_ExecuteText( EXEC_APPEND, va( "demo %s\n", uiInfo.demoList[uiInfo.demoIndex] ) ); 
     2915    else if( Q_stricmp( name, "Tremulous" ) == 0 ) 
     2916    { 
     2917      trap_Cvar_Set( "fs_game", "" ); 
     2918      trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); 
     2919    } 
     2920    else if( Q_stricmp( name, "closeJoin" ) == 0 ) 
     2921    { 
     2922      if( uiInfo.serverStatus.refreshActive ) 
     2923      { 
     2924        UI_StopServerRefresh(); 
     2925        uiInfo.serverStatus.nextDisplayRefresh = 0; 
     2926        uiInfo.nextServerStatusRefresh = 0; 
     2927        uiInfo.nextFindPlayerRefresh = 0; 
     2928        UI_BuildServerDisplayList( qtrue ); 
     2929      } 
     2930      else 
     2931      { 
     2932        Menus_CloseByName( "joinserver" ); 
     2933        Menus_ActivateByName( "main" ); 
     2934      } 
     2935    } 
     2936    else if( Q_stricmp( name, "StopRefresh" ) == 0 ) 
     2937    { 
     2938      UI_StopServerRefresh(); 
     2939      uiInfo.serverStatus.nextDisplayRefresh = 0; 
     2940      uiInfo.nextServerStatusRefresh = 0; 
     2941      uiInfo.nextFindPlayerRefresh = 0; 
     2942    } 
     2943    else if( Q_stricmp( name, "UpdateFilter" ) == 0 ) 
     2944    { 
     2945      if( ui_netSource.integer == AS_LOCAL ) 
     2946        UI_StartServerRefresh( qtrue ); 
     2947 
     2948      UI_BuildServerDisplayList( qtrue ); 
     2949      UI_FeederSelection( FEEDER_SERVERS, 0 ); 
     2950    } 
     2951    else if( Q_stricmp( name, "ServerStatus" ) == 0 ) 
     2952    { 
     2953      trap_LAN_GetServerAddressString( ui_netSource.integer, 
     2954                                       uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], 
     2955                                       uiInfo.serverStatusAddress, sizeof( uiInfo.serverStatusAddress ) ); 
     2956      UI_BuildServerStatus( qtrue ); 
     2957    } 
     2958    else if( Q_stricmp( name, "FoundPlayerServerStatus" ) == 0 ) 
     2959    { 
     2960      Q_strncpyz( uiInfo.serverStatusAddress, 
     2961                  uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], 
     2962                  sizeof( uiInfo.serverStatusAddress ) ); 
     2963      UI_BuildServerStatus( qtrue ); 
     2964      Menu_SetFeederSelection( NULL, FEEDER_FINDPLAYER, 0, NULL ); 
     2965    } 
     2966    else if( Q_stricmp( name, "FindPlayer" ) == 0 ) 
     2967    { 
     2968      UI_BuildFindPlayerList( qtrue ); 
     2969      // clear the displayed server status info 
     2970      uiInfo.serverStatusInfo.numLines = 0; 
     2971      Menu_SetFeederSelection( NULL, FEEDER_FINDPLAYER, 0, NULL ); 
     2972    } 
     2973    else if( Q_stricmp( name, "JoinServer" ) == 0 ) 
     2974    { 
     2975      if( uiInfo.serverStatus.currentServer >= 0 && 
     2976          uiInfo.serverStatus.currentServer < uiInfo.serverStatus.numDisplayServers ) 
     2977      { 
     2978        trap_LAN_GetServerAddressString( ui_netSource.integer, 
     2979                                          uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], 
     2980                                          buff, 1024 ); 
     2981        trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) ); 
     2982      } 
     2983    } 
     2984    else if( Q_stricmp( name, "FoundPlayerJoinServer" ) == 0 ) 
     2985    { 
     2986      if( uiInfo.currentFoundPlayerServer >= 0 && 
     2987          uiInfo.currentFoundPlayerServer < uiInfo.numFoundPlayerServers ) 
     2988      { 
     2989        trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", 
     2990                              uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer] ) ); 
     2991      } 
     2992    } 
     2993    else if( Q_stricmp( name, "Quit" ) == 0 ) 
     2994      trap_Cmd_ExecuteText( EXEC_NOW, "quit" ); 
     2995    else if( Q_stricmp( name, "Leave" ) == 0 ) 
     2996    { 
     2997      trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); 
     2998      trap_Key_SetCatcher( KEYCATCH_UI ); 
     2999      Menus_CloseAll(); 
     3000      Menus_ActivateByName( "main" ); 
     3001    } 
     3002    else if( Q_stricmp( name, "ServerSort" ) == 0 ) 
     3003    { 
     3004      int sortColumn; 
     3005 
     3006      if( Int_Parse( args, &sortColumn ) ) 
     3007      { 
     3008        // if same column we're already sorting on then flip the direction 
     3009 
     3010        if( sortColumn == uiInfo.serverStatus.sortKey ) 
     3011          uiInfo.serverStatus.sortDir = !uiInfo.serverStatus.sortDir; 
     3012 
     3013        // make sure we sort again 
     3014        UI_ServersSort( sortColumn, qtrue ); 
     3015 
     3016        uiInfo.serverStatus.sorted = qtrue; 
     3017      } 
     3018    } 
     3019    else if( Q_stricmp( name, "closeingame" ) == 0 ) 
     3020    { 
     3021      trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
     3022      trap_Key_ClearStates(); 
     3023      trap_Cvar_Set( "cl_paused", "0" ); 
     3024      Menus_CloseAll(); 
     3025    } 
     3026    else if( Q_stricmp( name, "voteMap" ) == 0 ) 
     3027    { 
     3028      if( ui_selectedMap.integer >= 0 && ui_selectedMap.integer < uiInfo.mapCount ) 
     3029      { 
     3030        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote map %s\n", 
     3031                              uiInfo.mapList[ui_selectedMap.integer].mapLoadName ) ); 
     3032      } 
     3033    } 
     3034    else if( Q_stricmp( name, "voteKick" ) == 0 ) 
     3035    { 
     3036      if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) 
     3037      { 
     3038        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote kick %d\n", 
     3039                                               uiInfo.clientNums[ uiInfo.playerIndex ] ) ); 
     3040      } 
     3041    } 
     3042    else if( Q_stricmp( name, "voteMute" ) == 0 ) 
     3043    { 
     3044      if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) 
     3045      { 
     3046        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote mute %d\n", 
     3047                                               uiInfo.clientNums[ uiInfo.playerIndex ] ) ); 
     3048      } 
     3049    } 
     3050    else if( Q_stricmp( name, "voteUnMute" ) == 0 ) 
     3051    { 
     3052      if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) 
     3053      { 
     3054        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote unmute %d\n", 
     3055                                               uiInfo.clientNums[ uiInfo.playerIndex ] ) ); 
     3056      } 
     3057    } 
     3058    else if( Q_stricmp( name, "voteTeamKick" ) == 0 ) 
     3059    { 
     3060      if( uiInfo.teamPlayerIndex >= 0 && uiInfo.teamPlayerIndex < uiInfo.myTeamCount ) 
     3061      { 
     3062        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote kick %d\n", 
     3063                                               uiInfo.teamClientNums[ uiInfo.teamPlayerIndex ] ) ); 
     3064      } 
     3065    } 
     3066    else if( Q_stricmp( name, "voteTeamDenyBuild" ) == 0 ) 
     3067    { 
     3068      if( uiInfo.teamPlayerIndex >= 0 && uiInfo.teamPlayerIndex < uiInfo.myTeamCount ) 
     3069      { 
     3070        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote denybuild %d\n", 
     3071                                               uiInfo.teamClientNums[ uiInfo.teamPlayerIndex ] ) ); 
     3072      } 
     3073    } 
     3074    else if( Q_stricmp( name, "voteTeamAllowBuild" ) == 0 ) 
     3075    { 
     3076      if( uiInfo.teamPlayerIndex >= 0 && uiInfo.teamPlayerIndex < uiInfo.myTeamCount ) 
     3077      { 
     3078        trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote allowbuild %d\n", 
     3079                                               uiInfo.teamClientNums[ uiInfo.teamPlayerIndex ] ) ); 
     3080      } 
     3081    } 
     3082    else if( Q_stricmp( name, "addFavorite" ) == 0 ) 
     3083    { 
     3084      if( ui_netSource.integer != AS_FAVORITES ) 
     3085      { 
     3086        char name[MAX_NAME_LENGTH]; 
     3087        char addr[MAX_NAME_LENGTH]; 
     3088        int res; 
     3089 
     3090        trap_LAN_GetServerInfo( ui_netSource.integer, 
     3091                                uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], 
     3092                                buff, MAX_STRING_CHARS ); 
     3093        name[0] = addr[0] = '\0'; 
     3094        Q_strncpyz( name,  Info_ValueForKey( buff, "hostname" ), MAX_NAME_LENGTH ); 
     3095        Q_strncpyz( addr,  Info_ValueForKey( buff, "addr" ), MAX_NAME_LENGTH ); 
     3096 
     3097        if( strlen( name ) > 0 && strlen( addr ) > 0 ) 
     3098        { 
     3099          res = trap_LAN_AddServer( AS_FAVORITES, name, addr ); 
     3100 
     3101          if( res == 0 ) 
     3102          { 
     3103            // server already in the list 
     3104            Com_Printf( "Favorite already in list\n" ); 
     3105          } 
     3106          else if( res == -1 ) 
     3107          { 
     3108            // list full 
     3109            Com_Printf( "Favorite list full\n" ); 
     3110          } 
     3111          else 
     3112          { 
     3113            // successfully added 
     3114            Com_Printf( "Added favorite server %s\n", addr ); 
     3115          } 
     3116        } 
     3117      } 
     3118    } 
     3119    else if( Q_stricmp( name, "deleteFavorite" ) == 0 ) 
     3120    { 
     3121      if( ui_netSource.integer == AS_FAVORITES ) 
     3122      { 
     3123        char addr[MAX_NAME_LENGTH]; 
     3124        trap_LAN_GetServerInfo( ui_netSource.integer, 
     3125                                uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], 
     3126                                buff, MAX_STRING_CHARS ); 
     3127        addr[0] = '\0'; 
     3128        Q_strncpyz( addr,  Info_ValueForKey( buff, "addr" ), MAX_NAME_LENGTH ); 
     3129 
     3130        if( strlen( addr ) > 0 ) 
     3131          trap_LAN_RemoveServer( AS_FAVORITES, addr ); 
     3132      } 
     3133    } 
     3134    else if( Q_stricmp( name, "createFavorite" ) == 0 ) 
     3135    { 
     3136      if( ui_netSource.integer == AS_FAVORITES ) 
     3137      { 
     3138        char name[MAX_NAME_LENGTH]; 
     3139        char addr[MAX_NAME_LENGTH]; 
     3140        int res; 
     3141 
     3142        name[0] = addr[0] = '\0'; 
     3143        Q_strncpyz( name,  UI_Cvar_VariableString( "ui_favoriteName" ), MAX_NAME_LENGTH ); 
     3144        Q_strncpyz( addr,  UI_Cvar_VariableString( "ui_favoriteAddress" ), MAX_NAME_LENGTH ); 
     3145 
     3146        if( strlen( name ) > 0 && strlen( addr ) > 0 ) 
     3147        { 
     3148          res = trap_LAN_AddServer( AS_FAVORITES, name, addr ); 
     3149 
     3150          if( res == 0 ) 
     3151          { 
     3152            // server already in the list 
     3153            Com_Printf( "Favorite already in list\n" ); 
     3154          } 
     3155          else if( res == -1 ) 
     3156          { 
     3157            // list full 
     3158            Com_Printf( "Favorite list full\n" ); 
     3159          } 
     3160          else 
     3161          { 
     3162            // successfully added 
     3163            Com_Printf( "Added favorite server %s\n", addr ); 
     3164          } 
     3165        } 
     3166      } 
     3167    } 
     3168    else if( Q_stricmp( name, "glCustom" ) == 0 ) 
     3169      trap_Cvar_Set( "ui_glCustom", "4" ); 
     3170    else if( Q_stricmp( name, "update" ) == 0 ) 
     3171    { 
     3172      if( String_Parse( args, &name2 ) ) 
     3173        UI_Update( name2 ); 
     3174    } 
     3175    else if( Q_stricmp( name, "InitIgnoreList" ) == 0 ) 
     3176      UI_BuildPlayerList(); 
     3177    else if( Q_stricmp( name, "ToggleIgnore" ) == 0 ) 
     3178    { 
     3179      if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount ) 
     3180      { 
     3181        if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3182                               uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ) 
     3183        { 
     3184          BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3185                               uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
     3186          trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n", 
     3187                                              uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
     3188        } 
     3189        else 
     3190        { 
     3191          BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3192                            uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
     3193          trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n", 
     3194                                              uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
     3195        } 
     3196      } 
     3197    } 
     3198    else if( Q_stricmp( name, "IgnorePlayer" ) == 0 ) 
     3199    { 
     3200      if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount ) 
     3201      { 
     3202        if( !BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3203                                uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ) 
     3204        { 
     3205          BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3206                            uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
     3207          trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n", 
     3208                                              uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
     3209        } 
     3210      } 
     3211    } 
     3212    else if( Q_stricmp( name, "UnIgnorePlayer" ) == 0 ) 
     3213    { 
     3214      if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount ) 
     3215      { 
     3216        if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3217                               uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ) 
     3218        { 
     3219          BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3220                               uiInfo.clientNums[ uiInfo.ignoreIndex ] ); 
     3221          trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n", 
     3222                                              uiInfo.clientNums[ uiInfo.ignoreIndex ] ) ); 
     3223        } 
     3224      } 
     3225    } 
     3226    else 
     3227      Com_Printf( "unknown UI script %s\n", name ); 
    48513228  } 
    48523229} 
     
    48573234================== 
    48583235*/ 
    4859 static int UI_FeederCount(float feederID) { 
    4860  
    4861   if (feederID == FEEDER_HEADS) { 
    4862     return UI_HeadCountByTeam(); 
    4863   } else if (feederID == FEEDER_Q3HEADS) { 
    4864     return uiInfo.q3HeadCount; 
    4865   } else if (feederID == FEEDER_CINEMATICS) { 
     3236static int UI_FeederCount( float feederID ) 
     3237{ 
     3238  if( feederID == FEEDER_CINEMATICS ) 
    48663239    return uiInfo.movieCount; 
    4867   } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) { 
    4868     return UI_MapCountByGameType(feederID == FEEDER_MAPS ? qtrue : qfalse); 
    4869   } else if (feederID == FEEDER_SERVERS) { 
     3240  else if( feederID == FEEDER_MAPS ) 
     3241    return uiInfo.mapCount; 
     3242  else if( feederID == FEEDER_SERVERS ) 
    48703243    return uiInfo.serverStatus.numDisplayServers; 
    4871   } else if (feederID == FEEDER_SERVERSTATUS) { 
     3244  else if( feederID == FEEDER_SERVERSTATUS ) 
    48723245    return uiInfo.serverStatusInfo.numLines; 
    4873   } else if (feederID == FEEDER_FINDPLAYER) { 
     3246  else if( feederID == FEEDER_FINDPLAYER ) 
    48743247    return uiInfo.numFoundPlayerServers; 
    4875   } else if (feederID == FEEDER_PLAYER_LIST) { 
    4876     if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) { 
     3248  else if( feederID == FEEDER_PLAYER_LIST ) 
     3249  { 
     3250    if( uiInfo.uiDC.realTime > uiInfo.playerRefresh ) 
     3251    { 
    48773252      uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000; 
    48783253      UI_BuildPlayerList(); 
    48793254    } 
     3255 
    48803256    return uiInfo.playerCount; 
    4881   } else if (feederID == FEEDER_TEAM_LIST) { 
    4882     if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) { 
     3257  } 
     3258  else if( feederID == FEEDER_TEAM_LIST ) 
     3259  { 
     3260    if( uiInfo.uiDC.realTime > uiInfo.playerRefresh ) 
     3261    { 
    48833262      uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000; 
    48843263      UI_BuildPlayerList(); 
    48853264    } 
     3265 
    48863266    return uiInfo.myTeamCount; 
    4887   } else if (feederID == FEEDER_IGNORE_LIST) { 
     3267  } 
     3268  else if( feederID == FEEDER_IGNORE_LIST ) 
    48883269    return uiInfo.playerCount; 
    4889   } else if (feederID == FEEDER_MODS) { 
     3270  else if( feederID == FEEDER_MODS ) 
    48903271    return uiInfo.modCount; 
    4891   } else if (feederID == FEEDER_DEMOS) { 
     3272  else if( feederID == FEEDER_DEMOS ) 
    48923273    return uiInfo.demoCount; 
    4893   } 
    48943274  else if( feederID == FEEDER_TREMTEAMS ) 
    4895     return uiInfo.tremTeamCount; 
     3275    return uiInfo.teamCount; 
    48963276  else if( feederID == FEEDER_TREMHUMANITEMS ) 
    48973277    return uiInfo.humanItemCount; 
     
    49123292} 
    49133293 
    4914 static const char *UI_SelectedMap(int index, int *actual) { 
     3294static const char *UI_SelectedMap( int index, int *actual ) 
     3295{ 
    49153296  int i, c; 
    49163297  c = 0; 
    49173298  *actual = 0; 
    4918   for (i = 0; i < uiInfo.mapCount; i++) { 
    4919     if (uiInfo.mapList[i].active) { 
    4920       if (c == index) { 
    4921         *actual = i; 
    4922         return uiInfo.mapList[i].mapName; 
    4923       } else { 
    4924         c++; 
    4925       } 
    4926     } 
    4927   } 
     3299 
     3300  for( i = 0; i < uiInfo.mapCount; i++ ) 
     3301  { 
     3302    if( c == index ) 
     3303    { 
     3304      *actual = i; 
     3305      return uiInfo.mapList[i].mapName; 
     3306    } 
     3307    else 
     3308      c++; 
     3309  } 
     3310 
    49283311  return ""; 
    49293312} 
    49303313 
    4931 static const char *UI_SelectedHead(int index, int *actual) { 
    4932   int i, c; 
    4933   c = 0; 
    4934   *actual = 0; 
    4935   for (i = 0; i < uiInfo.characterCount; i++) { 
    4936     if (uiInfo.characterList[i].active) { 
    4937       if (c == index) { 
    4938         *actual = i; 
    4939         return uiInfo.characterList[i].name; 
    4940       } else { 
    4941         c++; 
    4942       } 
    4943     } 
    4944   } 
    4945   return ""; 
    4946 } 
    4947  
    4948 static int UI_GetIndexFromSelection(int actual) { 
    4949   int i, c; 
    4950   c = 0; 
    4951   for (i = 0; i < uiInfo.mapCount; i++) { 
    4952     if (uiInfo.mapList[i].active) { 
    4953       if (i == actual) { 
    4954         return c; 
    4955       } 
    4956         c++; 
    4957     } 
    4958   } 
    4959   return 0; 
    4960 } 
    4961  
    4962 static void UI_UpdatePendingPings( void ) { 
    4963   trap_LAN_ResetPings(ui_netSource.integer); 
    4964   uiInfo.serverStatus.refreshActive = qtrue; 
    4965   uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; 
    4966  
    4967 } 
    4968  
    4969 static const char *UI_FeederItemText(float feederID, int index, int column, qhandle_t *handle) { 
     3314static const char *UI_FeederItemText( float feederID, int index, int column, qhandle_t *handle ) 
     3315{ 
    49703316  static char info[MAX_STRING_CHARS]; 
    49713317  static char hostname[1024]; 
     
    49743320  static int lastTime = 0; 
    49753321  *handle = -1; 
    4976   if (feederID == FEEDER_HEADS) { 
     3322 
     3323  if( feederID == FEEDER_MAPS ) 
     3324  { 
    49773325    int actual; 
    4978     return UI_SelectedHead(index, &actual); 
    4979   } else if (feederID == FEEDER_Q3HEADS) { 
    4980     if (index >= 0 && index < uiInfo.q3HeadCount) { 
    4981       return uiInfo.q3HeadNames[index]; 
    4982     } 
    4983   } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) { 
    4984     int actual; 
    4985     return UI_SelectedMap(index, &actual); 
    4986   } else if (feederID == FEEDER_SERVERS) { 
    4987     if (index >= 0 && index < uiInfo.serverStatus.numDisplayServers) { 
     3326    return UI_SelectedMap( index, &actual ); 
     3327  } 
     3328  else if( feederID == FEEDER_SERVERS ) 
     3329  { 
     3330    if( index >= 0 && index < uiInfo.serverStatus.numDisplayServers ) 
     3331    { 
    49883332      int ping; 
    4989       if (lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000) { 
    4990         trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS); 
     3333 
     3334      if( lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000 ) 
     3335      { 
     3336        trap_LAN_GetServerInfo( ui_netSource.integer, uiInfo.serverStatus.displayServers[index], 
     3337                                info, MAX_STRING_CHARS ); 
    49913338        lastColumn = column; 
    49923339        lastTime = uiInfo.uiDC.realTime; 
    49933340      } 
    49943341 
    4995       ping = atoi(Info_ValueForKey(info, "ping")); 
    4996       if (ping == -1) { 
     3342      ping = atoi( Info_ValueForKey( info, "ping" ) ); 
     3343 
     3344      if( ping == -1 ) 
     3345      { 
    49973346        // if we ever see a ping that is out of date, do a server refresh 
    49983347        // UI_UpdatePendingPings(); 
    49993348      } 
    5000       switch (column) { 
    5001         case SORT_HOST : 
    5002           if (ping <= 0) { 
    5003             return Info_ValueForKey(info, "addr"); 
    5004           } else { 
    5005             if ( ui_netSource.integer == AS_LOCAL ) { 
    5006               Com_sprintf( hostname, sizeof(hostname), "%s [%s]", 
    5007                       Info_ValueForKey(info, "hostname"), 
    5008                       netnames[atoi(Info_ValueForKey(info, "nettype"))] ); 
     3349 
     3350      switch( column ) 
     3351      { 
     3352        case SORT_HOST: 
     3353          if( ping <= 0 ) 
     3354            return Info_ValueForKey( info, "addr" ); 
     3355          else 
     3356          { 
     3357            if( ui_netSource.integer == AS_LOCAL ) 
     3358            { 
     3359              Com_sprintf( hostname, sizeof( hostname ), "%s [%s]", 
     3360                           Info_ValueForKey( info, "hostname" ), 
     3361                           netnames[atoi( Info_ValueForKey( info, "nettype" ) )] ); 
    50093362              return hostname; 
    50103363            } 
     
    50133366              char *text; 
    50143367 
    5015               Com_sprintf( hostname, sizeof(hostname), "%s", Info_ValueForKey(info, "hostname")); 
     3368              Com_sprintf( hostname, sizeof( hostname ), "%s", Info_ValueForKey( info, "hostname" ) ); 
    50163369 
    50173370              // Strip leading whitespace 
    50183371              text = hostname; 
     3372 
    50193373              while( *text != '\0' && *text == ' ' ) 
    50203374                text++; 
     
    50233377            } 
    50243378          } 
    5025         case SORT_MAP : 
    5026           return Info_ValueForKey(info, "mapname"); 
    5027         case SORT_CLIENTS : 
    5028           Com_sprintf( clientBuff, sizeof(clientBuff), "%s (%s)", Info_ValueForKey(info, "clients"), Info_ValueForKey(info, "sv_maxclients")); 
     3379 
     3380        case SORT_MAP: 
     3381          return Info_ValueForKey( info, "mapname" ); 
     3382 
     3383        case SORT_CLIENTS: 
     3384          Com_sprintf( clientBuff, sizeof( clientBuff ), "%s (%s)", 
     3385                       Info_ValueForKey( info, "clients" ), Info_ValueForKey( info, "sv_maxclients" ) ); 
    50293386          return clientBuff; 
    5030         case SORT_PING : 
    5031           if (ping <= 0) { 
     3387 
     3388        case SORT_PING: 
     3389          if( ping <= 0 ) 
    50323390            return "..."; 
    5033           } else { 
    5034             return Info_ValueForKey(info, "ping"); 
    5035           } 
    5036       } 
    5037     } 
    5038   } else if (feederID == FEEDER_SERVERSTATUS) { 
    5039     if ( index >= 0 && index < uiInfo.serverStatusInfo.numLines ) { 
    5040       if ( column >= 0 && column < 4 ) { 
     3391          else 
     3392            return Info_ValueForKey( info, "ping" ); 
     3393      } 
     3394    } 
     3395  } 
     3396  else if( feederID == FEEDER_SERVERSTATUS ) 
     3397  { 
     3398    if( index >= 0 && index < uiInfo.serverStatusInfo.numLines ) 
     3399    { 
     3400      if( column >= 0 && column < 4 ) 
    50413401        return uiInfo.serverStatusInfo.lines[index][column]; 
    5042       } 
    5043     } 
    5044   } else if (feederID == FEEDER_FINDPLAYER) { 
    5045     if ( index >= 0 && index < uiInfo.numFoundPlayerServers ) { 
     3402    } 
     3403  } 
     3404  else if( feederID == FEEDER_FINDPLAYER ) 
     3405  { 
     3406    if( index >= 0 && index < uiInfo.numFoundPlayerServers ) 
     3407    { 
    50463408      //return uiInfo.foundPlayerServerAddresses[index]; 
    50473409      return uiInfo.foundPlayerServerNames[index]; 
    50483410    } 
    5049   } else if (feederID == FEEDER_PLAYER_LIST) { 
    5050     if (index >= 0 && index < uiInfo.playerCount) { 
     3411  } 
     3412  else if( feederID == FEEDER_PLAYER_LIST ) 
     3413  { 
     3414    if( index >= 0 && index < uiInfo.playerCount ) 
    50513415      return uiInfo.playerNames[index]; 
    5052     } 
    5053   } else if (feederID == FEEDER_TEAM_LIST) { 
    5054     if (index >= 0 && index < uiInfo.myTeamCount) { 
     3416  } 
     3417  else if( feederID == FEEDER_TEAM_LIST ) 
     3418  { 
     3419    if( index >= 0 && index < uiInfo.myTeamCount ) 
    50553420      return uiInfo.teamNames[index]; 
    5056     } 
    5057   } else if (feederID == FEEDER_IGNORE_LIST) { 
    5058     if (index >= 0 && index < uiInfo.playerCount) { 
     3421  } 
     3422  else if( feederID == FEEDER_IGNORE_LIST ) 
     3423  { 
     3424    if( index >= 0 && index < uiInfo.playerCount ) 
     3425    { 
    50593426      switch( column ) 
    50603427      { 
    50613428        case 1: 
    50623429          // am I ignoring him 
    5063           return ( BG_ClientListTest(&uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
    5064             uiInfo.clientNums[ index ] ) ) ? "X" : ""; 
     3430          return ( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ], 
     3431                                      uiInfo.clientNums[ index ] ) ) ? "X" : ""; 
     3432 
    50653433        case 2: 
    50663434          // is he ignoring me 
    50673435          return ( BG_ClientListTest( &uiInfo.ignoreList[ index ], 
    5068             uiInfo.playerNumber ) ) ? "X" : ""; 
     3436                                      uiInfo.playerNumber ) ) ? "X" : ""; 
     3437 
    50693438        default: 
    50703439          return uiInfo.playerNames[index]; 
    50713440      } 
    50723441    } 
    5073   } else if (feederID == FEEDER_MODS) { 
    5074     if (index >= 0 && index < uiInfo.modCount) { 
    5075       if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr) { 
     3442  } 
     3443  else if( feederID == FEEDER_MODS ) 
     3444  { 
     3445    if( index >= 0 && index < uiInfo.modCount ) 
     3446    { 
     3447      if( uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr ) 
    50763448        return uiInfo.modList[index].modDescr; 
    5077       } else { 
     3449      else 
    50783450        return uiInfo.modList[index].modName; 
    5079       } 
    5080     } 
    5081   } else if (feederID == FEEDER_CINEMATICS) { 
    5082     if (index >= 0 && index < uiInfo.movieCount) { 
     3451    } 
     3452  } 
     3453  else if( feederID == FEEDER_CINEMATICS ) 
     3454  { 
     3455    if( index >= 0 && index < uiInfo.movieCount ) 
    50833456      return uiInfo.movieList[index]; 
    5084     } 
    5085   } else if (feederID == FEEDER_DEMOS) { 
    5086     if (index >= 0 && index < uiInfo.demoCount) { 
     3457  } 
     3458  else if( feederID == FEEDER_DEMOS ) 
     3459  { 
     3460    if( index >= 0 && index < uiInfo.demoCount ) 
    50873461      return uiInfo.demoList[index]; 
    5088     } 
    50893462  } 
    50903463  else if( feederID == FEEDER_TREMTEAMS ) 
    50913464  { 
    5092     if( index >= 0 && index < uiInfo.tremTeamCount ) 
    5093       return uiInfo.tremTeamList[ index ].text; 
     3465    if( index >= 0 && index < uiInfo.teamCount ) 
     3466      return uiInfo.teamList[ index ].text; 
    50943467  } 
    50953468  else if( feederID == FEEDER_TREMHUMANITEMS ) 
     
    51333506 
    51343507 
    5135 static qhandle_t UI_FeederItemImage(float feederID, int index) { 
    5136   if (feederID == FEEDER_HEADS) { 
    5137   int actual; 
    5138   UI_SelectedHead(index, &actual); 
    5139   index = actual; 
    5140   if (index >= 0 && index < uiInfo.characterCount) { 
    5141     if (uiInfo.characterList[index].headImage == -1) { 
    5142       uiInfo.characterList[index].headImage = trap_R_RegisterShaderNoMip(uiInfo.characterList[index].imageName); 
    5143     } 
    5144     return uiInfo.characterList[index].headImage; 
    5145   } 
    5146   } else if (feederID == FEEDER_Q3HEADS) { 
    5147     if (index >= 0 && index < uiInfo.q3HeadCount) { 
    5148       return uiInfo.q3HeadIcons[index]; 
    5149     } 
    5150   } else if (feederID == FEEDER_ALLMAPS || feederID == FEEDER_MAPS) { 
     3508static qhandle_t UI_FeederItemImage( float feederID, int index ) 
     3509{ 
     3510  if( feederID == FEEDER_MAPS ) 
     3511  { 
    51513512    int actual; 
    5152     UI_SelectedMap(index, &actual); 
     3513    UI_SelectedMap( index, &actual ); 
    51533514    index = actual; 
    5154     if (index >= 0 && index < uiInfo.mapCount) { 
    5155       if (uiInfo.mapList[index].levelShot == -1) { 
    5156         uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[index].imageName); 
    5157       } 
     3515 
     3516    if( index >= 0 && index < uiInfo.mapCount ) 
     3517    { 
     3518      if( uiInfo.mapList[index].levelShot == -1 ) 
     3519        uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip( uiInfo.mapList[index].imageName ); 
     3520 
    51583521      return uiInfo.mapList[index].levelShot; 
    51593522    } 
    51603523  } 
     3524 
    51613525  return 0; 
    51623526} 
    51633527 
    5164 static void UI_FeederSelection(float feederID, int index) { 
     3528static void UI_FeederSelection( float feederID, int index ) 
     3529{ 
    51653530  static char info[MAX_STRING_CHARS]; 
    5166   if (feederID == FEEDER_HEADS) { 
    5167   int actual; 
    5168   UI_SelectedHead(index, &actual); 
    5169   index = actual; 
    5170     if (index >= 0 && index < uiInfo.characterCount) { 
    5171     trap_Cvar_Set( "team_model", va("%s", uiInfo.characterList[index].base)); 
    5172     trap_Cvar_Set( "team_headmodel", va("*%s", uiInfo.characterList[index].name)); 
    5173     updateModel = qtrue; 
    5174     } 
    5175   } else if (feederID == FEEDER_Q3HEADS) { 
    5176     if (index >= 0 && index < uiInfo.q3HeadCount) { 
    5177       trap_Cvar_Set( "model", uiInfo.q3HeadNames[index]); 
    5178       trap_Cvar_Set( "headmodel", uiInfo.q3HeadNames[index]); 
    5179       updateModel = qtrue; 
    5180     } 
    5181   } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) { 
     3531 
     3532  if( feederID == FEEDER_MAPS ) 
     3533  { 
    51823534    int actual, map; 
    5183     map = (feederID == FEEDER_ALLMAPS) ? ui_currentNetMap.integer : ui_currentMap.integer; 
    5184     if (uiInfo.mapList[map].cinematic >= 0) { 
    5185       trap_CIN_StopCinematic(uiInfo.mapList[map].cinematic); 
     3535    map = ui_selectedMap.integer; 
     3536 
     3537    if( uiInfo.mapList[map].cinematic >= 0 ) 
     3538    { 
     3539      trap_CIN_StopCinematic( uiInfo.mapList[map].cinematic ); 
    51863540      uiInfo.mapList[map].cinematic = -1; 
    51873541    } 
    5188     UI_SelectedMap(index, &actual); 
    5189     trap_Cvar_Set("ui_mapIndex", va("%d", index)); 
    5190     ui_mapIndex.integer = index; 
    5191  
    5192     if (feederID == FEEDER_MAPS) { 
    5193       ui_currentMap.integer = actual; 
    5194       trap_Cvar_Set("ui_currentMap", va("%d", actual)); 
    5195       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) ); 
    5196       UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum); 
    5197       trap_Cvar_Set("ui_opponentModel", uiInfo.mapList[ui_currentMap.integer].opponentName); 
    5198       updateOpponentModel = qtrue; 
    5199     } else { 
    5200       ui_currentNetMap.integer = actual; 
    5201       trap_Cvar_Set("ui_currentNetMap", va("%d", actual)); 
    5202       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) ); 
    5203     } 
    5204  
    5205   } else if (feederID == FEEDER_SERVERS) { 
    5206     const char *mapName = NULL; 
     3542 
     3543    UI_SelectedMap( index, &actual ); 
     3544 
     3545    ui_selectedMap.integer = actual; 
     3546    trap_Cvar_Set( "ui_selectedMap", va( "%d", actual ) ); 
     3547    uiInfo.mapList[ui_selectedMap.integer].cinematic = 
     3548      trap_CIN_PlayCinematic( va( "%s.roq", uiInfo.mapList[ui_selectedMap.integer].mapLoadName ), 
     3549                              0, 0, 0, 0, ( CIN_loop | CIN_silent ) ); 
     3550  } 
     3551  else if( feederID == FEEDER_SERVERS ) 
     3552  { 
     3553    const char * mapName = NULL; 
    52073554    uiInfo.serverStatus.currentServer = index; 
    5208     trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS); 
    5209     uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip(va("levelshots/%s", Info_ValueForKey(info, "mapname"))); 
    5210     if (uiInfo.serverStatus.currentServerCinematic >= 0) { 
    5211       trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic); 
     3555    trap_LAN_GetServerInfo( ui_netSource.integer, uiInfo.serverStatus.displayServers[index], 
     3556                            info, MAX_STRING_CHARS ); 
     3557    uiInfo.serverStatus.currentServerPreview = 
     3558      trap_R_RegisterShaderNoMip( va( "levelshots/%s", Info_ValueForKey( info, "mapname" ) ) ); 
     3559 
     3560    if( uiInfo.serverStatus.currentServerCinematic >= 0 ) 
     3561    { 
     3562      trap_CIN_StopCinematic( uiInfo.serverStatus.currentServerCinematic ); 
    52123563      uiInfo.serverStatus.currentServerCinematic = -1; 
    52133564    } 
    5214     mapName = Info_ValueForKey(info, "mapname"); 
    5215     if (mapName && *mapName) { 
    5216       uiInfo.serverStatus.currentServerCinematic = trap_CIN_PlayCinematic(va("%s.roq", mapName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); 
    5217     } 
    5218   } else if (feederID == FEEDER_SERVERSTATUS) { 
    5219     // 
    5220   } else if (feederID == FEEDER_FINDPLAYER) { 
     3565 
     3566    mapName = Info_ValueForKey( info, "mapname" ); 
     3567 
     3568    if( mapName && *mapName ) 
     3569    { 
     3570      uiInfo.serverStatus.currentServerCinematic = 
     3571        trap_CIN_PlayCinematic( va( "%s.roq", mapName ), 0, 0, 0, 0, ( CIN_loop | CIN_silent ) ); 
     3572    } 
     3573  } 
     3574  else if( feederID == FEEDER_SERVERSTATUS ) 
     3575  { 
     3576  } 
     3577  else if( feederID == FEEDER_FINDPLAYER ) 
     3578  { 
    52213579    uiInfo.currentFoundPlayerServer = index; 
    52223580    // 
    5223     if ( index < uiInfo.numFoundPlayerServers-1) { 
     3581 
     3582    if( index < uiInfo.numFoundPlayerServers - 1 ) 
     3583    { 
    52243584      // build a new server status for this server 
    5225       Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress)); 
    5226       Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL); 
    5227       UI_BuildServerStatus(qtrue); 
    5228     } 
    5229   } else if (feederID == FEEDER_PLAYER_LIST) { 
     3585      Q_strncpyz( uiInfo.serverStatusAddress, 
     3586                  uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], 
     3587                  sizeof( uiInfo.serverStatusAddress ) ); 
     3588      Menu_SetFeederSelection( NULL, FEEDER_SERVERSTATUS, 0, NULL ); 
     3589      UI_BuildServerStatus( qtrue ); 
     3590    } 
     3591  } 
     3592  else if( feederID == FEEDER_PLAYER_LIST ) 
    52303593    uiInfo.playerIndex = index; 
    5231   } else if (feederID == FEEDER_TEAM_LIST) { 
     3594  else if( feederID == FEEDER_TEAM_LIST ) 
     3595    uiInfo.teamPlayerIndex = index; 
     3596  else if( feederID == FEEDER_IGNORE_LIST ) 
     3597    uiInfo.ignoreIndex = index; 
     3598  else if( feederID == FEEDER_MODS ) 
     3599    uiInfo.modIndex = index; 
     3600  else if( feederID == FEEDER_CINEMATICS ) 
     3601  { 
     3602    uiInfo.movieIndex = index; 
     3603 
     3604    if( uiInfo.previewMovie >= 0 ) 
     3605      trap_CIN_StopCinematic( uiInfo.previewMovie ); 
     3606 
     3607    uiInfo.previewMovie = -1; 
     3608  } 
     3609  else if( feederID == FEEDER_DEMOS ) 
     3610    uiInfo.demoIndex = index; 
     3611  else if( feederID == FEEDER_TREMTEAMS ) 
    52323612    uiInfo.teamIndex = index; 
    5233   } else if (feederID == FEEDER_IGNORE_LIST) { 
    5234     uiInfo.ignoreIndex = index; 
    5235   } else if (feederID == FEEDER_MODS) { 
    5236     uiInfo.modIndex = index; 
    5237   } else if (feederID == FEEDER_CINEMATICS) { 
    5238     uiInfo.movieIndex = index; 
    5239     if (uiInfo.previewMovie >= 0) { 
    5240       trap_CIN_StopCinematic(uiInfo.previewMovie); 
    5241     } 
    5242     uiInfo.previewMovie = -1; 
    5243   } else if (feederID == FEEDER_DEMOS) { 
    5244     uiInfo.demoIndex = index; 
    5245   } 
    5246   else if( feederID == FEEDER_TREMTEAMS ) 
    5247     uiInfo.tremTeamIndex = index; 
    52483613  else if( feederID == FEEDER_TREMHUMANITEMS ) 
    52493614    uiInfo.humanItemIndex = index; 
     
    52623627} 
    52633628 
    5264 static void UI_Pause(qboolean b) { 
    5265   if (b) { 
     3629static void UI_Pause( qboolean b ) 
     3630{ 
     3631  if( b ) 
     3632  { 
    52663633    // pause the game and set the ui keycatcher 
    52673634    trap_Cvar_Set( "cl_paused", "1" ); 
    52683635    trap_Key_SetCatcher( KEYCATCH_UI ); 
    5269   } else { 
     3636  } 
     3637  else 
     3638  { 
    52703639    // unpause the game and clear the ui keycatcher 
    52713640    trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
     
    52753644} 
    52763645 
    5277 static int UI_PlayCinematic(const char *name, float x, float y, float w, float h) { 
    5278   return trap_CIN_PlayCinematic(name, x, y, w, h, (CIN_loop | CIN_silent)); 
    5279 } 
    5280  
    5281 static void UI_StopCinematic(int handle) { 
    5282   if (handle >= 0) { 
    5283     trap_CIN_StopCinematic(handle); 
    5284   } else { 
    5285     handle = abs(handle); 
    5286     if (handle == UI_MAPCINEMATIC) { 
    5287       if (uiInfo.mapList[ui_currentMap.integer].cinematic >= 0) { 
    5288         trap_CIN_StopCinematic(uiInfo.mapList[ui_currentMap.integer].cinematic); 
    5289         uiInfo.mapList[ui_currentMap.integer].cinematic = -1; 
    5290       } 
    5291     } else if (handle == UI_NETMAPCINEMATIC) { 
    5292       if (uiInfo.serverStatus.currentServerCinematic >= 0) { 
    5293         trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic); 
     3646static int UI_PlayCinematic( const char *name, float x, float y, float w, float h ) 
     3647{ 
     3648  return trap_CIN_PlayCinematic( name, x, y, w, h, ( CIN_loop | CIN_silent ) ); 
     3649} 
     3650 
     3651static void UI_StopCinematic( int handle ) 
     3652{ 
     3653  if( handle >= 0 ) 
     3654    trap_CIN_StopCinematic( handle ); 
     3655  else 
     3656  { 
     3657    handle = abs( handle ); 
     3658 
     3659    if( handle == UI_NETMAPCINEMATIC ) 
     3660    { 
     3661      if( uiInfo.serverStatus.currentServerCinematic >= 0 ) 
     3662      { 
     3663        trap_CIN_StopCinematic( uiInfo.serverStatus.currentServerCinematic ); 
    52943664        uiInfo.serverStatus.currentServerCinematic = -1; 
    52953665      } 
    5296     } else if (handle == UI_CLANCINEMATIC) { 
    5297       int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName")); 
    5298       if (i >= 0 && i < uiInfo.teamCount) { 
    5299         if (uiInfo.teamList[i].cinematic >= 0) { 
    5300           trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic); 
    5301           uiInfo.teamList[i].cinematic = -1; 
    5302         } 
    5303       } 
    5304     } 
    5305   } 
    5306 } 
    5307  
    5308 static void UI_DrawCinematic(int handle, float x, float y, float w, float h) { 
    5309   trap_CIN_SetExtents(handle, x, y, w, h); 
    5310   trap_CIN_DrawCinematic(handle); 
    5311 } 
    5312  
    5313 static void UI_RunCinematicFrame(int handle) { 
    5314   trap_CIN_RunCinematic(handle); 
     3666    } 
     3667  } 
     3668} 
     3669 
     3670static void UI_DrawCinematic( int handle, float x, float y, float w, float h ) 
     3671{ 
     3672  trap_CIN_SetExtents( handle, x, y, w, h ); 
     3673  trap_CIN_DrawCinematic( handle ); 
     3674} 
     3675 
     3676static void UI_RunCinematicFrame( int handle ) 
     3677{ 
     3678  trap_CIN_RunCinematic( handle ); 
     3679} 
     3680 
     3681static float UI_GetValue( int ownerDraw ) 
     3682{ 
     3683  return 0.0f; 
    53153684} 
    53163685 
     
    53213690================= 
    53223691*/ 
    5323 void _UI_Init( qboolean inGameLoad ) { 
     3692void UI_Init( qboolean inGameLoad ) 
     3693{ 
    53243694  int start; 
    53253695 
     
    53273697  BG_InitAllowedGameElements( ); 
    53283698 
    5329   //uiInfo.inGameLoad = inGameLoad; 
     3699  uiInfo.inGameLoad = inGameLoad; 
    53303700 
    53313701  UI_RegisterCvars(); 
     
    53363706 
    53373707  // for 640x480 virtualized screen 
    5338   uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0/480.0); 
    5339   uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0/640.0); 
    5340   if ( uiInfo.uiDC.glconfig.vidWidth * 480 > uiInfo.uiDC.glconfig.vidHeight * 640 ) { 
    5341     // wide screen 
    5342     uiInfo.uiDC.bias = 0.5 * ( uiInfo.uiDC.glconfig.vidWidth - ( uiInfo.uiDC.glconfig.vidHeight * (640.0/480.0) ) ); 
    5343   } 
    5344   else { 
    5345     // no wide screen 
    5346     uiInfo.uiDC.bias = 0; 
    5347   } 
    5348  
    5349  
    5350   //UI_Load(); 
     3708  uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * ( 1.0f / 480.0f ); 
     3709  uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * ( 1.0f / 640.0f ); 
     3710 
     3711  // wide screen 
     3712  uiInfo.uiDC.aspectScale = ( ( 640.0f * uiInfo.uiDC.glconfig.vidHeight ) / 
     3713      ( 480.0f * uiInfo.uiDC.glconfig.vidWidth ) ); 
     3714 
    53513715  uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip; 
    53523716  uiInfo.uiDC.setColor = &UI_SetColor; 
    53533717  uiInfo.uiDC.drawHandlePic = &UI_DrawHandlePic; 
    53543718  uiInfo.uiDC.drawStretchPic = &trap_R_DrawStretchPic; 
    5355   uiInfo.uiDC.drawText = &Text_Paint; 
    5356   uiInfo.uiDC.textWidth = &Text_Width; 
    5357   uiInfo.uiDC.textHeight = &Text_Height; 
    53583719  uiInfo.uiDC.registerModel = &trap_R_RegisterModel; 
    53593720  uiInfo.uiDC.modelBounds = &trap_R_ModelBounds; 
    53603721  uiInfo.uiDC.fillRect = &UI_FillRect; 
    5361   uiInfo.uiDC.drawRect = &_UI_DrawRect; 
    5362   uiInfo.uiDC.drawSides = &_UI_DrawSides; 
    5363   uiInfo.uiDC.drawTopBottom = &_UI_DrawTopBottom; 
     3722  uiInfo.uiDC.drawRect = &UI_DrawRect; 
     3723  uiInfo.uiDC.drawSides = &UI_DrawSides; 
     3724  uiInfo.uiDC.drawTopBottom = &UI_DrawTopBottom; 
    53643725  uiInfo.uiDC.clearScene = &trap_R_ClearScene; 
    5365   uiInfo.uiDC.drawSides = &_UI_DrawSides; 
     3726  uiInfo.uiDC.drawSides = &UI_DrawSides; 
    53663727  uiInfo.uiDC.addRefEntityToScene = &trap_R_AddRefEntityToScene; 
    53673728  uiInfo.uiDC.renderScene = &trap_R_RenderScene; 
     
    53713732  uiInfo.uiDC.ownerDrawVisible = &UI_OwnerDrawVisible; 
    53723733  uiInfo.uiDC.runScript = &UI_RunMenuScript; 
    5373   uiInfo.uiDC.getTeamColor = &UI_GetTeamColor; 
    53743734  uiInfo.uiDC.setCVar = trap_Cvar_Set; 
    53753735  uiInfo.uiDC.getCVarString = trap_Cvar_VariableStringBuffer; 
    53763736  uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue; 
    5377   uiInfo.uiDC.drawTextWithCursor = &Text_PaintWithCursor; 
    53783737  uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode; 
    53793738  uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode; 
     
    53923751  uiInfo.uiDC.Pause = &UI_Pause; 
    53933752  uiInfo.uiDC.ownerDrawWidth = &UI_OwnerDrawWidth; 
     3753  uiInfo.uiDC.ownerDrawText = &UI_OwnerDrawText; 
    53943754  uiInfo.uiDC.registerSound = &trap_S_RegisterSound; 
    53953755  uiInfo.uiDC.startBackgroundTrack = &trap_S_StartBackgroundTrack; 
     
    54003760  uiInfo.uiDC.runCinematicFrame = &UI_RunCinematicFrame; 
    54013761 
    5402   Init_Display(&uiInfo.uiDC); 
     3762  Init_Display( &uiInfo.uiDC ); 
    54033763 
    54043764  String_Init(); 
     
    54103770  start = trap_Milliseconds(); 
    54113771 
    5412   uiInfo.teamCount = 0; 
    5413   uiInfo.characterCount = 0; 
    5414   uiInfo.aliasCount = 0; 
    5415  
    5416   UI_LoadMenus("ui/menus.txt", qtrue); 
    5417   UI_LoadMenus("ui/ingame.txt", qfalse); 
    5418   UI_LoadMenus("ui/tremulous.txt", qfalse); 
     3772  UI_LoadMenus( "ui/menus.txt", qtrue ); 
     3773  UI_LoadMenus( "ui/ingame.txt", qfalse ); 
     3774  UI_LoadMenus( "ui/tremulous.txt", qfalse ); 
    54193775 
    54203776  Menus_CloseAll(); 
    54213777 
    54223778  trap_LAN_LoadCachedServers(); 
    5423   UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum); 
    54243779 
    54253780  // sets defaults for ui temp cvars 
    5426   uiInfo.effectsColor = gamecodetoui[(int)trap_Cvar_VariableValue("color1")-1]; 
    5427   uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue("cg_drawCrosshair"); 
    5428   trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1"); 
     3781  trap_Cvar_Set( "ui_mousePitch", ( trap_Cvar_VariableValue( "m_pitch" ) >= 0 ) ? "0" : "1" ); 
    54293782 
    54303783  uiInfo.serverStatus.currentServerCinematic = -1; 
    54313784  uiInfo.previewMovie = -1; 
    54323785 
    5433   if (trap_Cvar_VariableValue("ui_TeamArenaFirstRun") == 0) { 
    5434     trap_Cvar_Set("s_volume", "0.8"); 
    5435     trap_Cvar_Set("s_musicvolume", "0.5"); 
    5436     trap_Cvar_Set("ui_TeamArenaFirstRun", "1"); 
    5437   } 
    5438  
    5439   trap_Cvar_Register(NULL, "debug_protocol", "", 0 ); 
    5440  
    5441   trap_Cvar_Set("ui_actualNetGameType", va("%d", ui_netGameType.integer)); 
     3786  trap_Cvar_Register( NULL, "debug_protocol", "", 0 ); 
    54423787} 
    54433788 
     
    54483793================= 
    54493794*/ 
    5450 void _UI_KeyEvent( int key, qboolean down ) { 
    5451  
    5452   if (Menu_Count() > 0) { 
    5453     menuDef_t *menu = Menu_GetFocused(); 
    5454     if (menu) { 
    5455       if (key == K_ESCAPE && down && !Menus_AnyFullScreenVisible()) { 
     3795void UI_KeyEvent( int key, qboolean down ) 
     3796{ 
     3797  if( Menu_Count() > 0 ) 
     3798  { 
     3799    menuDef_t * menu = Menu_GetFocused(); 
     3800 
     3801    if( menu ) 
     3802    { 
     3803      if( key == K_ESCAPE && down && !Menus_AnyFullScreenVisible() ) 
    54563804        Menus_CloseAll(); 
    5457       } else { 
    5458         Menu_HandleKey(menu, key, down ); 
    5459       } 
    5460     } else { 
     3805      else 
     3806        Menu_HandleKey( menu, key, down ); 
     3807    } 
     3808    else 
     3809    { 
    54613810      trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
    54623811      trap_Key_ClearStates(); 
     
    54643813    } 
    54653814  } 
    5466  
    5467   //if ((s > 0) && (s != menu_null_sound)) { 
    5468   //  trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND ); 
    5469   //} 
    54703815} 
    54713816 
     
    54753820================= 
    54763821*/ 
    5477 void _UI_MouseEvent( int dx, int dy ) 
     3822void UI_MouseEvent( int dx, int dy ) 
    54783823{ 
    54793824  // update mouse screen position 
    5480   uiInfo.uiDC.cursorx += dx; 
    5481   if (uiInfo.uiDC.cursorx < 0) 
     3825  uiInfo.uiDC.cursorx += ( dx * uiInfo.uiDC.aspectScale ); 
     3826 
     3827  if( uiInfo.uiDC.cursorx < 0 ) 
    54823828    uiInfo.uiDC.cursorx = 0; 
    5483   else if (uiInfo.uiDC.cursorx > SCREEN_WIDTH) 
     3829  else if( uiInfo.uiDC.cursorx > SCREEN_WIDTH ) 
    54843830    uiInfo.uiDC.cursorx = SCREEN_WIDTH; 
    54853831 
    54863832  uiInfo.uiDC.cursory += dy; 
    5487   if (uiInfo.uiDC.cursory < 0) 
     3833 
     3834  if( uiInfo.uiDC.cursory < 0 ) 
    54883835    uiInfo.uiDC.cursory = 0; 
    5489   else if (uiInfo.uiDC.cursory > SCREEN_HEIGHT) 
     3836  else if( uiInfo.uiDC.cursory > SCREEN_HEIGHT ) 
    54903837    uiInfo.uiDC.cursory = SCREEN_HEIGHT; 
    54913838 
    5492   if (Menu_Count() > 0) { 
    5493     //menuDef_t *menu = Menu_GetFocused(); 
    5494     //Menu_HandleMouseMove(menu, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); 
    5495     Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); 
    5496   } 
    5497  
    5498 } 
    5499  
    5500 void UI_LoadNonIngame( void ) { 
    5501   UI_LoadMenus("ui/menus.txt", qfalse); 
    5502   uiInfo.inGameLoad = qfalse; 
    5503 } 
    5504  
    5505 void _UI_SetActiveMenu( uiMenuCommand_t menu ) { 
     3839  if( Menu_Count() > 0 ) 
     3840    Display_MouseMove( NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory ); 
     3841} 
     3842 
     3843void UI_SetActiveMenu( uiMenuCommand_t menu ) 
     3844{ 
    55063845  char buf[256]; 
    55073846 
    55083847  // this should be the ONLY way the menu system is brought up 
    55093848  // enusure minumum menu data is cached 
    5510   if (Menu_Count() > 0) { 
     3849 
     3850  if( Menu_Count() > 0 ) 
     3851  { 
    55113852    vec3_t v; 
    55123853    v[0] = v[1] = v[2] = 0; 
    5513     switch ( menu ) { 
    5514     case UIMENU_NONE: 
    5515       trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
    5516       trap_Key_ClearStates(); 
    5517       trap_Cvar_Set( "cl_paused", "0" ); 
    5518       Menus_CloseAll(); 
    5519  
    5520       return; 
    5521     case UIMENU_MAIN: 
    5522       trap_Cvar_Set( "sv_killserver", "1" ); 
    5523       trap_Key_SetCatcher( KEYCATCH_UI ); 
    5524       //trap_S_StartLocalSound( trap_S_RegisterSound("sound/misc/menu_background.wav", qfalse) , CHAN_LOCAL_SOUND ); 
    5525       //trap_S_StartBackgroundTrack("sound/misc/menu_background.wav", NULL); 
    5526       if (uiInfo.inGameLoad) { 
    5527         UI_LoadNonIngame(); 
    5528       } 
    5529       Menus_CloseAll(); 
    5530       Menus_ActivateByName("main"); 
    5531       trap_Cvar_Set( "ui_loading", "0" ); 
    5532       trap_Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf)); 
    5533       if (strlen(buf)) { 
    5534         if (!ui_singlePlayerActive.integer) { 
     3854 
     3855    switch( menu ) 
     3856    { 
     3857      case UIMENU_NONE: 
     3858        trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); 
     3859        trap_Key_ClearStates(); 
     3860        trap_Cvar_Set( "cl_paused", "0" ); 
     3861        Menus_CloseAll(); 
     3862 
     3863        return; 
     3864 
     3865      case UIMENU_MAIN: 
     3866        trap_Cvar_Set( "sv_killserver", "1" ); 
     3867        trap_Key_SetCatcher( KEYCATCH_UI ); 
     3868        Menus_CloseAll(); 
     3869        Menus_ActivateByName( "main" ); 
     3870        trap_Cvar_VariableStringBuffer( "com_errorMessage", buf, sizeof( buf ) ); 
     3871 
     3872        if( strlen( buf ) ) 
     3873        { 
    55353874          if( trap_Cvar_VariableValue( "com_errorCode" ) == ERR_SERVERDISCONNECT ) 
    5536             Menus_ActivateByName("drop_popmenu"); 
     3875            Menus_ActivateByName( "drop_popmenu" ); 
    55373876          else 
    5538             Menus_ActivateByName("error_popmenu"); 
    5539         } else { 
    5540           trap_Cvar_Set("com_errorMessage", ""); 
     3877            Menus_ActivateByName( "error_popmenu" ); 
    55413878        } 
    5542       } 
    5543       return; 
    5544     case UIMENU_TEAM: 
    5545       trap_Key_SetCatcher( KEYCATCH_UI ); 
    5546       Menus_ActivateByName("team"); 
    5547       return; 
    5548     case UIMENU_POSTGAME: 
    5549       trap_Cvar_Set( "sv_killserver", "1" ); 
    5550       trap_Key_SetCatcher( KEYCATCH_UI ); 
    5551       if (uiInfo.inGameLoad) { 
    5552         UI_LoadNonIngame(); 
    5553       } 
    5554       Menus_CloseAll(); 
    5555       Menus_ActivateByName("endofgame"); 
    5556       return; 
    5557     case UIMENU_INGAME: 
    5558       trap_Cvar_Set( "cl_paused", "1" ); 
    5559       trap_Key_SetCatcher( KEYCATCH_UI ); 
    5560       UI_BuildPlayerList(); 
    5561       Menus_CloseAll(); 
    5562       Menus_ActivateByName("ingame"); 
    5563       return; 
    5564     } 
    5565   } 
    5566 } 
    5567  
    5568 qboolean _UI_IsFullscreen( void ) { 
     3879 
     3880        return; 
     3881 
     3882      case UIMENU_INGAME: 
     3883        trap_Cvar_Set( "cl_paused", "1" ); 
     3884        trap_Key_SetCatcher( KEYCATCH_UI ); 
     3885        UI_BuildPlayerList(); 
     3886        Menus_CloseAll(); 
     3887        Menus_ActivateByName( "ingame" ); 
     3888        return; 
     3889    } 
     3890  } 
     3891} 
     3892 
     3893qboolean UI_IsFullscreen( void ) 
     3894{ 
    55693895  return Menus_AnyFullScreenVisible(); 
    55703896} 
     
    55773903static void UI_ReadableSize ( char *buf, int bufsize, int value ) 
    55783904{ 
    5579   if (value > 1024*1024*1024 ) { // gigs 
    5580     Com_sprintf( buf, bufsize, "%d", value / (1024*1024*1024) ); 
    5581     Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d GB", 
    5582       (value % (1024*1024*1024))*100 / (1024*1024*1024) ); 
    5583   } else if (value > 1024*1024 ) { // megs 
    5584     Com_sprintf( buf, bufsize, "%d", value / (1024*1024) ); 
    5585     Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d MB", 
    5586       (value % (1024*1024))*100 / (1024*1024) ); 
    5587   } else if (value > 1024 ) { // kilos 
     3905  if( value > 1024 * 1024 * 1024 ) 
     3906  { // gigs 
     3907    Com_sprintf( buf, bufsize, "%d", value / ( 1024 * 1024 * 1024 ) ); 
     3908    Com_sprintf( buf + strlen( buf ), bufsize - strlen( buf ), ".%02d GB", 
     3909        ( value % ( 1024 * 1024 * 1024 ) ) * 100 / ( 1024 * 1024 * 1024 ) ); 
     3910  } 
     3911  else if( value > 1024 * 1024 ) 
     3912  { // megs 
     3913    Com_sprintf( buf, bufsize, "%d", value / ( 1024 * 1024 ) ); 
     3914    Com_sprintf( buf + strlen( buf ), bufsize - strlen( buf ), ".%02d MB", 
     3915        ( value % ( 1024 * 1024 ) ) * 100 / ( 1024 * 1024 ) ); 
     3916  } 
     3917  else if( value > 1024 ) 
     3918  { // kilos 
    55883919    Com_sprintf( buf, bufsize, "%d KB", value / 1024 ); 
    5589   } else { // bytes 
     3920  } 
     3921  else 
     3922  { // bytes 
    55903923    Com_sprintf( buf, bufsize, "%d bytes", value ); 
    55913924  } 
     
    55933926 
    55943927// Assumes time is in msec 
    5595 static void UI_PrintTime ( char *buf, int bufsize, int time ) { 
     3928static void UI_PrintTime ( char *buf, int bufsize, int time ) 
     3929{ 
    55963930  time /= 1000;  // change to seconds 
    55973931 
    5598   if (time > 3600) { // in the hours range 
    5599     Com_sprintf( buf, bufsize, "%d hr %d min", time / 3600, (time % 3600) / 60 ); 
    5600   } else if (time > 60) { // mins 
     3932  if( time > 3600 ) 
     3933  { // in the hours range 
     3934    Com_sprintf( buf, bufsize, "%d hr %d min", time / 3600, ( time % 3600 ) / 60 ); 
     3935  } 
     3936  else if( time > 60 ) 
     3937  { // mins 
    56013938    Com_sprintf( buf, bufsize, "%d min %d sec", time / 60, time % 60 ); 
    5602   } else  { // secs 
     3939  } 
     3940  else 
     3941  { // secs 
    56033942    Com_sprintf( buf, bufsize, "%d sec", time ); 
    56043943  } 
    56053944} 
    56063945 
    5607 void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust) { 
    5608   int len = Text_Width(text, scale, 0); 
    5609   Text_Paint(x - len / 2, y, scale, color, text, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE); 
    5610 } 
    5611  
    5612 void Text_PaintCenter_AutoWrapped(float x, float y, float xmax, float ystep, float scale, vec4_t color, const char *str, float adjust) { 
     3946// FIXME: move to ui_shared.c? 
     3947void Text_PaintCenter( float x, float y, float scale, vec4_t color, const char *text, float adjust ) 
     3948{ 
     3949  int len = UI_Text_Width( text, scale, 0 ); 
     3950  UI_Text_Paint( x - len / 2, y, scale, color, text, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE ); 
     3951} 
     3952 
     3953void Text_PaintCenter_AutoWrapped( float x, float y, float xmax, float ystep, float scale, vec4_t color, const char *str, float adjust ) 
     3954{ 
    56133955  int width; 
    5614   char *s1,*s2,*s3; 
     3956  char *s1, *s2, *s3; 
    56153957  char c_bcp; 
    56163958  char buf[1024]; 
    56173959 
    5618   if (!str || str[0]=='\0') 
     3960  if( !str || str[0] == '\0' ) 
    56193961    return; 
    56203962 
    5621   Q_strncpyz(buf, str, sizeof(buf)); 
     3963  Q_strncpyz( buf, str, sizeof( buf ) ); 
     3964 
    56223965  s1 = s2 = s3 = buf; 
    56233966 
    5624   while (1) { 
    5625     do { 
     3967  while( 1 ) 
     3968  { 
     3969    do 
    56263970      s3++; 
    5627     } while (*s3!=' ' && *s3!='\0'); 
     3971    while( *s3 != ' ' && *s3 != '\0' ); 
     3972 
    56283973    c_bcp = *s3; 
     3974 
    56293975    *s3 = '\0'; 
    5630     width = Text_Width(s1, scale, 0); 
     3976 
     3977    width = UI_Text_Width( s1, scale, 0 ); 
     3978 
    56313979    *s3 = c_bcp; 
    5632     if (width > xmax) { 
    5633       if (s1==s2) 
     3980 
     3981    if( width > xmax ) 
     3982    { 
     3983      if( s1 == s2 ) 
    56343984      { 
    56353985        // fuck, don't have a clean cut, we'll overflow 
    56363986        s2 = s3; 
    56373987      } 
     3988 
    56383989      *s2 = '\0'; 
    5639       Text_PaintCenter(x, y, scale, color, s1, adjust); 
     3990      Text_PaintCenter( x, y, scale, color, s1, adjust ); 
    56403991      y += ystep; 
    5641       if (c_bcp == '\0') 
     3992 
     3993      if( c_bcp == '\0' ) 
    56423994      { 
    56433995        // that was the last word 
     
    56463998        // so just print it now if needed 
    56473999        s2++; 
    5648         if (*s2 != '\0') // if we are printing an overflowing line we have s2 == s3 
    5649           Text_PaintCenter(x, y, scale, color, s2, adjust); 
     4000 
     4001        if( *s2 != '\0' ) // if we are printing an overflowing line we have s2 == s3 
     4002          Text_PaintCenter( x, y, scale, color, s2, adjust ); 
     4003 
    56504004        break; 
    56514005      } 
     4006 
    56524007      s2++; 
    56534008      s1 = s2; 
     
    56574012    { 
    56584013      s2 = s3; 
    5659       if (c_bcp == '\0') // we reached the end 
    5660       { 
    5661         Text_PaintCenter(x, y, scale, color, s1, adjust); 
     4014 
     4015      if( c_bcp == '\0' ) // we reached the end 
     4016      { 
     4017        Text_PaintCenter( x, y, scale, color, s1, adjust ); 
    56624018        break; 
    56634019      } 
     
    56674023 
    56684024 
    5669 static void UI_DisplayDownloadInfo( const char *downloadName, float centerPoint, float yStart, float scale ) { 
     4025static void UI_DisplayDownloadInfo( const char *downloadName, float centerPoint, float yStart, float scale ) 
     4026{ 
    56704027  static char dlText[]  = "Downloading:"; 
    56714028  static char etaText[] = "Estimated time left:"; 
     
    56844041  leftWidth = 320; 
    56854042 
    5686   UI_SetColor(colorWhite); 
    5687   Text_PaintCenter(centerPoint, yStart + 112, scale, colorWhite, dlText, 0); 
    5688   Text_PaintCenter(centerPoint, yStart + 192, scale, colorWhite, etaText, 0); 
    5689   Text_PaintCenter(centerPoint, yStart + 248, scale, colorWhite, xferText, 0); 
    5690  
    5691   if (downloadSize > 0) { 
    5692     s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize ); 
    5693   } else { 
     4043  UI_SetColor( colorWhite ); 
     4044  Text_PaintCenter( centerPoint, yStart + 112, scale, colorWhite, dlText, 0 ); 
     4045  Text_PaintCenter( centerPoint, yStart + 192, scale, colorWhite, etaText, 0 ); 
     4046  Text_PaintCenter( centerPoint, yStart + 248, scale, colorWhite, xferText, 0 ); 
     4047 
     4048  if( downloadSize > 0 ) 
     4049    s = va( "%s (%d%%)", downloadName, ( int )( ( float )downloadCount * 100.0f / downloadSize ) ); 
     4050  else 
    56944051    s = downloadName; 
    5695   } 
    5696  
    5697   Text_PaintCenter(centerPoint, yStart+136, scale, colorWhite, s, 0); 
     4052 
     4053  Text_PaintCenter( centerPoint, yStart + 136, scale, colorWhite, s, 0 ); 
    56984054 
    56994055  UI_ReadableSize( dlSizeBuf,   sizeof dlSizeBuf,   downloadCount ); 
    57004056  UI_ReadableSize( totalSizeBuf,  sizeof totalSizeBuf,  downloadSize ); 
    57014057 
    5702   if (downloadCount < 4096 || !downloadTime) { 
    5703     Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0); 
    5704     Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0); 
    5705   } else { 
    5706     if ((uiInfo.uiDC.realTime - downloadTime) / 1000) { 
    5707       xferRate = downloadCount / ((uiInfo.uiDC.realTime - downloadTime) / 1000); 
    5708     } else { 
     4058  if( downloadCount < 4096 || !downloadTime ) 
     4059  { 
     4060    Text_PaintCenter( leftWidth, yStart + 216, scale, colorWhite, "estimating", 0 ); 
     4061    Text_PaintCenter( leftWidth, yStart + 160, scale, colorWhite, va( "(%s of %s copied)", dlSizeBuf, totalSizeBuf ), 0 ); 
     4062  } 
     4063  else 
     4064  { 
     4065    if( ( uiInfo.uiDC.realTime - downloadTime ) / 1000 ) 
     4066      xferRate = downloadCount / ( ( uiInfo.uiDC.realTime - downloadTime ) / 1000 ); 
     4067    else 
    57094068      xferRate = 0; 
    5710     } 
     4069 
    57114070    UI_ReadableSize( xferRateBuf, sizeof xferRateBuf, xferRate ); 
    57124071 
    57134072    // Extrapolate estimated completion time 
    5714     if (downloadSize && xferRate) { 
     4073 
     4074    if( downloadSize && xferRate ) 
     4075    { 
    57154076      int n = downloadSize / xferRate; // estimated time for entire d/l in secs 
    57164077 
    57174078      // We do it in K (/1024) because we'd overflow around 4MB 
    57184079      UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf, 
    5719         (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000); 
    5720  
    5721       Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, dlTimeBuf, 0); 
    5722       Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0); 
    5723     } else { 
    5724       Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0); 
    5725       if (downloadSize) { 
    5726         Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0); 
    5727       } else { 
    5728         Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s copied)", dlSizeBuf), 0); 
    5729       } 
    5730     } 
    5731  
    5732     if (xferRate) { 
    5733       Text_PaintCenter(leftWidth, yStart+272, scale, colorWhite, va("%s/Sec", xferRateBuf), 0); 
    5734     } 
     4080          ( n - ( ( ( downloadCount / 1024 ) * n ) / ( downloadSize / 1024 ) ) ) * 1000 ); 
     4081 
     4082      Text_PaintCenter( leftWidth, yStart + 216, scale, colorWhite, dlTimeBuf, 0 ); 
     4083      Text_PaintCenter( leftWidth, yStart + 160, scale, colorWhite, va( "(%s of %s copied)", dlSizeBuf, totalSizeBuf ), 0 ); 
     4084    } 
     4085    else 
     4086    { 
     4087      Text_PaintCenter( leftWidth, yStart + 216, scale, colorWhite, "estimating", 0 ); 
     4088 
     4089      if( downloadSize ) 
     4090        Text_PaintCenter( leftWidth, yStart + 160, scale, colorWhite, va( "(%s of %s copied)", dlSizeBuf, totalSizeBuf ), 0 ); 
     4091      else 
     4092        Text_PaintCenter( leftWidth, yStart + 160, scale, colorWhite, va( "(%s copied)", dlSizeBuf ), 0 ); 
     4093    } 
     4094 
     4095    if( xferRate ) 
     4096      Text_PaintCenter( leftWidth, yStart + 272, scale, colorWhite, va( "%s/Sec", xferRateBuf ), 0 ); 
    57354097  } 
    57364098} 
     
    57394101======================== 
    57404102UI_DrawConnectScreen 
    5741  
    5742 This will also be overlaid on the cgame info screen during loading 
    5743 to prevent it from blinking away too rapidly on local or lan games. 
    57444103======================== 
    57454104*/ 
    5746 void UI_DrawConnectScreen( qboolean overlay ) { 
    5747   char      *s; 
     4105void UI_DrawConnectScreen( qboolean overlay ) 
     4106{ 
     4107  char      * s; 
    57484108  uiClientState_t cstate; 
    57494109  char      info[MAX_INFO_VALUE]; 
     
    57514111  float centerPoint, yStart, scale; 
    57524112 
    5753   menuDef_t *menu = Menus_FindByName("Connect"); 
    5754  
    5755  
    5756   if ( !overlay && menu ) { 
    5757     Menu_Paint(menu, qtrue); 
    5758   } 
    5759  
    5760   if (!overlay) { 
     4113  menuDef_t *menu = Menus_FindByName( "Connect" ); 
     4114 
     4115 
     4116  if( !overlay && menu ) 
     4117    Menu_Paint( menu, qtrue ); 
     4118 
     4119  if( !overlay ) 
     4120  { 
    57614121    centerPoint = 320; 
    57624122    yStart = 130; 
    57634123    scale = 0.5f; 
    5764   } else { 
     4124  } 
     4125  else 
     4126  { 
    57654127    centerPoint = 320; 
    57664128    yStart = 32; 
     
    57734135 
    57744136  info[0] = '\0'; 
    5775   if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) { 
    5776     Text_PaintCenter(centerPoint, yStart, scale, colorWhite, va( "Loading %s", Info_ValueForKey( info, "mapname" )), 0); 
    5777   } 
    5778  
    5779   if (!Q_stricmp(cstate.servername,"localhost")) { 
    5780     Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, va("Starting up..."), ITEM_TEXTSTYLE_SHADOWEDMORE); 
    5781   } else { 
    5782     strcpy(text, va("Connecting to %s", cstate.servername)); 
    5783     Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite,text , ITEM_TEXTSTYLE_SHADOWEDMORE); 
     4137 
     4138  if( trap_GetConfigString( CS_SERVERINFO, info, sizeof( info ) ) ) 
     4139    Text_PaintCenter( centerPoint, yStart, scale, colorWhite, va( "Loading %s", Info_ValueForKey( info, "mapname" ) ), 0 ); 
     4140 
     4141  if( !Q_stricmp( cstate.servername, "localhost" ) ) 
     4142    Text_PaintCenter( centerPoint, yStart + 48, scale, colorWhite, va( "Starting up..." ), ITEM_TEXTSTYLE_SHADOWEDMORE ); 
     4143  else 
     4144  { 
     4145    strcpy( text, va( "Connecting to %s", cstate.servername ) ); 
     4146    Text_PaintCenter( centerPoint, yStart + 48, scale, colorWhite, text , ITEM_TEXTSTYLE_SHADOWEDMORE ); 
    57844147  } 
    57854148 
    57864149 
    57874150  // display global MOTD at bottom 
    5788   Text_PaintCenter(centerPoint, 600, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0); 
     4151  Text_PaintCenter( centerPoint, 600, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0 ); 
     4152 
    57894153  // print any server info (server full, bad version, etc) 
    5790   if ( cstate.connState < CA_CONNECTED ) { 
    5791     Text_PaintCenter_AutoWrapped(centerPoint, yStart + 176, 630, 20, scale, colorWhite, cstate.messageString, 0); 
    5792   } 
    5793  
    5794   if ( lastConnState > cstate.connState ) { 
     4154  if( cstate.connState < CA_CONNECTED ) 
     4155    Text_PaintCenter_AutoWrapped( centerPoint, yStart + 176, 630, 20, scale, colorWhite, cstate.messageString, 0 ); 
     4156 
     4157  if( lastConnState > cstate.connState ) 
    57954158    lastLoadingText[0] = '\0'; 
    5796   } 
     4159 
    57974160  lastConnState = cstate.connState; 
    57984161 
    5799   switch ( cstate.connState ) { 
    5800   case CA_CONNECTING: 
    5801     s = va("Awaiting connection...%i", cstate.connectPacketCount); 
    5802     break; 
    5803   case CA_CHALLENGING: 
    5804     s = va("Awaiting challenge...%i", cstate.connectPacketCount); 
    5805     break; 
    5806   case CA_CONNECTED: { 
    5807     char downloadName[MAX_INFO_VALUE]; 
    5808  
    5809       trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) ); 
    5810       if (*downloadName) { 
    5811         UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, scale ); 
    5812         return; 
    5813       } 
    5814     } 
    5815     s = "Awaiting gamestate..."; 
    5816     break; 
    5817   case CA_LOADING: 
    5818     return; 
    5819   case CA_PRIMED: 
    5820     return; 
    5821   default: 
    5822     return; 
    5823   } 
    5824  
    5825  
    5826   if (Q_stricmp(cstate.servername,"localhost")) { 
    5827     Text_PaintCenter(centerPoint, yStart + 80, scale, colorWhite, s, 0); 
    5828   } 
     4162  switch( cstate.connState ) 
     4163  { 
     4164    case CA_CONNECTING: 
     4165      s = va( "Awaiting connection...%i", cstate.connectPacketCount ); 
     4166      break; 
     4167 
     4168    case CA_CHALLENGING: 
     4169      s = va( "Awaiting challenge...%i", cstate.connectPacketCount ); 
     4170      break; 
     4171 
     4172    case CA_CONNECTED: 
     4173      { 
     4174        char downloadName[MAX_INFO_VALUE]; 
     4175 
     4176        trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof( downloadName ) ); 
     4177 
     4178        if( *downloadName ) 
     4179        { 
     4180          UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, scale ); 
     4181          return; 
     4182        } 
     4183      } 
     4184 
     4185      s = "Awaiting gamestate..."; 
     4186      break; 
     4187 
     4188    case CA_LOADING: 
     4189      return; 
     4190 
     4191    case CA_PRIMED: 
     4192      return; 
     4193 
     4194    default: 
     4195      return; 
     4196  } 
     4197 
     4198 
     4199  if( Q_stricmp( cstate.servername, "localhost" ) ) 
     4200    Text_PaintCenter( centerPoint, yStart + 80, scale, colorWhite, s, 0 ); 
    58294201 
    58304202  // password required / connection rejected information goes here 
    58314203} 
    5832  
    5833  
    5834 /* 
    5835 ================ 
    5836 cvars 
    5837 ================ 
    5838 */ 
    5839  
    5840 typedef struct { 
    5841   vmCvar_t  *vmCvar; 
    5842   char    *cvarName; 
    5843   char    *defaultString; 
    5844   int     cvarFlags; 
    5845 } cvarTable_t; 
    5846  
    5847 vmCvar_t  ui_ffa_fraglimit; 
    5848 vmCvar_t  ui_ffa_timelimit; 
    5849  
    5850 vmCvar_t  ui_tourney_fraglimit; 
    5851 vmCvar_t  ui_tourney_timelimit; 
    5852  
    5853 vmCvar_t  ui_team_fraglimit; 
    5854 vmCvar_t  ui_team_timelimit; 
    5855 vmCvar_t  ui_team_friendly; 
    5856  
    5857 vmCvar_t  ui_ctf_capturelimit; 
    5858 vmCvar_t  ui_ctf_timelimit; 
    5859 vmCvar_t  ui_ctf_friendly; 
    5860  
    5861 vmCvar_t  ui_arenasFile; 
    5862 vmCvar_t  ui_botsFile; 
    5863 vmCvar_t  ui_spScores1; 
    5864 vmCvar_t  ui_spScores2; 
    5865 vmCvar_t  ui_spScores3; 
    5866 vmCvar_t  ui_spScores4; 
    5867 vmCvar_t  ui_spScores5; 
    5868 vmCvar_t  ui_spAwards; 
    5869 vmCvar_t  ui_spVideos; 
    5870 vmCvar_t  ui_spSkill; 
    5871  
    5872 vmCvar_t  ui_spSelection; 
    5873  
    5874 vmCvar_t  ui_browserMaster; 
    5875 vmCvar_t  ui_browserGameType; 
    5876 vmCvar_t  ui_browserSortKey; 
    5877 vmCvar_t  ui_browserShowFull; 
    5878 vmCvar_t  ui_browserShowEmpty; 
    5879  
    5880 vmCvar_t  ui_brassTime; 
    5881 vmCvar_t  ui_drawCrosshair; 
    5882 vmCvar_t  ui_drawCrosshairNames; 
    5883 vmCvar_t  ui_marks; 
    5884  
    5885 vmCvar_t  ui_server1; 
    5886 vmCvar_t  ui_server2; 
    5887 vmCvar_t  ui_server3; 
    5888 vmCvar_t  ui_server4; 
    5889 vmCvar_t  ui_server5; 
    5890 vmCvar_t  ui_server6; 
    5891 vmCvar_t  ui_server7; 
    5892 vmCvar_t  ui_server8; 
    5893 vmCvar_t  ui_server9; 
    5894 vmCvar_t  ui_server10; 
    5895 vmCvar_t  ui_server11; 
    5896 vmCvar_t  ui_server12; 
    5897 vmCvar_t  ui_server13; 
    5898 vmCvar_t  ui_server14; 
    5899 vmCvar_t  ui_server15; 
    5900 vmCvar_t  ui_server16; 
    5901  
    5902 vmCvar_t  ui_redteam; 
    5903 vmCvar_t  ui_redteam1; 
    5904 vmCvar_t  ui_redteam2; 
    5905 vmCvar_t  ui_redteam3; 
    5906 vmCvar_t  ui_redteam4; 
    5907 vmCvar_t  ui_redteam5; 
    5908 vmCvar_t  ui_blueteam; 
    5909 vmCvar_t  ui_blueteam1; 
    5910 vmCvar_t  ui_blueteam2; 
    5911 vmCvar_t  ui_blueteam3; 
    5912 vmCvar_t  ui_blueteam4; 
    5913 vmCvar_t  ui_blueteam5; 
    5914 vmCvar_t  ui_teamName; 
    5915 vmCvar_t  ui_dedicated; 
    5916 vmCvar_t  ui_gameType; 
    5917 vmCvar_t  ui_netGameType; 
    5918 vmCvar_t  ui_actualNetGameType; 
    5919 vmCvar_t  ui_joinGameType; 
    5920 vmCvar_t  ui_netSource; 
    5921 vmCvar_t  ui_serverFilterType; 
    5922 vmCvar_t  ui_opponentName; 
    5923 vmCvar_t  ui_menuFiles; 
    5924 vmCvar_t  ui_currentTier; 
    5925 vmCvar_t  ui_currentMap; 
    5926 vmCvar_t  ui_currentNetMap; 
    5927 vmCvar_t  ui_mapIndex; 
    5928 vmCvar_t  ui_currentOpponent; 
    5929 vmCvar_t  ui_selectedPlayer; 
    5930 vmCvar_t  ui_selectedPlayerName; 
    5931 vmCvar_t  ui_lastServerRefresh_0; 
    5932 vmCvar_t  ui_lastServerRefresh_1; 
    5933 vmCvar_t  ui_lastServerRefresh_2; 
    5934 vmCvar_t  ui_lastServerRefresh_3; 
    5935 vmCvar_t  ui_lastServerRefresh_0_time; 
    5936 vmCvar_t  ui_lastServerRefresh_1_time; 
    5937 vmCvar_t  ui_lastServerRefresh_2_time; 
    5938 vmCvar_t  ui_lastServerRefresh_3_time; 
    5939 vmCvar_t  ui_singlePlayerActive; 
    5940 vmCvar_t  ui_scoreAccuracy; 
    5941 vmCvar_t  ui_scoreImpressives; 
    5942 vmCvar_t  ui_scoreExcellents; 
    5943 vmCvar_t  ui_scoreCaptures; 
    5944 vmCvar_t  ui_scoreDefends; 
    5945 vmCvar_t  ui_scoreAssists; 
    5946 vmCvar_t  ui_scoreGauntlets; 
    5947 vmCvar_t  ui_scoreScore; 
    5948 vmCvar_t  ui_scorePerfect; 
    5949 vmCvar_t  ui_scoreTeam; 
    5950 vmCvar_t  ui_scoreBase; 
    5951 vmCvar_t  ui_scoreTimeBonus; 
    5952 vmCvar_t  ui_scoreSkillBonus; 
    5953 vmCvar_t  ui_scoreShutoutBonus; 
    5954 vmCvar_t  ui_scoreTime; 
    5955 vmCvar_t  ui_captureLimit; 
    5956 vmCvar_t  ui_fragLimit; 
    5957 vmCvar_t  ui_smallFont; 
    5958 vmCvar_t  ui_bigFont; 
    5959 vmCvar_t  ui_findPlayer; 
    5960 vmCvar_t  ui_Q3Model; 
    5961 vmCvar_t  ui_hudFiles; 
    5962 vmCvar_t  ui_recordSPDemo; 
    5963 vmCvar_t  ui_realCaptureLimit; 
    5964 vmCvar_t  ui_realWarmUp; 
    5965 vmCvar_t  ui_serverStatusTimeOut; 
    5966  
    5967 vmCvar_t  ui_winner; 
    5968  
    5969 static cvarTable_t    cvarTable[] = { 
    5970   { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE }, 
    5971   { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", CVAR_ARCHIVE }, 
    5972  
    5973   { &ui_tourney_fraglimit, "ui_tourney_fraglimit", "0", CVAR_ARCHIVE }, 
    5974   { &ui_tourney_timelimit, "ui_tourney_timelimit", "15", CVAR_ARCHIVE }, 
    5975  
    5976   { &ui_team_fraglimit, "ui_team_fraglimit", "0", CVAR_ARCHIVE }, 
    5977   { &ui_team_timelimit, "ui_team_timelimit", "20", CVAR_ARCHIVE }, 
    5978   { &ui_team_friendly, "ui_team_friendly",  "1", CVAR_ARCHIVE }, 
    5979  
    5980   { &ui_ctf_capturelimit, "ui_ctf_capturelimit", "8", CVAR_ARCHIVE }, 
    5981   { &ui_ctf_timelimit, "ui_ctf_timelimit", "30", CVAR_ARCHIVE }, 
    5982   { &ui_ctf_friendly, "ui_ctf_friendly",  "0", CVAR_ARCHIVE }, 
    5983  
    5984   { &ui_arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM }, 
    5985   { &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM }, 
    5986   { &ui_spScores1, "g_spScores1", "", CVAR_ARCHIVE | CVAR_ROM }, 
    5987   { &ui_spScores2, "g_spScores2", "", CVAR_ARCHIVE | CVAR_ROM }, 
    5988   { &ui_spScores3, "g_spScores3", "", CVAR_ARCHIVE | CVAR_ROM }, 
    5989   { &ui_spScores4, "g_spScores4", "", CVAR_ARCHIVE | CVAR_ROM }, 
    5990   { &ui_spScores5, "g_spScores5", "", CVAR_ARCHIVE | CVAR_ROM }, 
    5991   { &ui_spAwards, "g_spAwards", "", CVAR_ARCHIVE | CVAR_ROM }, 
    5992   { &ui_spVideos, "g_spVideos", "", CVAR_ARCHIVE | CVAR_ROM }, 
    5993   { &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE }, 
    5994  
    5995   { &ui_spSelection, "ui_spSelection", "", CVAR_ROM }, 
    5996   { &ui_winner, "ui_winner", "", CVAR_ROM }, 
    5997  
    5998   { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE }, 
    5999   { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE }, 
    6000   { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE }, 
    6001   { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE }, 
    6002   { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE }, 
    6003  
    6004   { &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, 
    6005   { &ui_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, 
    6006   { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, 
    6007   { &ui_marks, "cg_marks", "1", CVAR_ARCHIVE }, 
    6008  
    6009   { &ui_server1, "server1", "", CVAR_ARCHIVE }, 
    6010   { &ui_server2, "server2", "", CVAR_ARCHIVE }, 
    6011   { &ui_server3, "server3", "", CVAR_ARCHIVE }, 
    6012   { &ui_server4, "server4", "", CVAR_ARCHIVE }, 
    6013   { &ui_server5, "server5", "", CVAR_ARCHIVE }, 
    6014   { &ui_server6, "server6", "", CVAR_ARCHIVE }, 
    6015   { &ui_server7, "server7", "", CVAR_ARCHIVE }, 
    6016   { &ui_server8, "server8", "", CVAR_ARCHIVE }, 
    6017   { &ui_server9, "server9", "", CVAR_ARCHIVE }, 
    6018   { &ui_server10, "server10", "", CVAR_ARCHIVE }, 
    6019   { &ui_server11, "server11", "", CVAR_ARCHIVE }, 
    6020   { &ui_server12, "server12", "", CVAR_ARCHIVE }, 
    6021   { &ui_server13, "server13", "", CVAR_ARCHIVE }, 
    6022   { &ui_server14, "server14", "", CVAR_ARCHIVE }, 
    6023   { &ui_server15, "server15", "", CVAR_ARCHIVE }, 
    6024   { &ui_server16, "server16", "", CVAR_ARCHIVE }, 
    6025   { &ui_new, "ui_new", "0", CVAR_TEMP }, 
    6026   { &ui_debug, "ui_debug", "0", CVAR_TEMP }, 
    6027   { &ui_initialized, "ui_initialized", "0", CVAR_TEMP }, 
    6028   { &ui_teamName, "ui_teamName", "Pagans", CVAR_ARCHIVE }, 
    6029   { &ui_opponentName, "ui_opponentName", "Stroggs", CVAR_ARCHIVE }, 
    6030   { &ui_redteam, "ui_redteam", "Pagans", CVAR_ARCHIVE }, 
    6031   { &ui_blueteam, "ui_blueteam", "Stroggs", CVAR_ARCHIVE }, 
    6032   { &ui_dedicated, "ui_dedicated", "0", CVAR_ARCHIVE }, 
    6033   { &ui_gameType, "ui_gametype", "3", CVAR_ARCHIVE }, 
    6034   { &ui_joinGameType, "ui_joinGametype", "0", CVAR_ARCHIVE }, 
    6035   { &ui_netGameType, "ui_netGametype", "3", CVAR_ARCHIVE }, 
    6036   { &ui_actualNetGameType, "ui_actualNetGametype", "3", CVAR_ARCHIVE }, 
    6037   { &ui_redteam1, "ui_redteam1", "0", CVAR_ARCHIVE }, 
    6038   { &ui_redteam2, "ui_redteam2", "0", CVAR_ARCHIVE }, 
    6039   { &ui_redteam3, "ui_redteam3", "0", CVAR_ARCHIVE }, 
    6040   { &ui_redteam4, "ui_redteam4", "0", CVAR_ARCHIVE }, 
    6041   { &ui_redteam5, "ui_redteam5", "0", CVAR_ARCHIVE }, 
    6042   { &ui_blueteam1, "ui_blueteam1", "0", CVAR_ARCHIVE }, 
    6043   { &ui_blueteam2, "ui_blueteam2", "0", CVAR_ARCHIVE }, 
    6044   { &ui_blueteam3, "ui_blueteam3", "0", CVAR_ARCHIVE }, 
    6045   { &ui_blueteam4, "ui_blueteam4", "0", CVAR_ARCHIVE }, 
    6046   { &ui_blueteam5, "ui_blueteam5", "0", CVAR_ARCHIVE }, 
    6047   { &ui_netSource, "ui_netSource", "0", CVAR_ARCHIVE }, 
    6048   { &ui_menuFiles, "ui_menuFiles", "ui/menus.txt", CVAR_ARCHIVE }, 
    6049   { &ui_currentTier, "ui_currentTier", "0", CVAR_ARCHIVE }, 
    6050   { &ui_currentMap, "ui_currentMap", "0", CVAR_ARCHIVE }, 
    6051   { &ui_currentNetMap, "ui_currentNetMap", "0", CVAR_ARCHIVE }, 
    6052   { &ui_mapIndex, "ui_mapIndex", "0", CVAR_ARCHIVE }, 
    6053   { &ui_currentOpponent, "ui_currentOpponent", "0", CVAR_ARCHIVE }, 
    6054   { &ui_selectedPlayer, "cg_selectedPlayer", "0", CVAR_ARCHIVE}, 
    6055   { &ui_selectedPlayerName, "cg_selectedPlayerName", "", CVAR_ARCHIVE}, 
    6056   { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0", "", CVAR_ARCHIVE}, 
    6057   { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1", "", CVAR_ARCHIVE}, 
    6058   { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2", "", CVAR_ARCHIVE}, 
    6059   { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3", "", CVAR_ARCHIVE}, 
    6060   { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0_time", "", CVAR_ARCHIVE}, 
    6061   { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1_time", "", CVAR_ARCHIVE}, 
    6062   { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2_time", "", CVAR_ARCHIVE}, 
    6063   { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3_time", "", CVAR_ARCHIVE}, 
    6064   { &ui_singlePlayerActive, "ui_singlePlayerActive", "0", 0}, 
    6065   { &ui_scoreAccuracy, "ui_scoreAccuracy", "0", CVAR_ARCHIVE}, 
    6066   { &ui_scoreImpressives, "ui_scoreImpressives", "0", CVAR_ARCHIVE}, 
    6067   { &ui_scoreExcellents, "ui_scoreExcellents", "0", CVAR_ARCHIVE}, 
    6068   { &ui_scoreCaptures, "ui_scoreCaptures", "0", CVAR_ARCHIVE}, 
    6069   { &ui_scoreDefends, "ui_scoreDefends", "0", CVAR_ARCHIVE}, 
    6070   { &ui_scoreAssists, "ui_scoreAssists", "0", CVAR_ARCHIVE}, 
    6071   { &ui_scoreGauntlets, "ui_scoreGauntlets", "0",CVAR_ARCHIVE}, 
    6072   { &ui_scoreScore, "ui_scoreScore", "0", CVAR_ARCHIVE}, 
    6073   { &ui_scorePerfect, "ui_scorePerfect", "0", CVAR_ARCHIVE}, 
    6074   { &ui_scoreTeam, "ui_scoreTeam", "0 to 0", CVAR_ARCHIVE}, 
    6075   { &ui_scoreBase, "ui_scoreBase", "0", CVAR_ARCHIVE}, 
    6076   { &ui_scoreTime, "ui_scoreTime", "00:00", CVAR_ARCHIVE}, 
    6077   { &ui_scoreTimeBonus, "ui_scoreTimeBonus", "0", CVAR_ARCHIVE}, 
    6078   { &ui_scoreSkillBonus, "ui_scoreSkillBonus", "0", CVAR_ARCHIVE}, 
    6079   { &ui_scoreShutoutBonus, "ui_scoreShutoutBonus", "0", CVAR_ARCHIVE}, 
    6080   { &ui_fragLimit, "ui_fragLimit", "10", 0}, 
    6081   { &ui_captureLimit, "ui_captureLimit", "5", 0}, 
    6082   { &ui_smallFont, "ui_smallFont", "0.2", CVAR_ARCHIVE}, 
    6083   { &ui_bigFont, "ui_bigFont", "0.5", CVAR_ARCHIVE}, 
    6084   { &ui_findPlayer, "ui_findPlayer", "Sarge", CVAR_ARCHIVE}, 
    6085   { &ui_Q3Model, "ui_q3model", "0", CVAR_ARCHIVE}, 
    6086   { &ui_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE}, 
    6087   { &ui_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE}, 
    6088   { &ui_teamArenaFirstRun, "ui_teamArenaFirstRun", "0", CVAR_ARCHIVE}, 
    6089   { &ui_realWarmUp, "g_warmup", "20", CVAR_ARCHIVE}, 
    6090   { &ui_realCaptureLimit, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART}, 
    6091   { &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE}, 
    6092 }; 
    6093  
    6094 static int    cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]); 
    6095  
    60964204 
    60974205/* 
     
    61004208================= 
    61014209*/ 
    6102 void UI_RegisterCvars( void ) { 
     4210void UI_RegisterCvars( void ) 
     4211{ 
    61034212  int     i; 
    61044213  cvarTable_t *cv; 
    61054214 
    6106   for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { 
     4215  for( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) 
    61074216    trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags ); 
    6108   } 
    61094217} 
    61104218 
     
    61144222================= 
    61154223*/ 
    6116 void UI_UpdateCvars( void ) { 
     4224void UI_UpdateCvars( void ) 
     4225{ 
    61174226  int     i; 
    61184227  cvarTable_t *cv; 
    61194228 
    6120   for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { 
     4229  for( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) 
    61214230    trap_Cvar_Update( cv->vmCvar ); 
    6122   } 
    6123 } 
    6124  
    6125  
    6126 /* 
    6127 ================= 
    6128 ArenaServers_StopRefresh 
    6129 ================= 
    6130 */ 
    6131 static void UI_StopServerRefresh( void ) 
    6132 { 
    6133   int count; 
    6134  
    6135   if (!uiInfo.serverStatus.refreshActive) { 
    6136     // not currently refreshing 
    6137     return; 
    6138   } 
    6139   uiInfo.serverStatus.refreshActive = qfalse; 
    6140   Com_Printf("%d servers listed in browser with %d players.\n", 
    6141           uiInfo.serverStatus.numDisplayServers, 
    6142           uiInfo.serverStatus.numPlayersOnServers); 
    6143   count = trap_LAN_GetServerCount(ui_netSource.integer); 
    6144   if (count - uiInfo.serverStatus.numDisplayServers > 0) { 
    6145     Com_Printf("%d servers not listed due to packet loss or pings higher than %d\n", 
    6146             count - uiInfo.serverStatus.numDisplayServers, 
    6147             (int) trap_Cvar_VariableValue("cl_maxPing")); 
    6148   } 
    6149  
    6150 } 
    6151  
    6152 /* 
    6153 ================= 
    6154 UI_DoServerRefresh 
    6155 ================= 
    6156 */ 
    6157 static void UI_DoServerRefresh( void ) 
    6158 { 
    6159   qboolean wait = qfalse; 
    6160  
    6161   if (!uiInfo.serverStatus.refreshActive) { 
    6162     return; 
    6163   } 
    6164   if (ui_netSource.integer != AS_FAVORITES) { 
    6165     if (ui_netSource.integer == AS_LOCAL) { 
    6166       if (!trap_LAN_GetServerCount(ui_netSource.integer)) { 
    6167         wait = qtrue; 
    6168       } 
    6169     } else { 
    6170       if (trap_LAN_GetServerCount(ui_netSource.integer) < 0) { 
    6171         wait = qtrue; 
    6172       } 
    6173     } 
    6174   } 
    6175  
    6176   if (uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime) { 
    6177     if (wait) { 
    6178       return; 
    6179     } 
    6180   } 
    6181  
    6182   // if still trying to retrieve pings 
    6183   if (trap_LAN_UpdateVisiblePings(ui_netSource.integer)) { 
    6184     uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; 
    6185   } else if (!wait) { 
    6186     // get the last servers in the list 
    6187     UI_BuildServerDisplayList(2); 
    6188     // stop the refresh 
    6189     UI_StopServerRefresh(); 
    6190   } 
    6191   // 
    6192   UI_BuildServerDisplayList(qfalse); 
    6193 } 
    6194  
    6195 /* 
    6196 ================= 
    6197 UI_StartServerRefresh 
    6198 ================= 
    6199 */ 
    6200 static void UI_StartServerRefresh(qboolean full) 
    6201 { 
    6202   int   i; 
    6203   char  *ptr; 
    6204   int   time; 
    6205   qtime_t q; 
    6206  
    6207   time = trap_RealTime(&q); 
    6208   trap_Cvar_Set( va("ui_lastServerRefresh_%i_time", ui_netSource.integer ), 
    6209                         va( "%i", time ) ); 
    6210   trap_Cvar_Set( va("ui_lastServerRefresh_%i", ui_netSource.integer), 
    6211                         va("%s-%i, %i at %i:%02i", MonthAbbrev[q.tm_mon],q.tm_mday, 1900+q.tm_year,q.tm_hour,q.tm_min)); 
    6212  
    6213   if (!full) { 
    6214     UI_UpdatePendingPings(); 
    6215     return; 
    6216   } 
    6217  
    6218   uiInfo.serverStatus.refreshActive = qtrue; 
    6219   uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 1000; 
    6220   // clear number of displayed servers 
    6221   uiInfo.serverStatus.numDisplayServers = 0; 
    6222   uiInfo.serverStatus.numPlayersOnServers = 0; 
    6223   // mark all servers as visible so we store ping updates for them 
    6224   trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue); 
    6225   // reset all the pings 
    6226   trap_LAN_ResetPings(ui_netSource.integer); 
    6227   // 
    6228   if( ui_netSource.integer == AS_LOCAL ) { 
    6229     trap_Cmd_ExecuteText( EXEC_NOW, "localservers\n" ); 
    6230     uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; 
    6231     return; 
    6232   } 
    6233  
    6234   uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000; 
    6235   if( ui_netSource.integer == AS_GLOBAL || ui_netSource.integer == AS_MPLAYER ) { 
    6236     if( ui_netSource.integer == AS_GLOBAL ) { 
    6237       i = 0; 
    6238     } 
    6239     else { 
    6240       i = 1; 
    6241     } 
    6242  
    6243     ptr = UI_Cvar_VariableString("debug_protocol"); 
    6244     if (strlen(ptr)) { 
    6245       trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %s full empty\n", i, ptr)); 
    6246     } 
    6247     else { 
    6248       trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %d full empty\n", i, (int)trap_Cvar_VariableValue( "protocol" ) ) ); 
    6249     } 
    6250   } 
    6251 } 
    6252  
     4231} 
  • src/ui/ui_public.h

    r119 r123  
    9595  UI_R_REGISTERFONT, 
    9696  UI_R_MODELBOUNDS, 
     97  UI_PARSE_ADD_GLOBAL_DEFINE, 
     98  UI_PARSE_LOAD_SOURCE, 
     99  UI_PARSE_FREE_SOURCE, 
     100  UI_PARSE_READ_TOKEN, 
     101  UI_PARSE_SOURCE_FILE_AND_LINE, 
    97102  UI_S_STOPBACKGROUNDTRACK, 
    98103  UI_S_STARTBACKGROUNDTRACK, 
     
    121126  UI_FS_SEEK, 
    122127  UI_SET_PBCLSTATUS, 
    123  
    124   UI_PARSE_ADD_GLOBAL_DEFINE, 
    125   UI_PARSE_LOAD_SOURCE, 
    126   UI_PARSE_FREE_SOURCE, 
    127   UI_PARSE_READ_TOKEN, 
    128   UI_PARSE_SOURCE_FILE_AND_LINE, 
    129128 
    130129  UI_MEMSET = 100, 
  • src/ui/ui_public.h

    r1 r123  
    33Copyright (C) 1999-2005 Id Software, Inc. 
    44Copyright (C) 2000-2006 Tim Angus 
    5  
     5  
    66This file is part of Tremulous. 
    7  
     7  
    88Tremulous is free software; you can redistribute it 
    99and/or modify it under the terms of the GNU General Public License as 
    1010published by the Free Software Foundation; either version 2 of the License, 
    1111or (at your option) any later version. 
    12  
     12  
    1313Tremulous is distributed in the hope that it will be 
    1414useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
    1515MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1616GNU General Public License for more details. 
    17  
     17  
    1818You should have received a copy of the GNU General Public License 
    1919along with Tremulous; if not, write to the Free Software 
     
    2222*/ 
    2323 
    24 #ifndef __UI_PUBLIC_H__ 
    25 #define __UI_PUBLIC_H__ 
     24#ifndef UI_PUBLIC_H 
     25#define UI_PUBLIC_H 
    2626 
    2727#define UI_API_VERSION  6 
    2828 
    29 typedef struct { 
     29typedef struct 
     30{ 
    3031  connstate_t   connState; 
    3132  int       connectPacketCount; 
     
    3435  char      updateInfoString[MAX_STRING_CHARS]; 
    3536  char      messageString[MAX_STRING_CHARS]; 
    36 } uiClientState_t; 
     37} 
     38uiClientState_t; 
    3739 
    38 typedef enum { 
     40typedef enum 
     41{ 
    3942  UI_ERROR, 
    4043  UI_PRINT, 
     
    133136  UI_FLOOR, 
    134137  UI_CEIL 
    135 } uiImport_t; 
     138} 
     139uiImport_t; 
    136140 
    137 typedef enum { 
     141typedef enum 
     142{ 
    138143  UIMENU_NONE, 
    139144  UIMENU_MAIN, 
    140   UIMENU_INGAME, 
    141   UIMENU_TEAM, 
    142   UIMENU_POSTGAME 
    143 } uiMenuCommand_t; 
     145  UIMENU_INGAME 
     146} 
     147uiMenuCommand_t; 
    144148 
    145149typedef enum 
     
    149153  SORT_CLIENTS, 
    150154  SORT_PING 
    151 } serverSortField_t; 
     155} 
     156serverSortField_t; 
    152157 
    153 typedef enum { 
     158typedef enum 
     159{ 
    154160  UI_GETAPIVERSION = 0, // system reserved 
    155161 
    156162  UI_INIT, 
    157 //  void  UI_Init( void ); 
     163  //  void  UI_Init( void ); 
    158164 
    159165  UI_SHUTDOWN, 
    160 //  void  UI_Shutdown( void ); 
     166  //  void  UI_Shutdown( void ); 
    161167 
    162168  UI_KEY_EVENT, 
    163 //  void  UI_KeyEvent( int key ); 
     169  //  void  UI_KeyEvent( int key ); 
    164170 
    165171  UI_MOUSE_EVENT, 
    166 //  void  UI_MouseEvent( int dx, int dy ); 
     172  //  void  UI_MouseEvent( int dx, int dy ); 
    167173 
    168174  UI_REFRESH, 
    169 //  void  UI_Refresh( int time ); 
     175  //  void  UI_Refresh( int time ); 
    170176 
    171177  UI_IS_FULLSCREEN, 
    172 //  qboolean UI_IsFullscreen( void ); 
     178  //  qboolean UI_IsFullscreen( void ); 
    173179 
    174180  UI_SET_ACTIVE_MENU, 
    175 //  void  UI_SetActiveMenu( uiMenuCommand_t menu ); 
     181  //  void  UI_SetActiveMenu( uiMenuCommand_t menu ); 
    176182 
    177183  UI_CONSOLE_COMMAND, 
    178 //  qboolean UI_ConsoleCommand( int realTime ); 
     184  //  qboolean UI_ConsoleCommand( int realTime ); 
    179185 
    180186  UI_DRAW_CONNECT_SCREEN 
    181 //  void  UI_DrawConnectScreen( qboolean overlay ); 
     187  //  void  UI_DrawConnectScreen( qboolean overlay ); 
    182188 
    183 // if !overlay, the background will be drawn, otherwise it will be 
    184 // overlayed over whatever the cgame has drawn. 
    185 // a GetClientState syscall will be made to get the current strings 
    186 } uiExport_t; 
     189  // if !overlay, the background will be drawn, otherwise it will be 
     190  // overlayed over whatever the cgame has drawn. 
     191  // a GetClientState syscall will be made to get the current strings 
     192} 
     193uiExport_t; 
    187194 
    188195#endif