]> icculus.org git repositories - btb/d2x.git/blob - main/kmatrix.c
remove DirectDraw use and Windows mouse stuff made redundant by SDL (lots of WINDOWS...
[btb/d2x.git] / main / kmatrix.c
1 /* $Id: kmatrix.c,v 1.9 2005-08-02 06:13:56 chris Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Kill matrix displayed at end of level.
18  *
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <conf.h>
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <stdarg.h>
30
31 #include "error.h"
32 #include "pstypes.h"
33 #include "gr.h"
34 #include "mono.h"
35 #include "key.h"
36 #include "palette.h"
37 #include "game.h"
38 #include "gamefont.h"
39 #include "u_mem.h"
40 #include "newmenu.h"
41 #include "menu.h"
42 #include "player.h"
43 #include "screens.h"
44 #include "gamefont.h"
45 #include "cntrlcen.h"
46 #include "mouse.h"
47 #include "joy.h"
48 #include "timer.h"
49 #include "text.h"
50 #include "songs.h"
51 #include "multi.h"
52 #include "kmatrix.h"
53 #include "gauges.h"
54 #include "pcx.h"
55 #include "network.h"
56
57 #define CENTERING_OFFSET(x) ((300 - (70 + (x)*25 ))/2)
58 #define CENTERSCREEN (MenuHires?320:160)
59
60 int kmatrix_kills_changed = 0;
61 char ConditionLetters[]={' ','P','E','D','E','E','V','W'};
62 char WaitingForOthers=0;
63
64 int Kmatrix_nomovie_message=0;
65
66 extern char MaxPowerupsAllowed[],PowerupsInMine[];
67
68 void kmatrix_reactor (char *message);
69 void kmatrix_phallic ();
70 void kmatrix_redraw_coop();
71
72 #define LHX(x)          ((x)*(MenuHires?2:1))
73 #define LHY(y)          ((y)*(MenuHires?2.4:1))
74
75 void kmatrix_draw_item( int  i, int *sorted )
76 {
77         int j, x, y;
78         char temp[10];
79
80         y = LHY(50+i*9);
81
82         // Print player name.
83
84         gr_printf( LHX(CENTERING_OFFSET(N_players)), y, "%s", Players[sorted[i]].callsign );
85
86    if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
87            gr_printf (LHX(CENTERING_OFFSET(N_players)-15),y,"%c",ConditionLetters[Players[sorted[i]].connected]);
88    
89         for (j=0; j<N_players; j++) {
90
91                 x = LHX(70 + CENTERING_OFFSET(N_players) + j*25);
92
93                 if (sorted[i]==sorted[j]) {
94                         if (kill_matrix[sorted[i]][sorted[j]] == 0) {
95                                 gr_set_fontcolor( BM_XRGB(10,10,10),-1 );
96                                 gr_printf( x, y, "%d", kill_matrix[sorted[i]][sorted[j]] );
97                         } else {
98                                 gr_set_fontcolor( BM_XRGB(25,25,25),-1 );
99                                 gr_printf( x, y, "-%d", kill_matrix[sorted[i]][sorted[j]] );
100                         }
101                 } else {
102                         if (kill_matrix[sorted[i]][sorted[j]] <= 0) {
103                                 gr_set_fontcolor( BM_XRGB(10,10,10),-1 );
104                                 gr_printf( x, y, "%d", kill_matrix[sorted[i]][sorted[j]] );
105                         } else {
106                                 gr_set_fontcolor( BM_XRGB(25,25,25),-1 );
107                                 gr_printf( x, y, "%d", kill_matrix[sorted[i]][sorted[j]] );
108                         }
109                 }
110
111         }
112
113   if (Players[sorted[i]].net_killed_total+Players[sorted[i]].net_kills_total==0)
114         sprintf (temp,"NA");
115   else
116    sprintf (temp,"%d%%",(int)((float)((float)Players[sorted[i]].net_kills_total/((float)Players[sorted[i]].net_killed_total+(float)Players[sorted[i]].net_kills_total))*100.0));                
117                 
118         x = LHX(60 + CENTERING_OFFSET(N_players) + N_players*25);
119         gr_set_fontcolor( BM_XRGB(25,25,25),-1 );
120         gr_printf( x ,y,"%4d/%s",Players[sorted[i]].net_kills_total,temp);
121 }
122
123 void kmatrix_draw_coop_item( int  i, int *sorted )
124 {
125         int  x, y;
126
127         y = LHY(50+i*9);
128
129         // Print player name.
130
131         gr_printf( LHX(CENTERING_OFFSET(N_players)), y, "%s", Players[sorted[i]].callsign );
132    gr_printf (LHX(CENTERING_OFFSET(N_players)-15),y,"%c",ConditionLetters[Players[sorted[i]].connected]);
133    
134
135         x = CENTERSCREEN;
136
137         gr_set_fontcolor( BM_XRGB(60,40,10),-1 );
138         gr_printf( x, y, "%d", Players[sorted[i]].score );
139
140         x = CENTERSCREEN+LHX(50);
141
142         gr_set_fontcolor( BM_XRGB(60,40,10),-1 );
143         gr_printf( x, y, "%d", Players[sorted[i]].net_killed_total);
144 }
145
146
147 void kmatrix_draw_names(int *sorted)
148 {
149         int j, x;
150         
151         int color;
152
153    if (Kmatrix_nomovie_message)
154     {
155                 gr_set_fontcolor( BM_XRGB(63,0,0),-1 );
156                 gr_printf( CENTERSCREEN-LHX(40), LHY(20), "(Movie not played)");
157          }
158
159         for (j=0; j<N_players; j++) {
160                 if (Game_mode & GM_TEAM)
161                         color = get_team(sorted[j]);
162                 else
163                         color = sorted[j];
164
165                 x = LHX (70 + CENTERING_OFFSET(N_players) + j*25);
166
167       if (Players[sorted[j]].connected==0)
168         gr_set_fontcolor(gr_find_closest_color(31,31,31),-1);
169       else
170         gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
171
172                 gr_printf( x, LHY(40), "%c", Players[sorted[j]].callsign[0] );
173
174         }
175
176         x = LHX(72 + CENTERING_OFFSET(N_players) + N_players*25);
177         gr_set_fontcolor( BM_XRGB(31,31,31),-1 );
178         gr_printf( x, LHY(40), "K/E");
179                 
180 }
181 void kmatrix_draw_coop_names(int *sorted)
182 {
183         sorted=sorted;
184
185    if (Kmatrix_nomovie_message)
186     {
187                 gr_set_fontcolor( BM_XRGB(63,0,0),-1 );
188                 gr_printf( CENTERSCREEN-LHX(40), LHY(20), "(Movie not played)");
189          }
190
191         gr_set_fontcolor( BM_XRGB(63,31,31),-1 );
192         gr_printf( CENTERSCREEN, LHY(40), "SCORE");
193
194         gr_set_fontcolor( BM_XRGB(63,31,31),-1 );
195         gr_printf( CENTERSCREEN+LHX(50), LHY(40), "DEATHS");
196 }
197
198
199 void kmatrix_draw_deaths(int *sorted)
200 {
201         int y,x;
202         char reactor_message[50];
203
204    sorted=sorted;
205
206    y = LHY(55 + 72 + 35);
207         x = LHX(35);
208
209         {
210          
211                 int sw, sh, aw;
212                                         
213       gr_set_fontcolor(gr_find_closest_color(63,20,0),-1);
214       gr_get_string_size("P-Playing E-Escaped D-Died", &sw, &sh, &aw);
215
216            if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
217                    gr_printf( CENTERSCREEN-(sw/2), y,"P-Playing E-Escaped D-Died");
218   
219       y+=(sh+5);
220            gr_get_string_size("V-Viewing scores W-Waiting", &sw, &sh, &aw);
221
222            if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
223                    gr_printf( CENTERSCREEN-(sw/2), y,"V-Viewing scores W-Waiting");
224
225         }
226
227    y+=LHY(20);
228
229         {
230                 int sw, sh, aw;
231       gr_set_fontcolor(gr_find_closest_color(63,63,63),-1);
232
233       if (Players[Player_num].connected==7)
234        {
235         gr_get_string_size("Waiting for other players...",&sw, &sh, &aw);
236         gr_printf( CENTERSCREEN-(sw/2), y,"Waiting for other players...");
237        }
238       else
239        {
240         gr_get_string_size(TXT_PRESS_ANY_KEY2, &sw, &sh, &aw);
241         gr_printf( CENTERSCREEN-(sw/2), y, TXT_PRESS_ANY_KEY2);
242        }
243         }
244
245   if (Countdown_seconds_left <=0)
246    kmatrix_reactor(TXT_REACTOR_EXPLODED);
247   else
248    {
249      sprintf((char *)&reactor_message, "%s: %d %s  ", TXT_TIME_REMAINING, Countdown_seconds_left, TXT_SECONDS);
250      kmatrix_reactor ((char *)&reactor_message);
251    }
252  
253   if (Game_mode & GM_HOARD) 
254           kmatrix_phallic();
255
256 }
257 void kmatrix_draw_coop_deaths(int *sorted)
258 {
259         int j, x, y;
260         char reactor_message[50];
261         
262         y = LHY(55 + N_players * 9);
263
264 //      gr_set_fontcolor(gr_getcolor(player_rgb[j].r,player_rgb[j].g,player_rgb[j].b),-1 );
265         gr_set_fontcolor( BM_XRGB(31,31,31),-1 );
266
267         x = CENTERSCREEN+LHX(50);
268         gr_printf( x, y, TXT_DEATHS );
269
270         for (j=0; j<N_players; j++) {
271                 x = CENTERSCREEN+LHX(50);
272                 gr_printf( x, y, "%d", Players[sorted[j]].net_killed_total );
273         }
274
275    y = LHY(55 + 72 + 35);
276         x = LHX(35);
277
278         {
279          
280                 int sw, sh, aw;
281
282       gr_set_fontcolor(gr_find_closest_color(63,20,0),-1);
283       gr_get_string_size("P-Playing E-Escaped D-Died", &sw, &sh, &aw);
284
285           if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
286               gr_printf( CENTERSCREEN-(sw/2), y,"P-Playing E-Escaped D-Died");
287           
288   
289       y+=(sh+5);
290            gr_get_string_size("V-Viewing scores W-Waiting", &sw, &sh, &aw);
291
292            if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
293                gr_printf( CENTERSCREEN-(sw/2), y,"V-Viewing scores W-Waiting");
294
295         }
296
297    y+=LHY(20);
298
299         {
300                 int sw, sh, aw;
301       gr_set_fontcolor(gr_find_closest_color(63,63,63),-1);
302
303       if (Players[Player_num].connected==7)
304        {
305         gr_get_string_size("Waiting for other players...",&sw, &sh, &aw);
306         gr_printf( CENTERSCREEN-(sw/2), y,"Waiting for other players...");
307        }
308       else
309        {
310         gr_get_string_size(TXT_PRESS_ANY_KEY2, &sw, &sh, &aw);
311         gr_printf( CENTERSCREEN-(sw/2), y, TXT_PRESS_ANY_KEY2);
312        }
313         }
314
315   if (Countdown_seconds_left <=0)
316    kmatrix_reactor(TXT_REACTOR_EXPLODED);
317   else
318    {
319      sprintf((char *)&reactor_message, "%s: %d %s  ", TXT_TIME_REMAINING, Countdown_seconds_left, TXT_SECONDS);
320      kmatrix_reactor ((char *)&reactor_message);
321    }
322
323 }
324
325 void kmatrix_reactor (char *message)
326  {
327   static char oldmessage[50]={0};
328   int sw, sh, aw;
329
330   if ((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL))
331         return;
332
333   grd_curcanv->cv_font = SMALL_FONT;
334
335   if (oldmessage[0]!=0)
336    {
337     gr_set_fontcolor(gr_find_closest_color(0,0,0),-1);
338     gr_get_string_size(oldmessage, &sw, &sh, &aw);
339    // gr_printf( CENTERSCREEN-(sw/2), LHY(55+72+12), oldmessage);
340    }
341   gr_set_fontcolor(gr_find_closest_color(0,32,63),-1);
342   gr_get_string_size(message, &sw, &sh, &aw);
343   gr_printf( CENTERSCREEN-(sw/2), LHY(55+72+12), message);
344
345   strcpy ((char *)&oldmessage,message);
346  }
347
348 extern int PhallicLimit,PhallicMan;
349
350 void kmatrix_phallic ()
351  {
352   int sw, sh, aw;
353   char message[80];
354
355   if (!(Game_mode & GM_HOARD))
356         return;
357
358   if ((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL))
359         return;
360  
361   if (PhallicMan==-1)
362         strcpy (message,"There was no record set for this level.");
363   else
364         sprintf (message,"%s had the best record at %d points.",Players[PhallicMan].callsign,PhallicLimit);
365
366   grd_curcanv->cv_font = SMALL_FONT;
367   gr_set_fontcolor(gr_find_closest_color(63,63,63),-1);
368   gr_get_string_size(message, &sw, &sh, &aw);
369   gr_printf( CENTERSCREEN-(sw/2), LHY(55+72+3), message);
370  }
371
372
373 void load_stars(void);
374
375 grs_canvas *StarBackCanvas;
376
377
378 void kmatrix_redraw()
379 {
380         int i, color;
381         int sorted[MAX_NUM_NET_PLAYERS];
382         grs_canvas *tempcanvas;
383   
384    if (Game_mode & GM_MULTI_COOP)
385          {
386           kmatrix_redraw_coop();
387           return;
388          }
389         
390         multi_sort_kill_list();
391
392    tempcanvas=gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
393
394    gr_set_current_canvas (tempcanvas);
395
396    gr_bitmap (0,0,&StarBackCanvas->cv_bitmap);
397
398         grd_curcanv->cv_font = MEDIUM3_FONT;
399
400         gr_string( 0x8000, LHY(10), TXT_KILL_MATRIX_TITLE       );
401
402         grd_curcanv->cv_font = SMALL_FONT;
403
404         multi_get_kill_list(sorted);
405
406         kmatrix_draw_names(sorted);
407
408         for (i=0; i<N_players; i++ )            {
409 //              mprintf((0, "Sorted kill list pos %d = %d.\n", i+1, sorted[i]));
410
411                 if (Game_mode & GM_TEAM)
412                         color = get_team(sorted[i]);
413                 else
414                         color = sorted[i];
415
416      if (Players[sorted[i]].connected==0)
417        gr_set_fontcolor(gr_find_closest_color(31,31,31),-1);
418      else
419        gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
420
421      kmatrix_draw_item( i, sorted );
422         }
423
424         kmatrix_draw_deaths(sorted);
425
426         gr_set_current_canvas(NULL);
427
428         gr_bitmap (0,0,&tempcanvas->cv_bitmap);
429
430         gr_palette_load(gr_palette);
431         gr_free_canvas (tempcanvas);
432 }
433
434 void kmatrix_redraw_coop()
435 {
436         int i, color;
437         int sorted[MAX_NUM_NET_PLAYERS];
438         grs_canvas *tempcanvas;
439        
440         multi_sort_kill_list();
441
442         tempcanvas=gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
443         gr_set_current_canvas (tempcanvas);
444
445         gr_bitmap (0,0,&StarBackCanvas->cv_bitmap);
446
447
448         grd_curcanv->cv_font = MEDIUM3_FONT;
449         gr_string( 0x8000, LHY(10), "COOPERATIVE SUMMARY"       );
450
451         grd_curcanv->cv_font = SMALL_FONT;
452
453         multi_get_kill_list(sorted);
454
455         kmatrix_draw_coop_names(sorted);
456
457         for (i=0; i<N_players; i++ )            {
458
459      color = sorted[i];
460
461      if (Players[sorted[i]].connected==0)
462        gr_set_fontcolor(gr_find_closest_color(31,31,31),-1);
463      else
464        gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
465
466      kmatrix_draw_coop_item( i, sorted );
467         }
468
469         kmatrix_draw_deaths(sorted);
470
471         gr_set_current_canvas(NULL);
472
473         gr_bitmap (0,0,&tempcanvas->cv_bitmap);
474
475         gr_palette_load(gr_palette);
476         gr_free_canvas (tempcanvas);
477 }
478
479 #define MAX_VIEW_TIME   F1_0*15
480 #define ENDLEVEL_IDLE_TIME      F1_0*10
481
482 fix StartAbortMenuTime;
483
484
485 #ifdef MACINTOSH
486 extern void load_stars_palette();
487 #endif
488
489 extern void network_endlevel_poll3( int nitems, struct newmenu_item * menus, int * key, int citem );
490
491 void kmatrix_view(int network)
492 {                                                                                        
493    int i, k, done,choice;
494         fix entry_time = timer_get_approx_seconds();
495         int key;
496    int oldstates[MAX_PLAYERS];
497    int previous_seconds_left=-1;
498    int num_ready,num_escaped;
499
500         network=Game_mode & GM_NETWORK;
501
502    for (i=0;i<MAX_NUM_NET_PLAYERS;i++)
503         digi_kill_sound_linked_to_object (Players[i].objnum);
504         
505    set_screen_mode( SCREEN_MENU );
506
507    StarBackCanvas=gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
508    gr_set_current_canvas(StarBackCanvas);
509         #ifdef MACINTOSH
510         if (virtual_memory_on) {
511                 load_stars_palette();           // horrible hack to prevent too much paging when doing endlevel syncing
512                 gr_clear_canvas( BM_XRGB(0, 0, 0) );
513         } else
514         #endif                                                  // note link to above if/else pair
515                 load_stars();
516   
517    WaitingForOthers=0;
518    kmatrix_redraw();
519
520         //@@gr_palette_fade_in( gr_palette,32, 0);
521         game_flush_inputs();
522
523         done = 0;
524
525    for (i=0;i<N_players;i++)
526     oldstates[i]=Players[i].connected;
527
528         if (network)
529            network_endlevel(&key);
530
531         while(!done)    {
532       kmatrix_kills_changed = 0;
533       for (i=0; i<4; i++ )
534           if (joy_get_button_down_cnt(i)>0)
535                           {
536                                   if (is_D2_OEM)
537                                   {
538                                          if (Current_level_num==8)
539                                                 {
540                         Players[Player_num].connected=0;
541                                                  if (network)
542                                 network_send_endlevel_packet();
543                                                  gr_free_canvas (StarBackCanvas);
544                                             multi_leave_game();
545                                        Kmatrix_nomovie_message=0;
546                                        longjmp(LeaveGame, 0);
547                         return;
548                                                 }
549                                   }
550
551             Players[Player_num].connected=7;
552                                 if (network)
553                  network_send_endlevel_packet();
554                                 break;
555                           }                     
556         for (i=0; i<3; i++ )    
557           if (mouse_button_down_count(i)>0)
558                                 {
559                                   if (is_D2_OEM)
560                                   {
561                                          if (Current_level_num==8)
562                                                 {
563                         Players[Player_num].connected=0;
564                                                  if (network)
565                                 network_send_endlevel_packet();
566                                                  gr_free_canvas (StarBackCanvas);
567                                             multi_leave_game();
568                                        Kmatrix_nomovie_message=0;
569                                        longjmp(LeaveGame, 0);
570                         return;
571                                                 }
572                                   }
573                                         Players[Player_num].connected=7;
574                                    if (network)
575                        network_send_endlevel_packet();
576                                         break;
577                       }                 
578
579                 //see if redbook song needs to be restarted
580                 songs_check_redbook_repeat();
581
582                 k = key_inkey();
583                 switch( k )     {
584                         case KEY_ENTER:
585                         case KEY_SPACEBAR:
586                                   if ((Game_mode & GM_SERIAL) || (Game_mode & GM_MODEM))                
587                                         {
588                                                 done=1;
589                                                 break;
590                                         }
591
592                                   if (is_D2_OEM)
593                                   {
594                                          if (Current_level_num==8)
595                                                 {
596                         Players[Player_num].connected=0;
597                                                  if (network)
598                                 network_send_endlevel_packet();
599                                                  gr_free_canvas (StarBackCanvas);
600                                             multi_leave_game();
601                                        Kmatrix_nomovie_message=0;
602                                        longjmp(LeaveGame, 0);
603                         return;
604                                                 }
605                                   }
606
607               Players[Player_num].connected=7;
608                                   if (network)  
609                network_send_endlevel_packet();
610               break;
611                         case KEY_ESC:
612                                   if (Game_mode & GM_NETWORK)
613                                         {
614                                          StartAbortMenuTime=timer_get_approx_seconds();
615                                  choice=nm_messagebox1( NULL,network_endlevel_poll3, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
616                                         }
617                                   else
618                           choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
619               if (choice==0)
620                {
621                 Players[Player_num].connected=0;
622                                          if (network)
623                         network_send_endlevel_packet();
624                                          gr_free_canvas (StarBackCanvas);
625                                     multi_leave_game();
626                                Kmatrix_nomovie_message=0;
627                                longjmp(LeaveGame, 0);
628                 return;
629                }
630               else
631                kmatrix_kills_changed=1;
632           
633                                   break;
634
635                         case KEY_PRINT_SCREEN:
636                                 save_screen_shot(0);
637                                 break;
638                         case KEY_BACKSP:
639                                 Int3();
640                                 break;
641                         default:
642                                 break;
643                 }
644                 if (timer_get_approx_seconds() >= (entry_time+MAX_VIEW_TIME) && Players[Player_num].connected!=7)
645                         {
646                                   if (is_D2_OEM)
647                                   {
648                                          if (Current_level_num==8)
649                                                 {
650                         Players[Player_num].connected=0;
651                                                  if (network)
652                                 network_send_endlevel_packet();
653                                                  gr_free_canvas (StarBackCanvas);
654                                             multi_leave_game();
655                                        Kmatrix_nomovie_message=0;
656                                        longjmp(LeaveGame, 0);
657                         return;
658                                                 }
659                                   }
660
661                          if ((Game_mode & GM_SERIAL) || (Game_mode & GM_MODEM))         
662                                 {
663                                         done=1;
664                                         break;
665                                 }
666           Players[Player_num].connected=7;
667                          if (network)
668                   network_send_endlevel_packet();
669                    }    
670
671                 if (network && (Game_mode & GM_NETWORK))
672                 {
673         network_endlevel_poll2(0, NULL, &key, 0);
674                       
675         for (num_escaped=0,num_ready=0,i=0;i<N_players;i++)
676           {
677             if (Players[i].connected && i!=Player_num)
678                {
679                 // Check timeout for idle players
680                 if (timer_get_approx_seconds() > LastPacketTime[i]+ENDLEVEL_IDLE_TIME)
681                    {
682                     mprintf((0, "idle timeout for player %d.\n", i));
683                                   Players[i].connected = 0;
684                     network_send_endlevel_sub(i);
685                    }
686                 }
687
688                if (Players[i].connected!=oldstates[i])
689                   {
690                    if (ConditionLetters[Players[i].connected]!=ConditionLetters[oldstates[i]])
691                      kmatrix_kills_changed=1;
692                    oldstates[i]=Players[i].connected;
693                                                  network_send_endlevel_packet();
694                   }
695                                         if (Players[i].connected==0 || Players[i].connected==7)
696                                           num_ready++;
697
698                if (Players[i].connected!=1)
699                    num_escaped++;
700           }
701
702          if (num_ready>=N_players)
703              done=1;
704          if (num_escaped>=N_players)
705              Countdown_seconds_left=-1;
706
707          if (previous_seconds_left != Countdown_seconds_left)
708             {
709              previous_seconds_left=Countdown_seconds_left;
710                                  kmatrix_kills_changed=1;
711                                 }
712
713          if ( kmatrix_kills_changed )
714             {
715              kmatrix_redraw();
716              kmatrix_kills_changed=0;
717                         }
718
719                 }
720         }
721
722   Players[Player_num].connected=7;
723
724   if (network)
725      network_send_endlevel_packet();  // make sure
726
727
728 // Restore background and exit
729         gr_palette_fade_out( gr_palette, 32, 0 );
730
731         game_flush_inputs();
732
733         gr_free_canvas (StarBackCanvas);
734
735    Kmatrix_nomovie_message=0;
736
737 }