~ubuntu-branches/ubuntu/hardy/openarena/hardy-backports

« back to all changes in this revision

Viewing changes to code/q3_ui/ui_servers2.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno "Fuddl" Kleinert
  • Date: 2007-01-20 12:28:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070120122809-2yza5ojt7nqiyiam
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
===========================================================================
 
3
Copyright (C) 1999-2005 Id Software, Inc.
 
4
 
 
5
This file is part of Quake III Arena source code.
 
6
 
 
7
Quake III Arena source code is free software; you can redistribute it
 
8
and/or modify it under the terms of the GNU General Public License as
 
9
published by the Free Software Foundation; either version 2 of the License,
 
10
or (at your option) any later version.
 
11
 
 
12
Quake III Arena source code is distributed in the hope that it will be
 
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with Quake III Arena source code; if not, write to the Free Software
 
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
20
===========================================================================
 
21
*/
 
22
//
 
23
/*
 
24
=======================================================================
 
25
 
 
26
MULTIPLAYER MENU (SERVER BROWSER)
 
27
 
 
28
=======================================================================
 
29
*/
 
30
 
 
31
 
 
32
#include "ui_local.h"
 
33
 
 
34
 
 
35
#define MAX_GLOBALSERVERS               128
 
36
#define MAX_PINGREQUESTS                32
 
37
#define MAX_ADDRESSLENGTH               64
 
38
#define MAX_HOSTNAMELENGTH              22
 
39
#define MAX_MAPNAMELENGTH               16
 
40
#define MAX_LISTBOXITEMS                128
 
41
#define MAX_LOCALSERVERS                128
 
42
#define MAX_STATUSLENGTH                64
 
43
#define MAX_LEAGUELENGTH                28
 
44
#define MAX_LISTBOXWIDTH                68
 
45
 
 
46
#define ART_BACK0                               "menu/art/back_0"
 
47
#define ART_BACK1                               "menu/art/back_1"
 
48
#define ART_CREATE0                             "menu/art/create_0"
 
49
#define ART_CREATE1                             "menu/art/create_1"
 
50
#define ART_SPECIFY0                    "menu/art/specify_0"
 
51
#define ART_SPECIFY1                    "menu/art/specify_1"
 
52
#define ART_REFRESH0                    "menu/art/refresh_0"
 
53
#define ART_REFRESH1                    "menu/art/refresh_1"
 
54
#define ART_CONNECT0                    "menu/art/fight_0"
 
55
#define ART_CONNECT1                    "menu/art/fight_1"
 
56
#define ART_ARROWS0                             "menu/art/arrows_vert_0"
 
57
#define ART_ARROWS_UP                   "menu/art/arrows_vert_top"
 
58
#define ART_ARROWS_DOWN                 "menu/art/arrows_vert_bot"
 
59
#define ART_UNKNOWNMAP                  "menu/art/unknownmap"
 
60
#define ART_REMOVE0                             "menu/art/delete_0"
 
61
#define ART_REMOVE1                             "menu/art/delete_1"
 
62
#define ART_PUNKBUSTER          "menu/art/pblogo"
 
63
 
 
64
#define ID_MASTER                       10
 
65
#define ID_GAMETYPE                     11
 
66
#define ID_SORTKEY                      12
 
67
#define ID_SHOW_FULL            13
 
68
#define ID_SHOW_EMPTY           14
 
69
#define ID_LIST                         15
 
70
#define ID_SCROLL_UP            16
 
71
#define ID_SCROLL_DOWN          17
 
72
#define ID_BACK                         18
 
73
#define ID_REFRESH                      19
 
74
#define ID_SPECIFY                      20
 
75
#define ID_CREATE                       21
 
76
#define ID_CONNECT                      22
 
77
#define ID_REMOVE                       23
 
78
#define ID_PUNKBUSTER 24
 
79
 
 
80
#define GR_LOGO                         30
 
81
#define GR_LETTERS                      31
 
82
 
 
83
#define AS_LOCAL                        0
 
84
#define AS_MPLAYER                      1
 
85
#define AS_GLOBAL                       2
 
86
#define AS_FAVORITES            3
 
87
 
 
88
#define SORT_HOST                       0
 
89
#define SORT_MAP                        1
 
90
#define SORT_CLIENTS            2
 
91
#define SORT_GAME                       3
 
92
#define SORT_PING                       4
 
93
 
 
94
#define GAMES_ALL                       0
 
95
#define GAMES_FFA                       1
 
96
#define GAMES_TEAMPLAY          2
 
97
#define GAMES_TOURNEY           3
 
98
#define GAMES_CTF                       4
 
99
 
 
100
static const char *master_items[] = {
 
101
        "Local",
 
102
        "Internet",
 
103
        "Favorites",
 
104
        NULL
 
105
};
 
106
 
 
107
static const char *servertype_items[] = {
 
108
        "All",
 
109
        "Free For All",
 
110
        "Team Deathmatch",
 
111
        "Tournament",
 
112
        "Capture the Flag",
 
113
        NULL
 
114
};
 
115
 
 
116
static const char *sortkey_items[] = {
 
117
        "Server Name",
 
118
        "Map Name",
 
119
        "Open Player Spots",
 
120
        "Game Type",
 
121
        "Ping Time",
 
122
        NULL
 
123
};
 
124
 
 
125
static char* gamenames[] = {
 
126
        "DM ",  // deathmatch
 
127
        "1v1",  // tournament
 
128
        "SP ",  // single player
 
129
        "Team DM",      // team deathmatch
 
130
        "CTF",  // capture the flag
 
131
        "One Flag CTF",         // one flag ctf
 
132
        "OverLoad",                             // Overload
 
133
        "Harvester",                    // Harvester
 
134
        "Rocket Arena 3",       // Rocket Arena 3
 
135
        "Q3F",                                          // Q3F
 
136
        "Urban Terror",         // Urban Terror
 
137
        "OSP",                                          // Orange Smoothie Productions
 
138
        "???",                  // unknown
 
139
        NULL
 
140
};
 
141
 
 
142
static char* netnames[] = {
 
143
        "???",
 
144
        "UDP",
 
145
        "IPX",
 
146
        NULL
 
147
};
 
148
 
 
149
static char quake3worldMessage[] = "Visit www.quake3world.com - News, Community, Events, Files";
 
150
 
 
151
const char* punkbuster_items[] = {
 
152
        "Disabled",
 
153
        "Enabled",
 
154
        NULL
 
155
};
 
156
 
 
157
const char* punkbuster_msg[] = {
 
158
        "PunkBuster will be",
 
159
        "disabled the next time",
 
160
        "Quake III Arena",
 
161
        "is started.",
 
162
        NULL
 
163
};
 
164
 
 
165
typedef struct {
 
166
        char    adrstr[MAX_ADDRESSLENGTH];
 
167
        int             start;
 
168
} pinglist_t;
 
169
 
 
170
typedef struct servernode_s {
 
171
        char    adrstr[MAX_ADDRESSLENGTH];
 
172
        char    hostname[MAX_HOSTNAMELENGTH+3];
 
173
        char    mapname[MAX_MAPNAMELENGTH];
 
174
        int             numclients;
 
175
        int             maxclients;
 
176
        int             pingtime;
 
177
        int             gametype;
 
178
        char    gamename[12];
 
179
        int             nettype;
 
180
        int             minPing;
 
181
        int             maxPing;
 
182
        qboolean bPB;
 
183
 
 
184
} servernode_t; 
 
185
 
 
186
typedef struct {
 
187
        char                    buff[MAX_LISTBOXWIDTH];
 
188
        servernode_t*   servernode;
 
189
} table_t;
 
190
 
 
191
typedef struct {
 
192
        menuframework_s         menu;
 
193
 
 
194
        menutext_s                      banner;
 
195
 
 
196
        menulist_s                      master;
 
197
        menulist_s                      gametype;
 
198
        menulist_s                      sortkey;
 
199
        menuradiobutton_s       showfull;
 
200
        menuradiobutton_s       showempty;
 
201
 
 
202
        menulist_s                      list;
 
203
        menubitmap_s            mappic;
 
204
        menubitmap_s            arrows;
 
205
        menubitmap_s            up;
 
206
        menubitmap_s            down;
 
207
        menutext_s                      status;
 
208
        menutext_s                      statusbar;
 
209
 
 
210
        menubitmap_s            remove;
 
211
        menubitmap_s            back;
 
212
        menubitmap_s            refresh;
 
213
        menubitmap_s            specify;
 
214
        menubitmap_s            create;
 
215
        menubitmap_s            go;
 
216
 
 
217
        pinglist_t                      pinglist[MAX_PINGREQUESTS];
 
218
        table_t                         table[MAX_LISTBOXITEMS];
 
219
        char*                           items[MAX_LISTBOXITEMS];
 
220
        int                                     numqueriedservers;
 
221
        int                                     *numservers;
 
222
        servernode_t            *serverlist;    
 
223
        int                                     currentping;
 
224
        qboolean                        refreshservers;
 
225
        int                                     nextpingtime;
 
226
        int                                     maxservers;
 
227
        int                                     refreshtime;
 
228
        char                            favoriteaddresses[MAX_FAVORITESERVERS][MAX_ADDRESSLENGTH];
 
229
        int                                     numfavoriteaddresses;
 
230
 
 
231
        menulist_s              punkbuster;
 
232
        menubitmap_s    pblogo;
 
233
} arenaservers_t;
 
