]> icculus.org git repositories - btb/d2x.git/blob - main/netlist.c
Lotsa networking stuff from d1x
[btb/d2x.git] / main / netlist.c
1 /*
2  * $Source: /cvs/cvsroot/d2x/main/netlist.c,v $
3  * $Revision: 1.1 $
4  * $Author: bradleyb $
5  * $Date: 2002-02-14 09:05:33 $
6  *
7  * Descent II-a-like network game join menu
8  * Arne de Bruijn, 1998
9  *
10  * $Log: not supported by cvs2svn $
11  *
12  */
13
14 #ifdef HAVE_CONFIG_H
15 #include <conf.h>
16 #endif
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21
22 #include "pstypes.h"
23 #include "timer.h"
24 #include "gr.h"
25 #include "palette.h"
26 #include "inferno.h"
27 #include "mono.h"
28 #include "key.h"
29 #include "error.h"
30 #include "netmisc.h"
31 #include "network.h"
32 #include "ipx.h"
33 #include "game.h"
34 #include "multi.h"
35 #include "text.h"
36 //added 4/18/99 Matt Mueller - show radar in game info
37 #include "multipow.h"
38 //end addition -MM
39
40 #include "gamefont.h"
41 #include "u_mem.h"
42
43 #include "string.h"
44
45 //added on 1/5/99 by Victor Rachels for missiondir
46 #include "cfile.h"
47 //end this section addition
48
49 #define LINE_ITEMS 8
50 #define MAX_TEXT_LEN 25
51 // from network.c
52 extern int Network_games_changed;
53 extern netgame_info Active_games[MAX_ACTIVE_NETGAMES];
54 extern AllNetPlayers_info ActiveNetPlayers[MAX_ACTIVE_NETGAMES];
55 extern int num_active_games;
56 extern int Network_socket;
57 void network_listen();
58 void network_send_game_list_request();
59 // bitblt.c
60 void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest);
61
62 typedef struct bkg {
63   grs_canvas * menu_canvas;
64   grs_bitmap * saved;                   // The background under the menu.
65   grs_bitmap * background;
66   int background_is_sub;
67 } bkg;
68
69 extern grs_bitmap nm_background;
70
71 struct line_item {
72         int x, y;
73         int width;
74         char *value;
75 };
76
77 void network_draw_game(const netgame_info *game) {
78 }
79
80 char *network_mode_text(const netgame_info *game) {
81         //edit 4/18/99 Matt Mueller - GTEAM?  heh.  Should be "TEAM" I think.
82         static char *names[4]={"ANRCHY", "TEAM", "ROBO", "COOP"};
83         //end edit -MM
84 #ifndef SHAREWARE
85         if (game->gamemode >= 4 ||
86             (game->protocol_version != MULTI_PROTO_VERSION &&
87              (game->protocol_version != MULTI_PROTO_DXX_VER ||
88               game->required_subprotocol > MULTI_PROTO_DXX_MINOR)))
89             return "UNSUP";
90 #endif
91         return names[game->gamemode];
92 }
93
94 char *network_status_text(const netgame_info *game, int activeplayers) {
95         switch (game->game_status) {
96                 case NETSTAT_STARTING:
97                         return "Forming";
98                 case NETSTAT_PLAYING:
99                         if (game->game_flags & NETGAME_FLAG_CLOSED)
100                                 return "Closed";
101                         else if (activeplayers == game->max_numplayers)
102                                 return "Full";
103                         else
104                                 return "Open";
105                 default:
106                         return "Between";
107         }
108 }
109
110 static void network_update_item(const netgame_info *game, const AllNetPlayers_info *players, struct line_item li[]) {
111         int i, activeplayers = 0;
112         // get number of active players
113         for (i = 0; i < game->numplayers; i++)
114                 if (players->players[i].connected)
115                         activeplayers++;
116         strcpy(li[1].value, game->protocol_version == MULTI_PROTO_DXX_VER ? "+" : "");
117         strcpy(li[2].value, game->game_name);
118         strcpy(li[3].value, network_mode_text(game));
119
120         sprintf(li[4].value, "%d/%d", activeplayers, game->max_numplayers);
121 #ifndef SHAREWARE
122         strcpy(li[5].value, game->mission_title);
123 #else
124         strcpy(li[5].value, "Descent: First Strike");
125 #endif
126         if (game->levelnum < 0)
127                 sprintf(li[6].value, "S%d", -game->levelnum);
128         else    
129                 sprintf(li[6].value, "%d", game->levelnum);
130         strcpy(li[7].value, network_status_text(game, activeplayers));
131 }
132
133 static void update_items(struct line_item lis[MAX_ACTIVE_NETGAMES][LINE_ITEMS]) {
134         int i, j;
135
136         for (i = 0; i < MAX_ACTIVE_NETGAMES; i++) {
137                 if (i >= num_active_games) {
138                         for (j = 1; j < LINE_ITEMS; j++)
139                                 lis[i][j].value[0] = 0;
140                 } else
141                         network_update_item(&Active_games[i], &ActiveNetPlayers[i], lis[i]);
142         }
143 }
144
145 int network_menu_hskip=4;
146 int network_menu_width[LINE_ITEMS] = { 10, 6, 72, 37, 38, 66, 25, 40 };
147 int ref_network_menu_width[LINE_ITEMS] = { 10, 6, 72, 37, 38, 66, 25, 40 };
148 char *network_menu_title[LINE_ITEMS] = { "", "", "Game", "Mode", "#Plrs", "Mission", "Lev", "Status" };
149
150 static int selected_game;
151
152 static void draw_back(bkg *b, int x, int y, int w, int h) {
153        gr_bm_bitblt(b->background->bm_w-15, h, 5, y, 5, y, b->background, &(grd_curcanv->cv_bitmap) );
154 }
155
156 static void draw_item(bkg *b, struct line_item *li, int is_current) {
157         int i, w, h, aw, max_w, pad_w, y;
158         char str[MAX_TEXT_LEN], *p;
159
160         y = li[0].y;
161         if (is_current)
162                 gr_set_fontcolor(BM_XRGB(31, 27, 6), -1);
163         else
164                 gr_set_fontcolor(BM_XRGB(17, 17, 26), -1);
165         gr_get_string_size(" ...", &pad_w, &h, &aw);
166         draw_back(b, li[0].x, y, 
167          li[LINE_ITEMS-1].x + li[LINE_ITEMS-1].width - li[0].x, h);
168         for (i = 0; i < LINE_ITEMS; i++) {
169                 strcpy(str, li[i].value);
170                 gr_get_string_size(str, &w, &h, &aw);
171                 if (w > li[i].width) {
172                         max_w = li[i].width - pad_w;
173                         p = str + strlen(str);
174                         while (p > str && w > max_w) {
175                                 *(--p) = 0;
176                                 gr_get_string_size(str, &w, &h, &aw);
177                         }
178                         strcpy(p, " ...");
179                 }
180                 gr_ustring(li[i].x, y, str);
181         }
182 }
183
184 static void draw_list(bkg *bg,
185  struct line_item lis[MAX_ACTIVE_NETGAMES][LINE_ITEMS]) {
186         int i;
187         update_items(lis);
188         for (i = 0; i < MAX_ACTIVE_NETGAMES; i++) {
189                 draw_item(bg, lis[i], i == selected_game);
190         }
191 }
192 static void init_background(bkg *bg, int x, int y, int w, int h) {
193         bg->menu_canvas = gr_create_sub_canvas( &grd_curscreen->sc_canvas, x, y, w, h );
194         gr_set_current_canvas( bg->menu_canvas );
195
196         // Save the background under the menu...
197         bg->saved = gr_create_bitmap( w, h );
198         Assert( bg->saved != NULL );
199         gr_bm_bitblt(w, h, 0, 0, 0, 0, &grd_curcanv->cv_bitmap, bg->saved );
200         gr_set_current_canvas( NULL );
201         nm_draw_background(x,y,x+w-1,y+h-1);
202         if (w > nm_background.bm_w || h > nm_background.bm_h){
203                 bg->background=gr_create_bitmap(w,h);
204                 gr_bitmap_scale_to(&nm_background,bg->background);
205                 bg->background_is_sub=0;
206         }else{
207                 bg->background = gr_create_sub_bitmap(&nm_background,0,0,w,h);
208                 bg->background_is_sub=1;
209         }
210         gr_set_current_canvas( bg->menu_canvas );
211 }
212
213 static void done_background(bkg *bg) {
214         gr_set_current_canvas(bg->menu_canvas);
215         gr_bitmap(0, 0, bg->saved);     
216         gr_free_bitmap(bg->saved);
217         if (bg->background_is_sub)
218                 gr_free_sub_bitmap( bg->background );
219         else
220                 gr_free_bitmap( bg->background );
221         gr_free_sub_canvas( bg->menu_canvas );
222 }
223
224
225 //added on 9/16-18/98 by Victor Rachels to add info boxes to netgameslist
226 void show_game_players(netgame_info game, AllNetPlayers_info players)
227 {
228  char pilots[(CALLSIGN_LEN+2)*MAX_PLAYERS];
229  int i;
230
231   memset(pilots,0,sizeof(char)*(CALLSIGN_LEN+2)*MAX_PLAYERS);
232
233    for(i=0;i<game.numplayers;i++)
234     if(players.players[i].connected)
235      {
236       strcat(pilots,players.players[i].callsign);
237       strcat(pilots,"\n");
238      }
239
240   nm_messagebox("Players", 1, TXT_OK, pilots);
241 }
242
243 void show_game_score(netgame_info game, AllNetPlayers_info players);
244
245 int show_game_stats(netgame_info game, AllNetPlayers_info players, int awesomeflag)
246 {
247  //edited 4/18/99 Matt Mueller - show radar flag and banned stuff too
248  //switched to the info/rinfo mode to 1)allow sprintf easily 2) save some
249  //cpu cycles not seeking to the end of the string each time.
250  char rinfo[512],*info=rinfo;
251
252   memset(info,0,sizeof(char)*256);
253
254 #ifndef SHAREWARE
255    if(!game.mission_name)
256 #endif
257     info+=sprintf(info,"Level: Descent: First Strike");
258 #ifndef SHAREWARE
259    else
260     info+=sprintf(info,game.mission_name);
261 #endif
262
263    switch(game.gamemode)
264     {
265      case 0 : info+=sprintf(info,"\nMode:  Anarchy"); break;
266      case 1 : info+=sprintf(info,"\nMode:  Team"); break;
267      case 2 : info+=sprintf(info,"\nMode:  Robo"); break;
268      case 3 : info+=sprintf(info,"\nMode:  Coop"); break;
269      default: info+=sprintf(info,"\nMode:  Unknown"); break;
270     }
271
272    switch(game.difficulty)
273     {
274      case 0 : info+=sprintf(info,"\nDiff:  Trainee"); break;
275      case 1 : info+=sprintf(info,"\nDiff:  Rookie"); break;
276      case 2 : info+=sprintf(info,"\nDiff:  Hotshot"); break;
277      case 3 : info+=sprintf(info,"\nDiff:  Ace"); break;
278      case 4 : info+=sprintf(info,"\nDiff:  Insane"); break;
279      default: info+=sprintf(info,"\nDiff:  Unknown"); break;
280     }
281
282    switch(game.protocol_version)
283     {
284      case 1 : info+=sprintf(info,"\nPrtcl: Shareware"); break;
285      case 2 : info+=sprintf(info,"\nPrtcl: Normal"); break;
286      case 3 : info+=sprintf(info,"\nPrtcl: DXX only"); break;
287      case 0 : info+=sprintf(info,"\nPrtcl: DXX hybrid"); break;
288      default: info+=sprintf(info,"\nPrtcl: Unknown"); break;
289     }
290
291    if(game.game_flags & NETGAME_FLAG_SHOW_MAP)
292            info+=sprintf(info,"\n Players on Map");
293    //edited 04/19/99 Matt Mueller - check protocol_ver too.
294    if (game.protocol_version==MULTI_PROTO_DXX_VER 
295 #ifndef SHAREWARE
296 && game.subprotocol>=1
297 #endif
298 ){
299 #ifndef SHAREWARE
300            int i=0,b=0;
301            char sep0=':';
302            if(game.flags & NETFLAG_ENABLE_RADAR)
303                    info+=sprintf(info,"\n Radar");
304            if(game.flags & NETFLAG_ENABLE_ALT_VULCAN)
305                    info+=sprintf(info,"\n Alt Vulcan");
306            info+=sprintf(info,"\n Banned");
307 #define NETFLAG_SHOW_BANNED(D,V) if (!(game.flags&NETFLAG_DO ## D)) {if (i>3) i=0; else i++; info+=sprintf(info,"%c %s",i?sep0:'\n',#V);b++;sep0=',';}
308            NETFLAG_SHOW_BANNED(LASER,laser);
309            NETFLAG_SHOW_BANNED(QUAD,quad);
310            NETFLAG_SHOW_BANNED(VULCAN,vulcan);
311            NETFLAG_SHOW_BANNED(SPREAD,spread);
312            NETFLAG_SHOW_BANNED(PLASMA,plasma);
313            NETFLAG_SHOW_BANNED(FUSION,fusion);
314            NETFLAG_SHOW_BANNED(HOMING,homing);
315            NETFLAG_SHOW_BANNED(SMART,smart);
316            NETFLAG_SHOW_BANNED(MEGA,mega);
317            NETFLAG_SHOW_BANNED(PROXIM,proxim);
318            NETFLAG_SHOW_BANNED(CLOAK,cloak);
319            NETFLAG_SHOW_BANNED(INVUL,invuln);
320            if (b==0) info+=sprintf(info,": none");
321 #endif /* ! SHAREWARE */
322    }
323    //end edit -MM
324  //end edit -MM
325         if (awesomeflag){
326                 int c;
327                 while (1){
328                         c=nm_messagebox("Stats", 3, "Players","Scores","Join Game", rinfo);
329                         if (c==0)
330                                 show_game_players(game, players);
331                         else if (c==1)
332                                 show_game_score(game, players);
333                         else if (c==2)
334                                 return 1;
335                         else
336                                 return 0;
337                 }
338         }else{
339            nm_messagebox("Stats", 1, TXT_OK, rinfo);
340            return 0;
341         }
342 }
343 //end this section addition - Victor Rachels
344
345 //added on 11/12/98 by Victor Rachels to maybe fix some bugs
346 void alphanumize(char *string, int length);
347
348 void alphanumize(char *string, int length)
349 {
350  int i=0;
351   while(i<length && string[i])
352    {
353      if(!((string[i]<=122&&string[i]>=97) ||
354           (string[i]<=90 &&string[i]>=65) ||
355           (string[i]<=57 &&string[i]>=48) ||
356           (string[i]=='\n') ||
357           (string[i]==' ')  ||
358           (string[i]=='-')
359           ) )
360       string[i] = '_';
361     i++;
362    }
363 }
364
365 //added on 10/12/98 by Victor Rachels to show netgamelist scores
366 void show_game_score(netgame_info game, AllNetPlayers_info players)
367 {
368  char scores[2176]="",info[2048]="",deaths[128]="",tmp[10];
369  int i,j,k;
370
371   strcat(scores,"Pilots ");
372   strcat(deaths,"    ");
373
374    for(i=0;i<game.numplayers;i++)
375     if(players.players[i].connected)
376      {
377        strcat(scores,"     ");
378        sprintf(tmp,"%c",players.players[i].callsign[0]);
379        strcat(scores,tmp);
380        strcat(info,players.players[i].callsign);
381         for(k=strlen(players.players[i].callsign);k<9;k++)
382          strcat(info," ");
383         for(j=0;j<game.numplayers;j++)
384          if(players.players[j].connected)
385           {
386            if(i==j&&game.kills[i][j]>0)
387             {
388              strcat(info,"  ");
389              sprintf(tmp,"-%i",game.kills[i][j]);
390             }
391            else
392             {
393              strcat(info,"   ");
394              sprintf(tmp,"%i",game.kills[i][j]);
395             }
396            strcat(info,tmp);
397             for(k=strlen(tmp);k<3;k++)
398              strcat(info," ");
399           }
400        sprintf(tmp,"     %i",game.player_kills[i]);
401        strcat(info,tmp);
402        strcat(info,"\n\n");
403        sprintf(tmp,"     %i",game.killed[i]);
404        strcat(deaths,tmp);
405      }
406   strcat(scores,"   Total\n\n");
407   strcat(scores,info);
408   strcat(deaths,"   \n\n");
409   strcat(scores,deaths);
410   alphanumize(scores,sizeof(scores));
411   nm_messagebox_fixedfont("Score\n", 1, TXT_OK, scores);
412 }
413 //end this section addition - Victor Rachels
414
415 //added on 2000/01/29 by Matt Mueller for direct ip join.
416 #include "netpkt.h"
417 int network_do_join_game(netgame_info *jgame);
418 int get_and_show_netgame_info(ubyte *server, ubyte *node, ubyte *net_address){
419         sequence_packet me;
420         fix nextsend;
421         int numsent;
422         fix curtime;
423
424         if (setjmp(LeaveGame))
425                 return 0;
426     num_active_games = 0;
427         Network_games_changed = 0;
428         Network_status = NETSTAT_BROWSING;
429     memset(Active_games, 0, sizeof(netgame_info)*MAX_ACTIVE_NETGAMES);
430
431         nextsend=0;numsent=0;
432
433         while (1){
434                 curtime=timer_get_fixed_seconds();
435                 if (nextsend<curtime){
436                         if (numsent>=5)
437                                 return 0;//timeout
438                         nextsend=curtime+F1_0*3;
439                         numsent++;
440                         mprintf((0, "Sending game_list request.\n"));
441                         memcpy( me.player.callsign, Players[Player_num].callsign, CALLSIGN_LEN+1 );
442                         memcpy( me.player.network.ipx.node, ipx_get_my_local_address(), 6 );
443                         memcpy( me.player.network.ipx.server, ipx_get_my_server_address(), 4 );
444                         me.type = PID_DXX_GAME_INFO_REQ;//get full info.
445
446                         send_sequence_packet( me, server,node,net_address);
447                 }
448
449                 network_listen();
450
451                 if (Network_games_changed){
452                         if (num_active_games<1){
453                                 Network_games_changed=0;
454                                 continue;
455                         }
456                         if (show_game_stats(Active_games[0], ActiveNetPlayers[0], 1))
457                                 return (network_do_join_game(&Active_games[0]));
458                         else
459                                 return 0;
460                 }
461                 if (key_inkey()==KEY_ESC)
462                         return 0;
463
464         }
465         return 0;
466 }
467 //end addition -MM
468
469 //added on 1/5/99 by Victor Rachels for missiondir
470 void change_missiondir()
471 {
472  newmenu_item m[1];
473  int i=1;
474  char thogdir[64];
475
476   sprintf(thogdir,AltHogDir);
477
478   m[0].type = NM_TYPE_INPUT; m[0].text = thogdir; m[0].text_len = 64;
479
480   i=newmenu_do1(NULL, "Mission Directory", 1, m, NULL, 0);
481
482    if(i==0)
483     {
484      cfile_use_alternate_hogdir(thogdir);
485      sprintf(thogdir,AltHogDir);
486      m[0].text=thogdir;
487     }
488 }
489 //end this section addition - VR
490
491 //added/changed on 9/17/98 by Victor Rachels for netgame info screen redraw
492 //this was mostly a bunch of random moves and copies from the main function
493 //if you can figure this out more elegantly, go for it.
494 void netlist_redraw(bkg bg,
495                     char menu_text[MAX_ACTIVE_NETGAMES][LINE_ITEMS][MAX_TEXT_LEN],
496                     struct line_item lis[MAX_ACTIVE_NETGAMES][LINE_ITEMS])
497 {
498  int i,j,k,yp;
499
500         gr_set_current_canvas( NULL );
501
502         init_background(&bg, 0, 7, grd_curcanv->cv_bitmap.bm_w,
503          grd_curcanv->cv_bitmap.bm_h - 14);
504
505         yp=22;
506         gr_set_curfont(Gamefonts[GFONT_BIG_1]);
507         gr_string(0x8000, yp, "Netgames");//yp was 22
508         yp+=grd_curcanv->cv_font->ft_h+network_menu_hskip*3+Gamefonts[GFONT_SMALL]->ft_h;//need to account for size of current socket, drawn elsewhere
509         // draw titles
510         gr_set_curfont(Gamefonts[GFONT_SMALL]);
511         gr_set_fontcolor(BM_XRGB(27, 27, 27), -1);
512         k = 15;
513         for (j = 0; j < LINE_ITEMS; j++) {
514                 gr_ustring(k, yp, network_menu_title[j]);//yp was 61
515                 k += network_menu_width[j];
516         }
517         
518
519         for (i = 0; i < MAX_ACTIVE_NETGAMES; i++) {
520                 struct line_item *li = lis[i];
521                 k=15;
522
523                 yp+=grd_curcanv->cv_font->ft_h+network_menu_hskip;
524                 for (j = 0; j < LINE_ITEMS; j++) {
525                         li[j].x = k;
526                         li[j].y = yp;
527                         //                      li[j].y = 70 + i * 9;
528                         li[j].width = network_menu_width[j] - (j > 1 ? 4 : 0); // HACK!
529                         k += network_menu_width[j];
530                         li[j].value = menu_text[i][j];
531                 }
532                 sprintf(li[0].value, "%d.", i + 1); 
533         }
534
535 }
536 //end this section addition - Victor Rachels
537
538 int network_join_game_menu() {
539         char menu_text[MAX_ACTIVE_NETGAMES][LINE_ITEMS][MAX_TEXT_LEN];
540         struct line_item lis[MAX_ACTIVE_NETGAMES][LINE_ITEMS];
541         int k;
542         int old_select, old_socket, done, last_num_games;
543         grs_canvas * save_canvas;
544         grs_font * save_font;
545         bkg bg;
546         fix t, req_timer = 0;
547         
548         selected_game = 0;
549         gr_palette_fade_in( gr_palette, 32, 0 );
550         save_canvas = grd_curcanv;
551         gr_set_current_canvas( NULL );
552         save_font = grd_curcanv->cv_font;
553         
554         for (k=0;k<LINE_ITEMS;k++)//scale columns to fit screen res.
555                 network_menu_width[k]=ref_network_menu_width[k]*grd_curcanv->cv_bitmap.bm_w/320;
556         network_menu_hskip=(grd_curcanv->cv_bitmap.bm_h-Gamefonts[GFONT_BIG_1]->ft_h-22-Gamefonts[GFONT_SMALL]->ft_h*17)/17;
557
558         init_background(&bg, 0, 7, grd_curcanv->cv_bitmap.bm_w,
559          grd_curcanv->cv_bitmap.bm_h - 14);
560
561         game_flush_inputs();
562
563 //added/changed on 9/17/98 by Victor Rachels for netgame info screen redraw
564         netlist_redraw(bg,menu_text,lis);
565 //end this section addition - Victor Rachels
566
567         Network_games_changed = 1;
568         old_socket = -32768;
569         old_select = -1;
570         last_num_games = 0;
571         if ( gr_palette_faded_out ) {
572             gr_palette_fade_in( gr_palette, 32, 0 );
573         }
574
575         done = 0;
576
577         while (!done) {
578                 if (Network_socket != old_socket) {
579                         gr_set_fontcolor(BM_XRGB(27, 27, 27), -1);
580                         draw_back(&bg, 30, 22+Gamefonts[GFONT_BIG_1]->ft_h+network_menu_hskip*2, 250, Gamefonts[GFONT_SMALL]->ft_h+4);//was 52,250,9
581                         gr_printf(30, 22+Gamefonts[GFONT_BIG_1]->ft_h+network_menu_hskip*2, "Current IPX socket is %+d "
582                                         "(PgUp/PgDn to change)", Network_socket);
583                         if (old_socket != -32768) { /* changed by user? */
584                                 network_listen();
585                                 ipx_change_default_socket( IPX_DEFAULT_SOCKET + Network_socket );
586                                 num_active_games = 0;
587                         }
588                         req_timer -= F1_0 * 5; /* force send request */
589                         Network_games_changed = 1;
590                 }
591                 if (Network_games_changed) {
592                         if (num_active_games > last_num_games) /* new game? */
593                                 digi_play_sample(SOUND_HUD_MESSAGE, F1_0);
594                         last_num_games = num_active_games;
595                         Network_games_changed = 0;
596                         draw_list(&bg, lis);
597                         //added on 9/13/98 by adb to make update-needing arch's work
598                         gr_update();
599                         //end addition - adb
600
601                 } else if (selected_game != old_select) {
602                         draw_item(&bg, lis[old_select], 0);
603                         draw_item(&bg, lis[selected_game], 1);
604                         //added on 9/13/98 by adb to make update-needing arch's work
605                         gr_update();
606                         //end addition - adb
607                 }
608                 old_socket = Network_socket;
609                 old_select = selected_game;
610
611                 t = timer_get_approx_seconds();
612                 if (t < req_timer || t > req_timer + F1_0 * 5) {
613                         req_timer = timer_get_approx_seconds();
614                         network_send_game_list_request();
615                 }                               
616                 network_listen();
617
618                 k = key_inkey();
619                 switch (k) {
620 //added 9/16-17/98 by Victor Rachels for netgamelist info
621         //edit 4/18/99 Matt Mueller - use KEY_? defines so it actually works on non-dos
622                         case KEY_U: //U = 0x16
623                                 if(selected_game<num_active_games)
624                                  {
625                                    show_game_players(Active_games[selected_game], ActiveNetPlayers[selected_game]);
626                                    netlist_redraw(bg,menu_text,lis);
627                                    old_socket = -32768;
628                                    old_select = -1;
629                                  }
630                                 break;
631                         case KEY_I: //I = 0x17
632                                 if(selected_game<num_active_games)
633                                  {
634                                    show_game_stats(Active_games[selected_game], ActiveNetPlayers[selected_game], 0);
635                                    netlist_redraw(bg,menu_text,lis);
636                                    old_socket = -32768;
637                                    old_select = -1;
638                                  }
639                                 break;
640 //end this section addition - Victor
641 //added 10/12/98 by Victor Rachels for netgamelist scores
642                         case  KEY_S: //S = 0x1f
643                                 if(selected_game<num_active_games)
644                                  {
645                                   show_game_score(Active_games[selected_game], ActiveNetPlayers[selected_game]);
646                                   netlist_redraw(bg,menu_text,lis);
647                                   old_socket = -32768;
648                                   old_select = -1;
649                                  }
650                                 break;
651 //end this section addition - Victor
652                         case KEY_M: //M = 0x32
653         //end edit -MM
654                                  {
655                                   change_missiondir();
656                                   netlist_redraw(bg,menu_text,lis);
657                                   old_socket = -32768;
658                                   old_select = -1;
659                                  }
660                         case KEY_PAGEUP:
661                         case KEY_PAD9:
662                                 if (Network_socket < 99) Network_socket++;
663                                 break;
664                         case KEY_PAGEDOWN:
665                         case KEY_PAD3:
666                                 if (Network_socket > -99) Network_socket--;
667                                 break;
668                         case KEY_PAD5:
669                                 Network_socket = 0;
670                                 break;
671                         case KEY_TAB + KEY_SHIFTED:
672                         case KEY_UP:
673                         case KEY_PAD8:
674                                 if (selected_game-- == 0)
675                                         selected_game = MAX_ACTIVE_NETGAMES - 1;
676                                 break;
677                         case KEY_TAB:
678                         case KEY_DOWN:
679                         case KEY_PAD2:
680                                 if (++selected_game == MAX_ACTIVE_NETGAMES)
681                                         selected_game = 0;
682                                 break;
683                         case KEY_ENTER:
684                         case KEY_PADENTER:
685                                 done = 1;
686                                 break;
687 #if 0
688                         //added on 11/20/99 by Victor Rachels to add observer mode
689                         case KEY_O:
690                                 I_am_observer=1;
691                                 done = 1;
692                                 break;
693                         //end this section addition - VR
694 #endif
695                         case KEY_ESC:
696                                 selected_game = -1;
697                                 done = 1;
698                                 break;
699                         case KEYS_GR_TOGGLE_FULLSCREEN:
700                                 gr_toggle_fullscreen_menu();
701                                 break;
702                 }
703         }
704     done_background(&bg);
705         //edited 05/18/99 Matt Mueller - restore the font *after* the canvas, or else we are writing into the free'd memory
706         gr_set_current_canvas( save_canvas );
707         grd_curcanv->cv_font = save_font;
708         //end edit -MM
709         return selected_game;
710 }