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