234
 
 
235
static arenaservers_t   g_arenaservers;
 
236
 
 
237
 
 
238
static servernode_t             g_globalserverlist[MAX_GLOBALSERVERS];
 
239
static int                              g_numglobalservers;
 
240
static servernode_t             g_localserverlist[MAX_LOCALSERVERS];
 
241
static int                              g_numlocalservers;
 
242
static servernode_t             g_favoriteserverlist[MAX_FAVORITESERVERS];
 
243
static int                              g_numfavoriteservers;
 
244
static servernode_t             g_mplayerserverlist[MAX_GLOBALSERVERS];
 
245
static int                              g_nummplayerservers;
 
246
static int                              g_servertype;
 
247
static int                              g_gametype;
 
248
static int                              g_sortkey;
 
249
static int                              g_emptyservers;
 
250
static int                              g_fullservers;
 
251
 
 
252
 
 
253
/*
 
254
=================
 
255
ArenaServers_MaxPing
 
256
=================
 
257
*/
 
258
static int ArenaServers_MaxPing( void ) {
 
259
        int             maxPing;
 
260
 
 
261
        maxPing = (int)trap_Cvar_VariableValue( "cl_maxPing" );
 
262
        if( maxPing < 100 ) {
 
263
                maxPing = 100;
 
264
        }
 
265
        return maxPing;
 
266
}
 
267
 
 
268
 
 
269
/*
 
270
=================
 
271
ArenaServers_Compare
 
272
=================
 
273
*/
 
274
static int QDECL ArenaServers_Compare( const void *arg1, const void *arg2 ) {
 
275
        float                   f1;
 
276
        float                   f2;
 
277
        servernode_t*   t1;
 
278
        servernode_t*   t2;
 
279
 
 
280
        t1 = (servernode_t *)arg1;
 
281
        t2 = (servernode_t *)arg2;
 
282
 
 
283
        switch( g_sortkey ) {
 
284
        case SORT_HOST:
 
285
                return Q_stricmp( t1->hostname, t2->hostname );
 
286
 
 
287
        case SORT_MAP:
 
288
                return Q_stricmp( t1->mapname, t2->mapname );
 
289
 
 
290
        case SORT_CLIENTS:
 
291
                f1 = t1->maxclients - t1->numclients;
 
292
                if( f1 < 0 ) {
 
293
                        f1 = 0;
 
294
                }
 
295
 
 
296
                f2 = t2->maxclients - t2->numclients;
 
297
                if( f2 < 0 ) {
 
298
                        f2 = 0;
 
299
                }
 
300
 
 
301
                if( f1 < f2 ) {
 
302
                        return 1;
 
303
                }
 
304
                if( f1 == f2 ) {
 
305
                        return 0;
 
306
                }
 
307
                return -1;
 
308
 
 
309
        case SORT_GAME:
 
310
                if( t1->gametype < t2->gametype ) {
 
311
                        return -1;
 
312
                }
 
313
                if( t1->gametype == t2->gametype ) {
 
314
                        return 0;
 
315
                }
 
316
                return 1;
 
317
 
 
318
        case SORT_PING:
 
319
                if( t1->pingtime < t2->pingtime ) {
 
320
                        return -1;
 
321
                }
 
322
                if( t1->pingtime > t2->pingtime ) {
 
323
                        return 1;
 
324
                }
 
325
                return Q_stricmp( t1->hostname, t2->hostname );
 
326
        }
 
327
 
 
328
        return 0;
 
329
}
 
330
 
 
331
 
 
332
/*
 
333
=================
 
334
ArenaServers_Go
 
335
=================
 
336
*/
 
337
static void ArenaServers_Go( void ) {
 
338
        servernode_t*   servernode;
 
339
 
 
340
        servernode = g_arenaservers.table[g_arenaservers.list.curvalue].servernode;
 
341
        if( servernode ) {
 
342
                trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", servernode->adrstr ) );
 
343
        }
 
344
}
 
345
 
 
346
 
 
347
/*
 
348
=================
 
349
ArenaServers_UpdatePicture
 
350
=================
 
351
*/
 
352
static void ArenaServers_UpdatePicture( void ) {
 
353
        static char             picname[64];
 
354
        servernode_t*   servernodeptr;
 
355
 
 
356
        if( !g_arenaservers.list.numitems ) {
 
357
                g_arenaservers.mappic.generic.name = NULL;
 
358
        }
 
359
        else {
 
360
                servernodeptr = g_arenaservers.table[g_arenaservers.list.curvalue].servernode;
 
361
                Com_sprintf( picname, sizeof(picname), "levelshots/%s.tga", servernodeptr->mapname );
 
362
                g_arenaservers.mappic.generic.name = picname;
 
363
        
 
364
        }
 
365
 
 
366
        // force shader update during draw
 
367
        g_arenaservers.mappic.shader = 0;
 
368
}
 
369
 
 
370
 
 
371
/*
 
372
=================
 
373
ArenaServers_UpdateMenu
 
374
=================
 
375
*/
 
376
static void ArenaServers_UpdateMenu( void ) {
 
377
        int                             i;
 
378
        int                             j;
 
379
        int                             count;
 
380
        char*                   buff;
 
381
        servernode_t*   servernodeptr;
 
382
        table_t*                tableptr;
 
383
        char                    *pingColor;
 
384
 
 
385
        if( g_arenaservers.numqueriedservers > 0 ) {
 
386
                // servers found
 
387
                if( g_arenaservers.refreshservers && ( g_arenaservers.currentping <= g_arenaservers.numqueriedservers ) ) {
 
388
                        // show progress
 
389
                        Com_sprintf( g_arenaservers.status.string, MAX_STATUSLENGTH, "%d of %d Arena Servers.", g_arenaservers.currentping, g_arenaservers.numqueriedservers);
 
390
                        g_arenaservers.statusbar.string  = "Press SPACE to stop";
 
391
                        qsort( g_arenaservers.serverlist, *g_arenaservers.numservers, sizeof( servernode_t ), ArenaServers_Compare);
 
392
                }
 
393
                else {
 
394
                        // all servers pinged - enable controls
 
395
                        g_arenaservers.master.generic.flags             &= ~QMF_GRAYED;
 
396
                        g_arenaservers.gametype.generic.flags   &= ~QMF_GRAYED;
 
397
                        g_arenaservers.sortkey.generic.flags    &= ~QMF_GRAYED;
 
398
                        g_arenaservers.showempty.generic.flags  &= ~QMF_GRAYED;
 
399
                        g_arenaservers.showfull.generic.flags   &= ~QMF_GRAYED;
 
400
                        g_arenaservers.list.generic.flags               &= ~QMF_GRAYED;
 
401
                        g_arenaservers.refresh.generic.flags    &= ~QMF_GRAYED;
 
402
                        g_arenaservers.go.generic.flags                 &= ~QMF_GRAYED;
 
403
                        g_arenaservers.punkbuster.generic.flags &= ~QMF_GRAYED;
 
404
 
 
405
                        // update status bar
 
406
                        if( g_servertype == AS_GLOBAL || g_servertype == AS_MPLAYER ) {
 
407
                                g_arenaservers.statusbar.string = quake3worldMessage;
 
408
                        }
 
409
                        else {
 
410
                                g_arenaservers.statusbar.string = "";
 
411
                        }
 
412
 
 
413
                }
 
414
        }
 
415
        else {
 
416
                // no servers found
 
417
                if( g_arenaservers.refreshservers ) {
 
418
                        strcpy( g_arenaservers.status.string,"Scanning For Servers." );
 
419
                        g_arenaservers.statusbar.string = "Press SPACE to stop";
 
420
 
 
421
                        // disable controls during refresh
 
422
                        g_arenaservers.master.generic.flags             |= QMF_GRAYED;
 
423
                        g_arenaservers.gametype.generic.flags   |= QMF_GRAYED;
 
424
                        g_arenaservers.sortkey.generic.flags    |= QMF_GRAYED;
 
425
                        g_arenaservers.showempty.generic.flags  |= QMF_GRAYED;
 
426
                        g_arenaservers.showfull.generic.flags   |= QMF_GRAYED;
 
427
                        g_arenaservers.list.generic.flags               |= QMF_GRAYED;
 
428
                        g_arenaservers.refresh.generic.flags    |= QMF_GRAYED;
 
429
                        g_arenaservers.go.generic.flags                 |= QMF_GRAYED;
 
430
                        g_arenaservers.punkbuster.generic.flags |= QMF_GRAYED;
 
431
                }
 
432
                else {
 
433
                        if( g_arenaservers.numqueriedservers < 0 ) {
 
434
                                strcpy(g_arenaservers.status.string,"No Response From Master Server." );
 
435
                        }
 
436
                        else {
 
437
                                strcpy(g_arenaservers.status.string,"No Servers Found." );
 
438
                        }
 
439
 
 
440
                        // update status bar
 
441
                        if( g_servertype == AS_GLOBAL || g_servertype == AS_MPLAYER ) {
 
442
                                g_arenaservers.statusbar.string = quake3worldMessage;
 
443
                        }
 
444
                        else {
 
445
                                g_arenaservers.statusbar.string = "";
 
446
                        }
 
447
 
 
448
                        // end of refresh - set control state
 
449
                        g_arenaservers.master.generic.flags             &= ~QMF_GRAYED;
 
450
                        g_arenaservers.gametype.generic.flags   &= ~QMF_GRAYED;
 
451
                        g_arenaservers.sortkey.generic.flags    &= ~QMF_GRAYED;
 
452
                        g_arenaservers.showempty.generic.flags  &= ~QMF_GRAYED;
 
453
                        g_arenaservers.showfull.generic.flags   &= ~QMF_GRAYED;
 
454
                        g_arenaservers.list.generic.flags               |= QMF_GRAYED;
 
455
                        g_arenaservers.refresh.generic.flags    &= ~QMF_GRAYED;
 
456
                        g_arenaservers.go.generic.flags                 |= QMF_GRAYED;
 
457
                        g_arenaservers.punkbuster.generic.flags &= ~QMF_GRAYED;
 
458
                }
 
459
 
 
460
                // zero out list box
 
461
                g_arenaservers.list.numitems = 0;
 
462
                g_arenaservers.list.curvalue = 0;
 
463
                g_arenaservers.list.top      = 0;
 
464
 
 
465
                // update picture
 
466
                ArenaServers_UpdatePicture();
 
467
                return;
 
468
        }
 
469
 
 
470
        // build list box strings - apply culling filters
 
471
        servernodeptr = g_arenaservers.serverlist;
 
472
        count         = *g_arenaservers.numservers;
 
473
        for( i = 0, j = 0; i < count; i++, servernodeptr++ ) {
 
474
                tableptr = &g_arenaservers.table[j];
 
475
                tableptr->servernode = servernodeptr;
 
476
                buff = tableptr->buff;
 
477
 
 
478
                // can only cull valid results
 
479
                if( !g_emptyservers && !servernodeptr->numclients ) {
 
480
                        continue;
 
481
                }
 
482
 
 
483
                if( !g_fullservers && ( servernodeptr->numclients == servernodeptr->maxclients ) ) {
 
484
                        continue;
 
485
                }
 
486
 
 
487
                switch( g_gametype ) {
 
488
                case GAMES_ALL:
 
489
                        break;
 
490
 
 
491
                case GAMES_FFA:
 
492
                        if( servernodeptr->gametype != GT_FFA ) {
 
493
                                continue;
 
494
                        }
 
495
                        break;
 
496
 
 
497
                case GAMES_TEAMPLAY:
 
498
                        if( servernodeptr->gametype != GT_TEAM ) {
 
499
                                continue;
 
500
                        }
 
501
                        break;
 
502
 
 
503
                case GAMES_TOURNEY:
 
504
                        if( servernodeptr->gametype != GT_TOURNAMENT ) {
 
505
                                continue;
 
506
                        }
 
507
                        break;
 
508
 
 
509
                case GAMES_CTF:
 
510
                        if( servernodeptr->gametype != GT_CTF ) {
 
511
                                continue;
 
512
                        }
 
513
                        break;
 
514
                }
 
515
 
 
516
                if( servernodeptr->pingtime < servernodeptr->minPing ) {
 
517
                        pingColor = S_COLOR_BLUE;
 
518
                }
 
519
                else if( servernodeptr->maxPing && servernodeptr->pingtime > servernodeptr->maxPing ) {
 
520
                        pingColor = S_COLOR_BLUE;
 
521
                }
 
522
                else if( servernodeptr->pingtime < 200 ) {
 
523
                        pingColor = S_COLOR_GREEN;
 
524
                }
 
525
                else if( servernodeptr->pingtime < 400 ) {
 
526
                        pingColor = S_COLOR_YELLOW;
 
527
                }
 
528
                else {
 
529
                        pingColor = S_COLOR_RED;
 
530
                }
 
531
 
 
532
                Com_sprintf( buff, MAX_LISTBOXWIDTH, "%-20.20s %-12.12s %2d/%2d %-8.8s %3s %s%3d " S_COLOR_YELLOW "%s", 
 
533
                        servernodeptr->hostname, servernodeptr->mapname, servernodeptr->numclients,
 
534
                        servernodeptr->maxclients, servernodeptr->gamename,
 
535
                        netnames[servernodeptr->nettype], pingColor, servernodeptr->pingtime, servernodeptr->bPB ? "Yes" : "No" );
 
536
                j++;
 
537
        }
 
538
 
 
539
        g_arenaservers.list.numitems = j;
 
540
        g_arenaservers.list.curvalue = 0;
 
541
        g_arenaservers.list.top      = 0;
 
542
 
 
543
        // update picture
 
544
        ArenaServers_UpdatePicture();
 
545
}
 
546
 
 
547
 
 
548
/*
 
549
=================
 
550
ArenaServers_Remove
 
551
=================
 
552
*/
 
553
static void ArenaServers_Remove( void )
 
554
{
 
555
        int                             i;
 
556
        servernode_t*   servernodeptr;
 
557
        table_t*                tableptr;
 
558
 
 
559
        if (!g_arenaservers.list.numitems)
 
560
                return;
 
561
 
 
562
        // remove selected item from display list
 
563
        // items are in scattered order due to sort and cull
 
564
        // perform delete on list box contents, resync all lists
 
565
 
 
566
        tableptr      = &g_arenaservers.table[g_arenaservers.list.curvalue];
 
567
        servernodeptr = tableptr->servernode;
 
568
 
 
569
        // find address in master list
 
570
        for (i=0; i<g_arenaservers.numfavoriteaddresses; i++)
 
571
                if (!Q_stricmp(g_arenaservers.favoriteaddresses[i],servernodeptr->adrstr))
 
572
                                break;
 
573
 
 
574
        // delete address from master list
 
575
        if (i <= g_arenaservers.numfavoriteaddresses-1)
 
576
        {
 
577
                if (i < g_arenaservers.numfavoriteaddresses-1)
 
578
                {
 
579
                        // shift items up
 
580
                        memcpy( &g_arenaservers.favoriteaddresses[i], &g_arenaservers.favoriteaddresses[i+1], (g_arenaservers.numfavoriteaddresses - i - 1)*sizeof(MAX_ADDRESSLENGTH));
 
581
                }
 
582
                g_arenaservers.numfavoriteaddresses--;
 
583
        }       
 
584
 
 
585
        // find address in server list
 
586
        for (i=0; i<g_numfavoriteservers; i++)
 
587
                if (&g_favoriteserverlist[i] == servernodeptr)
 
588
                                break;
 
589
 
 
590
        // delete address from server list
 
591
        if (i <= g_numfavoriteservers-1)
 
592
        {
 
593
                if (i < g_numfavoriteservers-1)
 
594
                {
 
595
                        // shift items up
 
596
                        memcpy( &g_favoriteserverlist[i], &g_favoriteserverlist[i+1], (g_numfavoriteservers - i - 1)*sizeof(servernode_t));
 
597
                }
 
598
                g_numfavoriteservers--;
 
599
        }       
 
600
 
 
601
        g_arenaservers.numqueriedservers = g_arenaservers.numfavoriteaddresses;
 
602
        g_arenaservers.currentping       = g_arenaservers.numfavoriteaddresses;
 
603
}
 
604
 
 
605
 
 
606
/*
 
607
=================
 
608
ArenaServers_Insert
 
609
=================
 
610
*/
 
611
static void ArenaServers_Insert( char* adrstr, char* info, int pingtime )
 
612
{
 
613
        servernode_t*   servernodeptr;
 
614
        char*                   s;
 
615
        int                             i;
 
616
 
 
617
 
 
618
        if ((pingtime >= ArenaServers_MaxPing()) && (g_servertype != AS_FAVORITES))
 
619
        {
 
620
                // slow global or local servers do not get entered
 
621
                return;
 
622
        }
 
623
 
 
624
        if (*g_arenaservers.numservers >= g_arenaservers.maxservers) {
 
625
                // list full;
 
626
                servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers)-1;
 
627
        } else {
 
628
                // next slot
 
629
                servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers);
 
630
                (*g_arenaservers.numservers)++;
 
631
        }
 
632
 
 
633
        Q_strncpyz( servernodeptr->adrstr, adrstr, MAX_ADDRESSLENGTH );
 
634
 
 
635
        Q_strncpyz( servernodeptr->hostname, Info_ValueForKey( info, "hostname"), MAX_HOSTNAMELENGTH );
 
636
        Q_CleanStr( servernodeptr->hostname );
 
637
        Q_strupr( servernodeptr->hostname );
 
638
 
 
639
        Q_strncpyz( servernodeptr->mapname, Info_ValueForKey( info, "mapname"), MAX_MAPNAMELENGTH );
 
640
        Q_CleanStr( servernodeptr->mapname );
 
641
        Q_strupr( servernodeptr->mapname );
 
642
 
 
643
        servernodeptr->numclients = atoi( Info_ValueForKey( info, "clients") );
 
644
        servernodeptr->maxclients = atoi( Info_ValueForKey( info, "sv_maxclients") );
 
645
        servernodeptr->pingtime   = pingtime;
 
646
        servernodeptr->minPing    = atoi( Info_ValueForKey( info, "minPing") );
 
647
        servernodeptr->maxPing    = atoi( Info_ValueForKey( info, "maxPing") );
 
648
        servernodeptr->bPB = atoi( Info_ValueForKey( info, "punkbuster") );
 
649
 
 
650
        /*
 
651
        s = Info_ValueForKey( info, "nettype" );
 
652
        for (i=0; ;i++)
 
653
        {
 
654
                if (!netnames[i])
 
655
                {
 
656
                        servernodeptr->nettype = 0;
 
657
                        break;
 
658
                }
 
659
                else if (!Q_stricmp( netnames[i], s ))
 
660
                {
 
661
                        servernodeptr->nettype = i;
 
662
                        break;
 
663
                }
 
664
        }
 
665
        */
 
666
        servernodeptr->nettype = atoi(Info_ValueForKey(info, "nettype"));
 
667
 
 
668
        s = Info_ValueForKey( info, "game");
 
669
        i = atoi( Info_ValueForKey( info, "gametype") );
 
670
        if( i < 0 ) {
 
671
                i = 0;
 
672
        }
 
673
        else if( i > 11 ) {
 
674
                i = 12;
 
675
        }
 
676
        if( *s ) {
 
677
                servernodeptr->gametype = i;//-1;
 
678
                Q_strncpyz( servernodeptr->gamename, s, sizeof(servernodeptr->gamename) );
 
679
        }
 
680
        else {
 
681
                servernodeptr->gametype = i;
 
682
                Q_strncpyz( servernodeptr->gamename, gamenames[i], sizeof(servernodeptr->gamename) );
 
683
        }
 
684
}
 
685
 
 
686
 
 
687
/*
 
688
=================
 
689
ArenaServers_InsertFavorites
 
690
 
 
691
Insert nonresponsive address book entries into display lists.
 
692
=================
 
693
*/
 
694
void ArenaServers_InsertFavorites( void )
 
695
{
 
696
        int             i;
 
697
        int             j;
 
698
        char    info[MAX_INFO_STRING];
 
699
 
 
700
        // resync existing results with new or deleted cvars
 
701
        info[0] = '\0';
 
702
        Info_SetValueForKey( info, "hostname", "No Response" );
 
703
        for (i=0; i<g_arenaservers.numfavoriteaddresses; i++)
 
704
        {
 
705
                // find favorite address in refresh list
 
706
                for (j=0; j<g_numfavoriteservers; j++)
 
707
                        if (!Q_stricmp(g_arenaservers.favoriteaddresses[i],g_favoriteserverlist[j].adrstr))
 
708
                                break;
 
709
 
 
710
                if ( j >= g_numfavoriteservers)
 
711
                {
 
712
                        // not in list, add it
 
713
                        ArenaServers_Insert( g_arenaservers.favoriteaddresses[i], info, ArenaServers_MaxPing() );
 
714
                }
 
715
        }
 
716
}
 
717
 
 
718
 
 
719
/*
 
720
=================
 
721
ArenaServers_LoadFavorites
 
722
 
 
723
Load cvar address book entries into local lists.
 
724
=================
 
725
*/
 
726
void ArenaServers_LoadFavorites( void )
 
727
{
 
728
        int                             i;
 
729
        int                             j;
 
730
        int                             numtempitems;
 
731
        char                    emptyinfo[MAX_INFO_STRING];
 
732
        char                    adrstr[MAX_ADDRESSLENGTH];
 
733
        servernode_t    templist[MAX_FAVORITESERVERS];
 
734
        qboolean                found;
 
735
 
 
736
        found        = qfalse;
 
737
        emptyinfo[0] = '\0';
 
738
 
 
739
        // copy the old
 
740
        memcpy( templist, g_favoriteserverlist, sizeof(servernode_t)*MAX_FAVORITESERVERS );
 
741
        numtempitems = g_numfavoriteservers;
 
742
 
 
743
        // clear the current for sync
 
744
        memset( g_favoriteserverlist, 0, sizeof(servernode_t)*MAX_FAVORITESERVERS );
 
745
        g_numfavoriteservers = 0;
 
746
 
 
747
        // resync existing results with new or deleted cvars
 
748
        for (i=0; i<MAX_FAVORITESERVERS; i++)
 
749
        {
 
750
                trap_Cvar_VariableStringBuffer( va("server%d",i+1), adrstr, MAX_ADDRESSLENGTH );
 
751
                if (!adrstr[0])
 
752
                        continue;
 
753
 
 
754
                // quick sanity check to avoid slow domain name resolving
 
755
                // first character must be numeric
 
756
                if (adrstr[0] < '0' || adrstr[0] > '9')
 
757
                        continue;
 
758
 
 
759
                // favorite server addresses must be maintained outside refresh list
 
760
                // this mimics local and global netadr's stored in client
 
761
                // these can be fetched to fill ping list
 
762
                strcpy( g_arenaservers.favoriteaddresses[g_numfavoriteservers], adrstr );
 
763
 
 
764
                // find this server in the old list
 
765
                for (j=0; j<numtempitems; j++)
 
766
                        if (!Q_stricmp( templist[j].adrstr, adrstr ))
 
767
                                break;
 
768
 
 
769
                if (j < numtempitems)
 
770
                {
 
771
                        // found server - add exisiting results
 
772
                        memcpy( &g_favoriteserverlist[g_numfavoriteservers], &templist[j], sizeof(servernode_t) );
 
773
                        found = qtrue;
 
774
                }
 
775
                else
 
776
                {
 
777
                        // add new server
 
778
                        Q_strncpyz( g_favoriteserverlist[g_numfavoriteservers].adrstr, adrstr, MAX_ADDRESSLENGTH );
 
779
                        g_favoriteserverlist[g_numfavoriteservers].pingtime = ArenaServers_MaxPing();
 
780
                }
 
781
 
 
782
                g_numfavoriteservers++;
 
783
        }
 
784
 
 
785
        g_arenaservers.numfavoriteaddresses = g_numfavoriteservers;
 
786
 
 
787
        if (!found)
 
788
        {
 
789
                // no results were found, reset server list
 
790
                // list will be automatically refreshed when selected
 
791
                g_numfavoriteservers = 0;
 
792
        }
 
793
}
 
794
 
 
795
 
 
796
/*
 
797
=================
 
798
ArenaServers_StopRefresh
 
799
=================
 
800
*/
 
801
static void ArenaServers_StopRefresh( void )
 
802
{
 
803
        if (!g_arenaservers.refreshservers)
 
804
                // not currently refreshing
 
805
                return;
 
806
 
 
807
        g_arenaservers.refreshservers = qfalse;
 
808
 
 
809
        if (g_servertype == AS_FAVORITES)
 
810
        {
 
811
                // nonresponsive favorites must be shown
 
812
                ArenaServers_InsertFavorites();
 
813
        }
 
814
 
 
815
        // final tally
 
816
        if (g_arenaservers.numqueriedservers >= 0)
 
817
        {
 
818
                g_arenaservers.currentping       = *g_arenaservers.numservers;
 
819
                g_arenaservers.numqueriedservers = *g_arenaservers.numservers; 
 
820
        }
 
821
        
 
822
        // sort
 
823
        qsort( g_arenaservers.serverlist, *g_arenaservers.numservers, sizeof( servernode_t ), ArenaServers_Compare);
 
824
 
 
825
        ArenaServers_UpdateMenu();
 
826
}
 
827
 
 
828
 
 
829
/*
 
830
=================
 
831
ArenaServers_DoRefresh
 
832
=================
 
833
*/
 
834
static void ArenaServers_DoRefresh( void )
 
835
{
 
836
        int             i;
 
837
        int             j;
 
838
        int             time;
 
839
        int             maxPing;
 
840
        char    adrstr[MAX_ADDRESSLENGTH];
 
841
        char    info[MAX_INFO_STRING];
 
842
 
 
843
        if (uis.realtime < g_arenaservers.refreshtime)
 
844
        {
 
845
          if (g_servertype != AS_FAVORITES) {
 
846
                        if (g_servertype == AS_LOCAL) {
 
847
                                if (!trap_LAN_GetServerCount(g_servertype)) {
 
848
                                        return;
 
849
                                }
 
850
                        }
 
851
                        if (trap_LAN_GetServerCount(g_servertype) < 0) {
 
852
                          // still waiting for response
 
853
                          return;
 
854
                        }
 
855
          }
 
856
        }
 
857
 
 
858
        if (uis.realtime < g_arenaservers.nextpingtime)
 
859
        {
 
860
                // wait for time trigger
 
861
                return;
 
862
        }
 
863
 
 
864
        // trigger at 10Hz intervals
 
865
        g_arenaservers.nextpingtime = uis.realtime + 10;
 
866
 
 
867
        // process ping results
 
868
        maxPing = ArenaServers_MaxPing();
 
869
        for (i=0; i<MAX_PINGREQUESTS; i++)
 
870
        {
 
871
                trap_LAN_GetPing( i, adrstr, MAX_ADDRESSLENGTH, &time );
 
872
                if (!adrstr[0])
 
873
                {
 
874
                        // ignore empty or pending pings
 
875
                        continue;
 
876
                }
 
877
 
 
878
                // find ping result in our local list
 
879
                for (j=0; j<MAX_PINGREQUESTS; j++)
 
880
                        if (!Q_stricmp( adrstr, g_arenaservers.pinglist[j].adrstr ))
 
881
                                break;
 
882
 
 
883
                if (j < MAX_PINGREQUESTS)
 
884
                {
 
885
                        // found it
 
886
                        if (!time)
 
887
                        {
 
888
                                time = uis.realtime - g_arenaservers.pinglist[j].start;
 
889
                                if (time < maxPing)
 
890
                                {
 
891
                                        // still waiting
 
892
                                        continue;
 
893
                                }
 
894
                        }
 
895
 
 
896
                        if (time > maxPing)
 
897
                        {
 
898
                                // stale it out
 
899
                                info[0] = '\0';
 
900
                                time    = maxPing;
 
901
                        }
 
902
                        else
 
903
                        {
 
904
                                trap_LAN_GetPingInfo( i, info, MAX_INFO_STRING );
 
905
                        }
 
906
 
 
907
                        // insert ping results
 
908
                        ArenaServers_Insert( adrstr, info, time );
 
909
 
 
910
                        // clear this query from internal list
 
911
                        g_arenaservers.pinglist[j].adrstr[0] = '\0';
 
912
                }
 
913
 
 
914
                // clear this query from external list
 
915
                trap_LAN_ClearPing( i );
 
916
        }
 
917
 
 
918
        // get results of servers query
 
919
        // counts can increase as servers respond
 
920
        if (g_servertype == AS_FAVORITES) {
 
921
          g_arenaservers.numqueriedservers = g_arenaservers.numfavoriteaddresses;
 
922
        } else {
 
923
          g_arenaservers.numqueriedservers = trap_LAN_GetServerCount(g_servertype);
 
924
        }
 
925
 
 
926
//      if (g_arenaservers.numqueriedservers > g_arenaservers.maxservers)
 
927
//              g_arenaservers.numqueriedservers = g_arenaservers.maxservers;
 
928
 
 
929
        // send ping requests in reasonable bursts
 
930
        // iterate ping through all found servers
 
931
        for (i=0; i<MAX_PINGREQUESTS && g_arenaservers.currentping < g_arenaservers.numqueriedservers; i++)
 
932
        {
 
933
                if (trap_LAN_GetPingQueueCount() >= MAX_PINGREQUESTS)
 
934
                {
 
935
                        // ping queue is full
 
936
                        break;
 
937
                }
 
938
 
 
939
                // find empty slot
 
940
                for (j=0; j<MAX_PINGREQUESTS; j++)
 
941
                        if (!g_arenaservers.pinglist[j].adrstr[0])
 
942
                                break;
 
943
 
 
944
                if (j >= MAX_PINGREQUESTS)
 
945
                        // no empty slots available yet - wait for timeout
 
946
                        break;
 
947
 
 
948
                // get an address to ping
 
949
 
 
950
                if (g_servertype == AS_FAVORITES) {
 
951
                  strcpy( adrstr, g_arenaservers.favoriteaddresses[g_arenaservers.currentping] );               
 
952
                } else {
 
953
                  trap_LAN_GetServerAddressString(g_servertype, g_arenaservers.currentping, adrstr, MAX_ADDRESSLENGTH );
 
954
                }
 
955
 
 
956
                strcpy( g_arenaservers.pinglist[j].adrstr, adrstr );
 
957
                g_arenaservers.pinglist[j].start = uis.realtime;
 
958
 
 
959
                trap_Cmd_ExecuteText( EXEC_NOW, va( "ping %s\n", adrstr )  );
 
960
                
 
961
                // advance to next server
 
962
                g_arenaservers.currentping++;
 
963
        }
 
964
 
 
965
        if (!trap_LAN_GetPingQueueCount())
 
966
        {
 
967
                // all pings completed
 
968
                ArenaServers_StopRefresh();
 
969
                return;
 
970
        }
 
971
 
 
972
        // update the user interface with ping status
 
973
        ArenaServers_UpdateMenu();
 
974
}
 
975
 
 
976
 
 
977
/*
 
978
=================
 
979
ArenaServers_StartRefresh
 
980
=================
 
981
*/
 
982
static void ArenaServers_StartRefresh( void )
 
983
{
 
984
        int             i;
 
985
        char    myargs[32], protocol[32];
 
986
 
 
987
        memset( g_arenaservers.serverlist, 0, g_arenaservers.maxservers*sizeof(table_t) );
 
988
 
 
989
        for (i=0; i<MAX_PINGREQUESTS; i++)
 
990
        {
 
991
                g_arenaservers.pinglist[i].adrstr[0] = '\0';
 
992
                trap_LAN_ClearPing( i );
 
993
        }
 
994
 
 
995
        g_arenaservers.refreshservers    = qtrue;
 
996
        g_arenaservers.currentping       = 0;
 
997
        g_arenaservers.nextpingtime      = 0;
 
998
        *g_arenaservers.numservers       = 0;
 
999
        g_arenaservers.numqueriedservers = 0;
 
1000
 
 
1001
        // allow max 5 seconds for responses
 
1002
        g_arenaservers.refreshtime = uis.realtime + 5000;
 
1003
 
 
1004
        // place menu in zeroed state
 
1005
        ArenaServers_UpdateMenu();
 
1006
 
 
1007
        if( g_servertype == AS_LOCAL ) {
 
1008
                trap_Cmd_ExecuteText( EXEC_APPEND, "localservers\n" );
 
1009
                return;
 
1010
        }
 
1011
 
 
1012
        if( g_servertype == AS_GLOBAL || g_servertype == AS_MPLAYER ) {
 
1013
                if( g_servertype == AS_GLOBAL ) {
 
1014
                        i = 0;
 
1015
                }
 
1016
                else {
 
1017
                        i = 1;
 
1018
                }
 
1019
 
 
1020
                switch( g_arenaservers.gametype.curvalue ) {
 
1021
                default:
 
1022
                case GAMES_ALL:
 
1023
                        myargs[0] = 0;
 
1024
                        break;
 
1025
 
 
1026
                case GAMES_FFA:
 
1027
                        strcpy( myargs, " ffa" );
 
1028
                        break;
 
1029
 
 
1030
                case GAMES_TEAMPLAY:
 
1031
                        strcpy( myargs, " team" );
 
1032
                        break;
 
1033
 
 
1034
                case GAMES_TOURNEY:
 
1035
                        strcpy( myargs, " tourney" );
 
1036
                        break;
 
1037
 
 
1038
                case GAMES_CTF:
 
1039
                        strcpy( myargs, " ctf" );
 
1040
                        break;
 
1041
                }
 
1042
 
 
1043
 
 
1044
                if (g_emptyservers) {
 
1045
                        strcat(myargs, " empty");
 
1046
                }
 
1047
 
 
1048
                if (g_fullservers) {
 
1049
                        strcat(myargs, " full");
 
1050
                }
 
1051
 
 
1052
                protocol[0] = '\0';
 
1053
                trap_Cvar_VariableStringBuffer( "debug_protocol", protocol, sizeof(protocol) );
 
1054
                if (strlen(protocol)) {
 
1055
                        trap_Cmd_ExecuteText( EXEC_APPEND, va( "globalservers %d %s%s\n", i, protocol, myargs ));
 
1056
                }
 
1057
                else {
 
1058
                        trap_Cmd_ExecuteText( EXEC_APPEND, va( "globalservers %d %d%s\n", i, (int)trap_Cvar_VariableValue( "protocol" ), myargs ) );
 
1059
                }
 
1060
        }
 
1061
}
 
1062
 
 
1063
 
 
1064
/*
 
1065
=================
 
1066
ArenaServers_SaveChanges
 
1067
=================
 
1068
*/
 
1069
void ArenaServers_SaveChanges( void )
 
1070
{
 
1071
        int     i;
 
1072
 
 
1073
        for (i=0; i<g_arenaservers.numfavoriteaddresses; i++)
 
1074
                trap_Cvar_Set( va("server%d",i+1), g_arenaservers.favoriteaddresses[i] );
 
1075
 
 
1076
        for (; i<MAX_FAVORITESERVERS; i++)
 
1077
                trap_Cvar_Set( va("server%d",i+1), "" );
 
1078
}
 
1079
 
 
1080
 
 
1081
/*
 
1082
=================
 
1083
ArenaServers_Sort
 
1084
=================
 
1085
*/
 
1086
void ArenaServers_Sort( int type ) {
 
1087
        if( g_sortkey == type ) {
 
1088
                return;
 
1089
        }
 
1090
 
 
1091
        g_sortkey = type;
 
1092
        qsort( g_arenaservers.serverlist, *g_arenaservers.numservers, sizeof( servernode_t ), ArenaServers_Compare);
 
1093
}
 
1094
 
 
1095
 
 
1096
/*
 
1097
=================
 
1098
ArenaServers_SetType
 
1099
=================
 
1100
*/
 
1101
void ArenaServers_SetType( int type )
 
1102
{
 
1103
        if (g_servertype == type)
 
1104
                return;
 
1105
 
 
1106
        g_servertype = type;
 
1107
 
 
1108
        switch( type ) {
 
1109
        default:
 
1110
        case AS_LOCAL:
 
1111
                g_arenaservers.remove.generic.flags |= (QMF_INACTIVE|QMF_HIDDEN);
 
1112
                g_arenaservers.serverlist = g_localserverlist;
 
1113
                g_arenaservers.numservers = &g_numlocalservers;
 
1114
                g_arenaservers.maxservers = MAX_LOCALSERVERS;
 
1115
                break;
 
1116
 
 
1117
        case AS_GLOBAL:
 
1118
                g_arenaservers.remove.generic.flags |= (QMF_INACTIVE|QMF_HIDDEN);
 
1119
                g_arenaservers.serverlist = g_globalserverlist;
 
1120
                g_arenaservers.numservers = &g_numglobalservers;
 
1121
                g_arenaservers.maxservers = MAX_GLOBALSERVERS;
 
1122
                break;
 
1123
 
 
1124
        case AS_FAVORITES:
 
1125
                g_arenaservers.remove.generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN);
 
1126
                g_arenaservers.serverlist = g_favoriteserverlist;
 
1127
                g_arenaservers.numservers = &g_numfavoriteservers;
 
1128
                g_arenaservers.maxservers = MAX_FAVORITESERVERS;
 
1129
                break;
 
1130
 
 
1131
        case AS_MPLAYER:
 
1132
                g_arenaservers.remove.generic.flags |= (QMF_INACTIVE|QMF_HIDDEN);
 
1133
                g_arenaservers.serverlist = g_mplayerserverlist;
 
1134
                g_arenaservers.numservers = &g_nummplayerservers;
 
1135
                g_arenaservers.maxservers = MAX_GLOBALSERVERS;
 
1136
                break;
 
1137
                
 
1138
        }
 
1139
 
 
1140
        if( !*g_arenaservers.numservers ) {
 
1141
                ArenaServers_StartRefresh();
 
1142
        }
 
1143
        else {
 
1144
                // avoid slow operation, use existing results
 
1145
                g_arenaservers.currentping       = *g_arenaservers.numservers;
 
1146
                g_arenaservers.numqueriedservers = *g_arenaservers.numservers; 
 
1147
                ArenaServers_UpdateMenu();
 
1148
        }
 
1149
        strcpy(g_arenaservers.status.string,"hit refresh to update");
 
1150
}
 
1151
 
 
1152
/*
 
1153
=================
 
1154
PunkBuster_Confirm
 
1155
=================
 
1156
*/
 
1157
static void Punkbuster_ConfirmEnable( qboolean result ) {
 
1158
        if (result)
 
1159
        {               
 
1160
                trap_SetPbClStatus(1);
 
1161
        }
 
1162
        g_arenaservers.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "cl_punkbuster" ) );
 
1163
}
 
1164
 
 
1165
static void Punkbuster_ConfirmDisable( qboolean result ) {
 
1166
        if (result)
 
1167
        {
 
1168
                trap_SetPbClStatus(0);
 
1169
                UI_Message( punkbuster_msg );
 
1170
        }
 
1171
        g_arenaservers.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "cl_punkbuster" ) );
 
1172
}
 
1173
 
 
1174
/*
 
1175
=================
 
1176
ArenaServers_Event
 
1177
=================
 
1178
*/
 
1179
static void ArenaServers_Event( void* ptr, int event ) {
 
1180
        int             id;
 
1181
        int value;
 
1182
 
 
1183
        id = ((menucommon_s*)ptr)->id;
 
1184
 
 
1185
        if( event != QM_ACTIVATED && id != ID_LIST ) {
 
1186
                return;
 
1187
        }
 
1188
 
 
1189
        switch( id ) {
 
1190
        case ID_MASTER:
 
1191
                value = g_arenaservers.master.curvalue;
 
1192
                if (value >= 1)
 
1193
                {
 
1194
                        value++;
 
1195
                }
 
1196
                trap_Cvar_SetValue( "ui_browserMaster", value );
 
1197
                ArenaServers_SetType( value );
 
1198
                break;
 
1199
 
 
1200
        case ID_GAMETYPE:
 
1201
                trap_Cvar_SetValue( "ui_browserGameType", g_arenaservers.gametype.curvalue );
 
1202
                g_gametype = g_arenaservers.gametype.curvalue;
 
1203
                ArenaServers_UpdateMenu();
 
1204
                break;
 
1205
 
 
1206
        case ID_SORTKEY:
 
1207
                trap_Cvar_SetValue( "ui_browserSortKey", g_arenaservers.sortkey.curvalue );
 
1208
                ArenaServers_Sort( g_arenaservers.sortkey.curvalue );
 
1209
                ArenaServers_UpdateMenu();
 
1210
                break;
 
1211
 
 
1212
        case ID_SHOW_FULL:
 
1213
                trap_Cvar_SetValue( "ui_browserShowFull", g_arenaservers.showfull.curvalue );
 
1214
                g_fullservers = g_arenaservers.showfull.curvalue;
 
1215
                ArenaServers_UpdateMenu();
 
1216
                break;
 
1217
 
 
1218
        case ID_SHOW_EMPTY:
 
1219
                trap_Cvar_SetValue( "ui_browserShowEmpty", g_arenaservers.showempty.curvalue );
 
1220
                g_emptyservers = g_arenaservers.showempty.curvalue;
 
1221
                ArenaServers_UpdateMenu();
 
1222
                break;
 
1223
 
 
1224
        case ID_LIST:
 
1225
                if( event == QM_GOTFOCUS ) {
 
1226
                        ArenaServers_UpdatePicture();
 
1227
                }
 
1228
                break;
 
1229
 
 
1230
        case ID_SCROLL_UP:
 
1231
                ScrollList_Key( &g_arenaservers.list, K_UPARROW );
 
1232
                break;
 
1233
 
 
1234
        case ID_SCROLL_DOWN:
 
1235
                ScrollList_Key( &g_arenaservers.list, K_DOWNARROW );
 
1236
                break;
 
1237
 
 
1238
        case ID_BACK:
 
1239
                ArenaServers_StopRefresh();
 
1240
                ArenaServers_SaveChanges();
 
1241
                UI_PopMenu();
 
1242
                break;
 
1243
 
 
1244
        case ID_REFRESH:
 
1245
                ArenaServers_StartRefresh();
 
1246
                break;
 
1247
 
 
1248
        case ID_SPECIFY:
 
1249
                UI_SpecifyServerMenu();
 
1250
                break;
 
1251
 
 
1252
        case ID_CREATE:
 
1253
                UI_StartServerMenu( qtrue );
 
1254
                break;
 
1255
 
 
1256
        case ID_CONNECT:
 
1257
                ArenaServers_Go();
 
1258
                break;
 
1259
 
 
1260
        case ID_REMOVE:
 
1261
                ArenaServers_Remove();
 
1262
                ArenaServers_UpdateMenu();
 
1263
                break;
 
1264
        
 
1265
        case ID_PUNKBUSTER:
 
1266
                if (g_arenaservers.punkbuster.curvalue)                 
 
1267
                {
 
1268
                        UI_ConfirmMenu_Style( "Enable Punkbuster?",  UI_CENTER|UI_INVERSE|UI_SMALLFONT, 0, Punkbuster_ConfirmEnable );
 
1269
                }
 
1270
                else
 
1271
                {
 
1272
                        UI_ConfirmMenu_Style( "Disable Punkbuster?", UI_CENTER|UI_INVERSE|UI_SMALLFONT, 0, Punkbuster_ConfirmDisable );
 
1273
                }
 
1274
                break;
 
1275
        }
 
1276
}
 
1277
 
 
1278
 
 
1279
/*
 
1280
=================
 
1281
ArenaServers_MenuDraw
 
1282
=================
 
1283
*/
 
1284
static void ArenaServers_MenuDraw( void )
 
1285
{
 
1286
        if (g_arenaservers.refreshservers)
 
1287
                ArenaServers_DoRefresh();
 
1288
 
 
1289
        Menu_Draw( &g_arenaservers.menu );
 
1290
}
 
1291
 
 
1292
 
 
1293
/*
 
1294
=================
 
1295
ArenaServers_MenuKey
 
1296
=================
 
1297
*/
 
1298
static sfxHandle_t ArenaServers_MenuKey( int key ) {
 
1299
        if( key == K_SPACE  && g_arenaservers.refreshservers ) {
 
1300
                ArenaServers_StopRefresh();     
 
1301
                return menu_move_sound;
 
1302
        }
 
1303
 
 
1304
        if( ( key == K_DEL || key == K_KP_DEL ) && ( g_servertype == AS_FAVORITES ) &&
 
1305
                ( Menu_ItemAtCursor( &g_arenaservers.menu) == &g_arenaservers.list ) ) {
 
1306
                ArenaServers_Remove();
 
1307
                ArenaServers_UpdateMenu();
 
1308
                return menu_move_sound;
 
1309
        }
 
1310
 
 
1311
        if( key == K_MOUSE2 || key == K_ESCAPE ) {
 
1312
                ArenaServers_StopRefresh();
 
1313
                ArenaServers_SaveChanges();
 
1314
        }
 
1315
 
 
1316
 
 
1317
        return Menu_DefaultKey( &g_arenaservers.menu, key );
 
1318
}
 
1319
 
 
1320
 
 
1321
/*
 
1322
=================
 
1323
ArenaServers_MenuInit
 
1324
=================
 
1325
*/
 
1326
static void ArenaServers_MenuInit( void ) {
 
1327
        int                     i;
 
1328
        int                     type;
 
1329
        int                     y;
 
1330
        int                     value;
 
1331
        static char     statusbuffer[MAX_STATUSLENGTH];
 
1332
 
 
1333
        // zero set all our globals
 
1334
        memset( &g_arenaservers, 0 ,sizeof(arenaservers_t) );
 
1335
 
 
1336
        ArenaServers_Cache();
 
1337
 
 
1338
        g_arenaservers.menu.fullscreen = qtrue;
 
1339
        g_arenaservers.menu.wrapAround = qtrue;
 
1340
        g_arenaservers.menu.draw       = ArenaServers_MenuDraw;
 
1341
        g_arenaservers.menu.key        = ArenaServers_MenuKey;
 
1342
 
 
1343
        g_arenaservers.banner.generic.type  = MTYPE_BTEXT;
 
1344
        g_arenaservers.banner.generic.flags = QMF_CENTER_JUSTIFY;
 
1345
        g_arenaservers.banner.generic.x     = 320;
 
1346
        g_arenaservers.banner.generic.y     = 16;
 
1347
        g_arenaservers.banner.string            = "ARENA SERVERS";
 
1348
        g_arenaservers.banner.style         = UI_CENTER;
 
1349
        g_arenaservers.banner.color         = color_white;
 
1350
 
 
1351
        y = 80;
 
1352
        g_arenaservers.master.generic.type                      = MTYPE_SPINCONTROL;
 
1353
        g_arenaservers.master.generic.name                      = "Servers:";
 
1354
        g_arenaservers.master.generic.flags                     = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
 
1355
        g_arenaservers.master.generic.callback          = ArenaServers_Event;
 
1356
        g_arenaservers.master.generic.id                        = ID_MASTER;
 
1357
        g_arenaservers.master.generic.x                         = 320;
 
1358
        g_arenaservers.master.generic.y                         = y;
 
1359
        g_arenaservers.master.itemnames                         = master_items;
 
1360
 
 
1361
        y += SMALLCHAR_HEIGHT;
 
1362
        g_arenaservers.gametype.generic.type            = MTYPE_SPINCONTROL;
 
1363
        g_arenaservers.gametype.generic.name            = "Game Type:";
 
1364
        g_arenaservers.gametype.generic.flags           = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
 
1365
        g_arenaservers.gametype.generic.callback        = ArenaServers_Event;
 
1366
        g_arenaservers.gametype.generic.id                      = ID_GAMETYPE;
 
1367
        g_arenaservers.gametype.generic.x                       = 320;
 
1368
        g_arenaservers.gametype.generic.y                       = y;
 
1369
        g_arenaservers.gametype.itemnames                       = servertype_items;
 
1370
 
 
1371
        y += SMALLCHAR_HEIGHT;
 
1372
        g_arenaservers.sortkey.generic.type                     = MTYPE_SPINCONTROL;
 
1373
        g_arenaservers.sortkey.generic.name                     = "Sort By:";
 
1374
        g_arenaservers.sortkey.generic.flags            = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
 
1375
        g_arenaservers.sortkey.generic.callback         = ArenaServers_Event;
 
1376
        g_arenaservers.sortkey.generic.id                       = ID_SORTKEY;
 
1377
        g_arenaservers.sortkey.generic.x                        = 320;
 
1378
        g_arenaservers.sortkey.generic.y                        = y;
 
1379
        g_arenaservers.sortkey.itemnames                        = sortkey_items;
 
1380
 
 
1381
        y += SMALLCHAR_HEIGHT;
 
1382
        g_arenaservers.showfull.generic.type            = MTYPE_RADIOBUTTON;
 
1383
        g_arenaservers.showfull.generic.name            = "Show Full:";
 
1384
        g_arenaservers.showfull.generic.flags           = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
 
1385
        g_arenaservers.showfull.generic.callback        = ArenaServers_Event;
 
1386
        g_arenaservers.showfull.generic.id                      = ID_SHOW_FULL;
 
1387
        g_arenaservers.showfull.generic.x                       = 320;
 
1388
        g_arenaservers.showfull.generic.y                       = y;
 
1389
 
 
1390
        y += SMALLCHAR_HEIGHT;
 
1391
        g_arenaservers.showempty.generic.type           = MTYPE_RADIOBUTTON;
 
1392
        g_arenaservers.showempty.generic.name           = "Show Empty:";
 
1393
        g_arenaservers.showempty.generic.flags          = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
 
1394
        g_arenaservers.showempty.generic.callback       = ArenaServers_Event;
 
1395
        g_arenaservers.showempty.generic.id                     = ID_SHOW_EMPTY;
 
1396
        g_arenaservers.showempty.generic.x                      = 320;
 
1397
        g_arenaservers.showempty.generic.y                      = y;
 
1398
 
 
1399
        y += 3 * SMALLCHAR_HEIGHT;
 
1400
        g_arenaservers.list.generic.type                        = MTYPE_SCROLLLIST;
 
1401
        g_arenaservers.list.generic.flags                       = QMF_HIGHLIGHT_IF_FOCUS;
 
1402
        g_arenaservers.list.generic.id                          = ID_LIST;
 
1403
        g_arenaservers.list.generic.callback            = ArenaServers_Event;
 
1404
        g_arenaservers.list.generic.x                           = 72;
 
1405
        g_arenaservers.list.generic.y                           = y;
 
1406
        g_arenaservers.list.width                                       = MAX_LISTBOXWIDTH;
 
1407
        g_arenaservers.list.height                                      = 11;
 
1408
        g_arenaservers.list.itemnames                           = (const char **)g_arenaservers.items;
 
1409
        for( i = 0; i < MAX_LISTBOXITEMS; i++ ) {
 
1410
                g_arenaservers.items[i] = g_arenaservers.table[i].buff;
 
1411
        }
 
1412
 
 
1413
        g_arenaservers.mappic.generic.type                      = MTYPE_BITMAP;
 
1414
        g_arenaservers.mappic.generic.flags                     = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
 
1415
        g_arenaservers.mappic.generic.x                         = 72;
 
1416
        g_arenaservers.mappic.generic.y                         = 80;
 
1417
        g_arenaservers.mappic.width                                     = 128;
 
1418
        g_arenaservers.mappic.height                            = 96;
 
1419
        g_arenaservers.mappic.errorpic                          = ART_UNKNOWNMAP;
 
1420
 
 
1421
        g_arenaservers.arrows.generic.type                      = MTYPE_BITMAP;
 
1422
        g_arenaservers.arrows.generic.name                      = ART_ARROWS0;
 
1423
        g_arenaservers.arrows.generic.flags                     = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
 
1424
        g_arenaservers.arrows.generic.callback          = ArenaServers_Event;
 
1425
        g_arenaservers.arrows.generic.x                         = 512+48;
 
1426
        g_arenaservers.arrows.generic.y                         = 240-64+16;
 
1427
        g_arenaservers.arrows.width                                     = 64;
 
1428
        g_arenaservers.arrows.height                            = 128;
 
1429
 
 
1430
        g_arenaservers.up.generic.type                          = MTYPE_BITMAP;
 
1431
        g_arenaservers.up.generic.flags                         = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY;
 
1432
        g_arenaservers.up.generic.callback                      = ArenaServers_Event;
 
1433
        g_arenaservers.up.generic.id                            = ID_SCROLL_UP;
 
1434
        g_arenaservers.up.generic.x                                     = 512+48;
 
1435
        g_arenaservers.up.generic.y                                     = 240-64+16;
 
1436
        g_arenaservers.up.width                                         = 64;
 
1437
        g_arenaservers.up.height                                        = 64;
 
1438
        g_arenaservers.up.focuspic                                      = ART_ARROWS_UP;
 
1439
 
 
1440
        g_arenaservers.down.generic.type                        = MTYPE_BITMAP;
 
1441
        g_arenaservers.down.generic.flags                       = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY;
 
1442
        g_arenaservers.down.generic.callback            = ArenaServers_Event;
 
1443
        g_arenaservers.down.generic.id                          = ID_SCROLL_DOWN;
 
1444
        g_arenaservers.down.generic.x                           = 512+48;
 
1445
        g_arenaservers.down.generic.y                           = 240+16;
 
1446
        g_arenaservers.down.width                                       = 64;
 
1447
        g_arenaservers.down.height                                      = 64;
 
1448
        g_arenaservers.down.focuspic                            = ART_ARROWS_DOWN;
 
1449
 
 
1450
        y = 376;
 
1451
        g_arenaservers.status.generic.type              = MTYPE_TEXT;
 
1452
        g_arenaservers.status.generic.x                 = 320;
 
1453
        g_arenaservers.status.generic.y                 = y;
 
1454
        g_arenaservers.status.string                    = statusbuffer;
 
1455
        g_arenaservers.status.style                             = UI_CENTER|UI_SMALLFONT;
 
1456
        g_arenaservers.status.color                             = menu_text_color;
 
1457
 
 
1458
        y += SMALLCHAR_HEIGHT;
 
1459
        g_arenaservers.statusbar.generic.type   = MTYPE_TEXT;
 
1460
        g_arenaservers.statusbar.generic.x          = 320;
 
1461
        g_arenaservers.statusbar.generic.y          = y;
 
1462
        g_arenaservers.statusbar.string         = "";
 
1463
        g_arenaservers.statusbar.style          = UI_CENTER|UI_SMALLFONT;
 
1464
        g_arenaservers.statusbar.color          = text_color_normal;
 
1465
 
 
1466
        g_arenaservers.remove.generic.type              = MTYPE_BITMAP;
 
1467
        g_arenaservers.remove.generic.name              = ART_REMOVE0;
 
1468
        g_arenaservers.remove.generic.flags             = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
 
1469
        g_arenaservers.remove.generic.callback  = ArenaServers_Event;
 
1470
        g_arenaservers.remove.generic.id                = ID_REMOVE;
 
1471
        g_arenaservers.remove.generic.x                 = 450;
 
1472
        g_arenaservers.remove.generic.y                 = 86;
 
1473
        g_arenaservers.remove.width                             = 96;
 
1474
        g_arenaservers.remove.height                    = 48;
 
1475
        g_arenaservers.remove.focuspic                  = ART_REMOVE1;
 
1476
 
 
1477
        g_arenaservers.back.generic.type                = MTYPE_BITMAP;
 
1478
        g_arenaservers.back.generic.name                = ART_BACK0;
 
1479
        g_arenaservers.back.generic.flags               = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
 
1480
        g_arenaservers.back.generic.callback    = ArenaServers_Event;
 
1481
        g_arenaservers.back.generic.id                  = ID_BACK;
 
1482
        g_arenaservers.back.generic.x                   = 0;
 
1483
        g_arenaservers.back.generic.y                   = 480-64;
 
1484
        g_arenaservers.back.width                               = 128;
 
1485
        g_arenaservers.back.height                              = 64;
 
1486
        g_arenaservers.back.focuspic                    = ART_BACK1;
 
1487
 
 
1488
        g_arenaservers.specify.generic.type         = MTYPE_BITMAP;
 
1489
        g_arenaservers.specify.generic.name             = ART_SPECIFY0;
 
1490
        g_arenaservers.specify.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
 
1491
        g_arenaservers.specify.generic.callback = ArenaServers_Event;
 
1492
        g_arenaservers.specify.generic.id           = ID_SPECIFY;
 
1493
        g_arenaservers.specify.generic.x                = 128;
 
1494
        g_arenaservers.specify.generic.y                = 480-64;
 
1495
        g_arenaservers.specify.width                = 128;
 
1496
        g_arenaservers.specify.height               = 64;
 
1497
        g_arenaservers.specify.focuspic         = ART_SPECIFY1;
 
1498
 
 
1499
        g_arenaservers.refresh.generic.type             = MTYPE_BITMAP;
 
1500
        g_arenaservers.refresh.generic.name             = ART_REFRESH0;
 
1501
        g_arenaservers.refresh.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
 
1502
        g_arenaservers.refresh.generic.callback = ArenaServers_Event;
 
1503
        g_arenaservers.refresh.generic.id               = ID_REFRESH;
 
1504
        g_arenaservers.refresh.generic.x                = 256;
 
1505
        g_arenaservers.refresh.generic.y                = 480-64;
 
1506
        g_arenaservers.refresh.width                    = 128;
 
1507
        g_arenaservers.refresh.height                   = 64;
 
1508
        g_arenaservers.refresh.focuspic                 = ART_REFRESH1;
 
1509
 
 
1510
        g_arenaservers.create.generic.type              = MTYPE_BITMAP;
 
1511
        g_arenaservers.create.generic.name              = ART_CREATE0;
 
1512
        g_arenaservers.create.generic.flags             = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
 
1513
        g_arenaservers.create.generic.callback  = ArenaServers_Event;
 
1514
        g_arenaservers.create.generic.id                = ID_CREATE;
 
1515
        g_arenaservers.create.generic.x                 = 384;
 
1516
        g_arenaservers.create.generic.y                 = 480-64;
 
1517
        g_arenaservers.create.width                             = 128;
 
1518
        g_arenaservers.create.height                    = 64;
 
1519
        g_arenaservers.create.focuspic                  = ART_CREATE1;
 
1520
 
 
1521
        g_arenaservers.go.generic.type                  = MTYPE_BITMAP;
 
1522
        g_arenaservers.go.generic.name                  = ART_CONNECT0;
 
1523
        g_arenaservers.go.generic.flags                 = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
 
1524
        g_arenaservers.go.generic.callback              = ArenaServers_Event;
 
1525
        g_arenaservers.go.generic.id                    = ID_CONNECT;
 
1526
        g_arenaservers.go.generic.x                             = 640;
 
1527
        g_arenaservers.go.generic.y                             = 480-64;
 
1528
        g_arenaservers.go.width                                 = 128;
 
1529
        g_arenaservers.go.height                                = 64;
 
1530
        g_arenaservers.go.focuspic                              = ART_CONNECT1;
 
1531
 
 
1532
        g_arenaservers.punkbuster.generic.type                  = MTYPE_SPINCONTROL;
 
1533
        g_arenaservers.punkbuster.generic.name                  = "Punkbuster:";
 
1534
        g_arenaservers.punkbuster.generic.flags                 = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
 
1535
        g_arenaservers.punkbuster.generic.callback              = ArenaServers_Event;
 
1536
        g_arenaservers.punkbuster.generic.id                    = ID_PUNKBUSTER;
 
1537
        g_arenaservers.punkbuster.generic.x                             = 480+32;
 
1538
        g_arenaservers.punkbuster.generic.y                             = 144;
 
1539
        g_arenaservers.punkbuster.itemnames                             = punkbuster_items;
 
1540
        
 
1541
        g_arenaservers.pblogo.generic.type                      = MTYPE_BITMAP;
 
1542
        g_arenaservers.pblogo.generic.name                      = ART_PUNKBUSTER;
 
1543
        g_arenaservers.pblogo.generic.flags                     = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
 
1544
        g_arenaservers.pblogo.generic.x                         = 526;
 
1545
        g_arenaservers.pblogo.generic.y                         = 176;
 
1546
        g_arenaservers.pblogo.width                                     = 32;
 
1547
        g_arenaservers.pblogo.height                            = 16;
 
1548
        g_arenaservers.pblogo.errorpic                          = ART_UNKNOWNMAP;
 
1549
        
 
1550
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.banner );
 
1551
 
 
1552
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.master );
 
1553
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.gametype );
 
1554
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.sortkey );
 
1555
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.showfull);
 
1556
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.showempty );
 
1557
 
 
1558
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.mappic );
 
1559
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.list );
 
1560
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.status );
 
1561
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.statusbar );
 
1562
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.arrows );
 
1563
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.up );
 
1564
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.down );
 
1565
 
 
1566
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.remove );
 
1567
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.back );
 
1568
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.specify );
 
1569
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.refresh );
 
1570
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.create );
 
1571
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.go );
 
1572
 
 
1573
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.punkbuster );
 
1574
        Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.pblogo );
 
1575
        
 
1576
        ArenaServers_LoadFavorites();
 
1577
 
 
1578
        g_servertype = Com_Clamp( 0, 3, ui_browserMaster.integer );
 
1579
        // hack to get rid of MPlayer stuff
 
1580
        value = g_servertype;
 
1581
        if (value >= 1)
 
1582
                value--;
 
1583
        g_arenaservers.master.curvalue = value;
 
1584
 
 
1585
        g_gametype = Com_Clamp( 0, 4, ui_browserGameType.integer );
 
1586
        g_arenaservers.gametype.curvalue = g_gametype;
 
1587
 
 
1588
        g_sortkey = Com_Clamp( 0, 4, ui_browserSortKey.integer );
 
1589
        g_arenaservers.sortkey.curvalue = g_sortkey;
 
1590
 
 
1591
        g_fullservers = Com_Clamp( 0, 1, ui_browserShowFull.integer );
 
1592
        g_arenaservers.showfull.curvalue = g_fullservers;
 
1593
 
 
1594
        g_emptyservers = Com_Clamp( 0, 1, ui_browserShowEmpty.integer );
 
1595
        g_arenaservers.showempty.curvalue = g_emptyservers;
 
1596
        
 
1597
        g_arenaservers.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "cl_punkbuster" ) );
 
1598
 
 
1599
        // force to initial state and refresh
 
1600
        type = g_servertype;
 
1601
        g_servertype = -1;
 
1602
        ArenaServers_SetType( type );
 
1603
 
 
1604
        trap_Cvar_Register(NULL, "debug_protocol", "", 0 );
 
1605
}
 
1606
 
 
1607
 
 
1608
/*
 
1609
=================
 
1610
ArenaServers_Cache
 
1611
=================
 
1612
*/
 
1613
void ArenaServers_Cache( void ) {
 
1614
        trap_R_RegisterShaderNoMip( ART_BACK0 );
 
1615
        trap_R_RegisterShaderNoMip( ART_BACK1 );
 
1616
        trap_R_RegisterShaderNoMip( ART_CREATE0 );
 
1617
        trap_R_RegisterShaderNoMip( ART_CREATE1 );
 
1618
        trap_R_RegisterShaderNoMip( ART_SPECIFY0 );
 
1619
        trap_R_RegisterShaderNoMip( ART_SPECIFY1 );
 
1620
        trap_R_RegisterShaderNoMip( ART_REFRESH0 );
 
1621
        trap_R_RegisterShaderNoMip( ART_REFRESH1 );
 
1622
        trap_R_RegisterShaderNoMip( ART_CONNECT0 );
 
1623
        trap_R_RegisterShaderNoMip( ART_CONNECT1 );
 
1624
        trap_R_RegisterShaderNoMip( ART_ARROWS0  );
 
1625
        trap_R_RegisterShaderNoMip( ART_ARROWS_UP );
 
1626
        trap_R_RegisterShaderNoMip( ART_ARROWS_DOWN );
 
1627
        trap_R_RegisterShaderNoMip( ART_UNKNOWNMAP );
 
1628
        trap_R_RegisterShaderNoMip( ART_PUNKBUSTER );
 
1629
}
 
1630
 
 
1631
 
 
1632
/*
 
1633
=================
 
1634
UI_ArenaServersMenu
 
1635
=================
 
1636
*/
 
1637
void UI_ArenaServersMenu( void ) {
 
1638
        ArenaServers_MenuInit();
 
1639
        UI_PushMenu( &g_arenaservers.menu );
 
1640
}