]> icculus.org git repositories - btb/d2x.git/blob - main/kmatrix.c
fix bugfix for 1067
[btb/d2x.git] / main / kmatrix.c
1 /* $Id: kmatrix.c,v 1.6 2003-10-11 09:28:38 btb 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  * Old Log:
20  * Revision 1.6  1995/09/24  10:57:48  allender
21  * made any key move off of kill matrix screen as text indicates it should
22  *
23  * Revision 1.5  1995/08/18  08:33:05  allender
24  * fixed text problem with top level player names
25  *
26  * Revision 1.4  1995/07/26  17:03:05  allender
27  * sort of fixed spacing for mac
28  *
29  * Revision 1.3  1995/06/06  15:36:14  allender
30  * be sure to bitblt to screen inside of kmatrix loop
31  *
32  * Revision 1.2  1995/06/02  07:47:15  allender
33  * removed bogus include files
34  *
35  * Revision 1.1  1995/05/16  15:27:07  allender
36  * Initial revision
37  *
38  * Revision 2.3  1995/05/02  17:01:22  john
39  * Fixed bug with kill list not showing up in VFX mode.
40  *
41  * Revision 2.2  1995/03/21  14:38:20  john
42  * Ifdef'd out the NETWORK code.
43  *
44  * Revision 2.1  1995/03/06  15:22:54  john
45  * New screen techniques.
46  *
47  * Revision 2.0  1995/02/27  11:25:56  john
48  * New version 2.0, which has no anonymous unions, builds with
49  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
50  *
51  * Revision 1.19  1995/02/15  14:47:23  john
52  * Added code to keep track of kills during endlevel.
53  *
54  * Revision 1.18  1995/02/08  11:00:06  rob
55  * Moved string to localized file
56  *
57  * Revision 1.17  1995/02/01  23:45:55  rob
58  * Fixed string.
59  *
60  * Revision 1.16  1995/01/30  21:47:11  rob
61  * Added a line of instructions.
62  *
63  * Revision 1.15  1995/01/20  16:58:43  rob
64  * careless careless careless...
65  *
66  *
67  * Revision 1.14  1995/01/20  13:43:48  rob
68  * Longer time to view.
69  *
70  * Revision 1.13  1995/01/20  13:42:34  rob
71  * Fixed sorting bug.
72  *
73  * Revision 1.12  1995/01/19  17:35:21  rob
74  * Fixed coloration of player names in team mode.
75  *
76  * Revision 1.11  1995/01/16  21:26:15  rob
77  * Fixed it!!
78  *
79  * Revision 1.10  1995/01/16  18:55:41  rob
80  * Added include of network.h
81  *
82  * Revision 1.9  1995/01/16  18:22:35  rob
83  * Fixed problem with signs.
84  *
85  * Revision 1.8  1995/01/12  16:07:51  rob
86  * ADded sorting before display.
87  *
88  * Revision 1.7  1995/01/04  08:46:53  rob
89  * JOHN CHECKED IN FOR ROB !!!
90  *
91  * Revision 1.6  1994/12/09  20:17:20  yuan
92  * Touched up
93  *
94  * Revision 1.5  1994/12/09  19:46:35  yuan
95  * Localized the sucker.
96  *
97  * Revision 1.4  1994/12/09  19:24:58  rob
98  * Yuan's fix to the centering.
99  *
100  * Revision 1.3  1994/12/09  19:02:37  yuan
101  * Cleaned up a bit.
102  *
103  * Revision 1.2  1994/12/09  16:19:46  yuan
104  * kill matrix stuff.
105  *
106  * Revision 1.1  1994/12/09  15:08:58  yuan
107  * Initial revision
108  *
109  *
110  */
111
112 #ifdef HAVE_CONFIG_H
113 #include <conf.h>
114 #endif
115
116 #ifdef WINDOWS
117 #include "desw.h"
118 #endif
119
120 #include <stdio.h>
121 #include <stdlib.h>
122 #include <string.h>
123 #include <ctype.h>
124 #include <stdarg.h>
125
126 #include "pa_enabl.h"       //$$POLY_ACC
127 #include "error.h"
128 #include "pstypes.h"
129 #include "gr.h"
130 #include "mono.h"
131 #include "key.h"
132 #include "palette.h"
133 #include "game.h"
134 #include "gamefont.h"
135 #include "u_mem.h"
136 #include "newmenu.h"
137 #include "menu.h"
138 #include "player.h"
139 #include "screens.h"
140 #include "gamefont.h"
141 #include "cntrlcen.h"
142 #include "mouse.h"
143 #include "joy.h"
144 #include "timer.h"
145 #include "text.h"
146 #include "songs.h"
147 #include "multi.h"
148 #include "kmatrix.h"
149 #include "gauges.h"
150 #include "pcx.h"
151 #include "network.h"
152
153 #if defined(POLY_ACC)
154 #include "poly_acc.h"
155 #endif
156
157 #define CENTERING_OFFSET(x) ((300 - (70 + (x)*25 ))/2)
158 #define CENTERSCREEN (MenuHires?320:160)
159
160 int kmatrix_kills_changed = 0;
161 char ConditionLetters[]={' ','P','E','D','E','E','V','W'};
162 char WaitingForOthers=0;
163
164 int Kmatrix_nomovie_message=0;
165
166 extern char MaxPowerupsAllowed[],PowerupsInMine[];
167
168 void kmatrix_reactor (char *message);
169 void kmatrix_phallic ();
170 void kmatrix_redraw_coop();
171
172 #define LHX(x)          ((x)*(MenuHires?2:1))
173 #define LHY(y)          ((y)*(MenuHires?2.4:1))
174
175 void kmatrix_draw_item( int  i, int *sorted )
176 {
177         int j, x, y;
178         char temp[10];
179
180         y = LHY(50+i*9);
181
182         // Print player name.
183
184         gr_printf( LHX(CENTERING_OFFSET(N_players)), y, "%s", Players[sorted[i]].callsign );
185
186    if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
187            gr_printf (LHX(CENTERING_OFFSET(N_players)-15),y,"%c",ConditionLetters[Players[sorted[i]].connected]);
188    
189         for (j=0; j<N_players; j++) {
190
191                 x = LHX(70 + CENTERING_OFFSET(N_players) + j*25);
192
193                 if (sorted[i]==sorted[j]) {
194                         if (kill_matrix[sorted[i]][sorted[j]] == 0) {
195                                 gr_set_fontcolor( BM_XRGB(10,10,10),-1 );
196                                 gr_printf( x, y, "%d", kill_matrix[sorted[i]][sorted[j]] );
197                         } else {
198                                 gr_set_fontcolor( BM_XRGB(25,25,25),-1 );
199                                 gr_printf( x, y, "-%d", kill_matrix[sorted[i]][sorted[j]] );
200                         }
201                 } else {
202                         if (kill_matrix[sorted[i]][sorted[j]] <= 0) {
203                                 gr_set_fontcolor( BM_XRGB(10,10,10),-1 );
204                                 gr_printf( x, y, "%d", kill_matrix[sorted[i]][sorted[j]] );
205                         } else {
206                                 gr_set_fontcolor( BM_XRGB(25,25,25),-1 );
207                                 gr_printf( x, y, "%d", kill_matrix[sorted[i]][sorted[j]] );
208                         }
209                 }
210
211         }
212
213   if (Players[sorted[i]].net_killed_total+Players[sorted[i]].net_kills_total==0)
214         sprintf (temp,"NA");
215   else
216    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));                
217                 
218         x = LHX(60 + CENTERING_OFFSET(N_players) + N_players*25);
219         gr_set_fontcolor( BM_XRGB(25,25,25),-1 );
220         gr_printf( x ,y,"%4d/%s",Players[sorted[i]].net_kills_total,temp);
221 }
222
223 void kmatrix_draw_coop_item( int  i, int *sorted )
224 {
225         int  x, y;
226
227         y = LHY(50+i*9);
228
229         // Print player name.
230
231         gr_printf( LHX(CENTERING_OFFSET(N_players)), y, "%s", Players[sorted[i]].callsign );
232    gr_printf (LHX(CENTERING_OFFSET(N_players)-15),y,"%c",ConditionLetters[Players[sorted[i]].connected]);
233    
234
235         x = CENTERSCREEN;
236
237         gr_set_fontcolor( BM_XRGB(60,40,10),-1 );
238         gr_printf( x, y, "%d", Players[sorted[i]].score );
239
240         x = CENTERSCREEN+LHX(50);
241
242         gr_set_fontcolor( BM_XRGB(60,40,10),-1 );
243         gr_printf( x, y, "%d", Players[sorted[i]].net_killed_total);
244 }
245
246
247 void kmatrix_draw_names(int *sorted)
248 {
249         int j, x;
250         
251         int color;
252
253    if (Kmatrix_nomovie_message)
254     {
255                 gr_set_fontcolor( BM_XRGB(63,0,0),-1 );
256                 gr_printf( CENTERSCREEN-LHX(40), LHY(20), "(Movie not played)");
257          }
258
259         for (j=0; j<N_players; j++) {
260                 if (Game_mode & GM_TEAM)
261                         color = get_team(sorted[j]);
262                 else
263                         color = sorted[j];
264
265                 x = LHX (70 + CENTERING_OFFSET(N_players) + j*25);
266
267       if (Players[sorted[j]].connected==0)
268         gr_set_fontcolor(gr_find_closest_color(31,31,31),-1);
269       else
270         gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
271
272                 gr_printf( x, LHY(40), "%c", Players[sorted[j]].callsign[0] );
273
274         }
275
276         x = LHX(72 + CENTERING_OFFSET(N_players) + N_players*25);
277         gr_set_fontcolor( BM_XRGB(31,31,31),-1 );
278         gr_printf( x, LHY(40), "K/E");
279                 
280 }
281 void kmatrix_draw_coop_names(int *sorted)
282 {
283         sorted=sorted;
284
285    if (Kmatrix_nomovie_message)
286     {
287                 gr_set_fontcolor( BM_XRGB(63,0,0),-1 );
288                 gr_printf( CENTERSCREEN-LHX(40), LHY(20), "(Movie not played)");
289          }
290
291         gr_set_fontcolor( BM_XRGB(63,31,31),-1 );
292         gr_printf( CENTERSCREEN, LHY(40), "SCORE");
293
294         gr_set_fontcolor( BM_XRGB(63,31,31),-1 );
295         gr_printf( CENTERSCREEN+LHX(50), LHY(40), "DEATHS");
296 }
297
298
299 void kmatrix_draw_deaths(int *sorted)
300 {
301         int y,x;
302         char reactor_message[50];
303
304    sorted=sorted;
305
306    y = LHY(55 + 72 + 35);
307         x = LHX(35);
308
309         {
310          
311                 int sw, sh, aw;
312                                         
313       gr_set_fontcolor(gr_find_closest_color(63,20,0),-1);
314       gr_get_string_size("P-Playing E-Escaped D-Died", &sw, &sh, &aw);
315
316            if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
317                    gr_printf( CENTERSCREEN-(sw/2), y,"P-Playing E-Escaped D-Died");
318   
319       y+=(sh+5);
320            gr_get_string_size("V-Viewing scores W-Waiting", &sw, &sh, &aw);
321
322            if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
323                    gr_printf( CENTERSCREEN-(sw/2), y,"V-Viewing scores W-Waiting");
324
325         }
326
327    y+=LHY(20);
328
329         {
330                 int sw, sh, aw;
331       gr_set_fontcolor(gr_find_closest_color(63,63,63),-1);
332
333       if (Players[Player_num].connected==7)
334        {
335         gr_get_string_size("Waiting for other players...",&sw, &sh, &aw);
336         gr_printf( CENTERSCREEN-(sw/2), y,"Waiting for other players...");
337        }
338       else
339        {
340         gr_get_string_size(TXT_PRESS_ANY_KEY2, &sw, &sh, &aw);
341         gr_printf( CENTERSCREEN-(sw/2), y, TXT_PRESS_ANY_KEY2);
342        }
343         }
344
345   if (Countdown_seconds_left <=0)
346    kmatrix_reactor(TXT_REACTOR_EXPLODED);
347   else
348    {
349      sprintf((char *)&reactor_message, "%s: %d %s  ", TXT_TIME_REMAINING, Countdown_seconds_left, TXT_SECONDS);
350      kmatrix_reactor ((char *)&reactor_message);
351    }
352  
353   if (Game_mode & GM_HOARD) 
354           kmatrix_phallic();
355
356 }
357 void kmatrix_draw_coop_deaths(int *sorted)
358 {
359         int j, x, y;
360         char reactor_message[50];
361         
362         y = LHY(55 + N_players * 9);
363
364 //      gr_set_fontcolor(gr_getcolor(player_rgb[j].r,player_rgb[j].g,player_rgb[j].b),-1 );
365         gr_set_fontcolor( BM_XRGB(31,31,31),-1 );
366
367         x = CENTERSCREEN+LHX(50);
368         gr_printf( x, y, TXT_DEATHS );
369
370         for (j=0; j<N_players; j++) {
371                 x = CENTERSCREEN+LHX(50);
372                 gr_printf( x, y, "%d", Players[sorted[j]].net_killed_total );
373         }
374
375    y = LHY(55 + 72 + 35);
376         x = LHX(35);
377
378         {
379          
380                 int sw, sh, aw;
381
382       gr_set_fontcolor(gr_find_closest_color(63,20,0),-1);
383       gr_get_string_size("P-Playing E-Escaped D-Died", &sw, &sh, &aw);
384
385           if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
386               gr_printf( CENTERSCREEN-(sw/2), y,"P-Playing E-Escaped D-Died");
387           
388   
389       y+=(sh+5);
390            gr_get_string_size("V-Viewing scores W-Waiting", &sw, &sh, &aw);
391
392            if (!((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL)))
393                gr_printf( CENTERSCREEN-(sw/2), y,"V-Viewing scores W-Waiting");
394
395         }
396
397    y+=LHY(20);
398
399         {
400                 int sw, sh, aw;
401       gr_set_fontcolor(gr_find_closest_color(63,63,63),-1);
402
403       if (Players[Player_num].connected==7)
404        {
405         gr_get_string_size("Waiting for other players...",&sw, &sh, &aw);
406         gr_printf( CENTERSCREEN-(sw/2), y,"Waiting for other players...");
407        }
408       else
409        {
410         gr_get_string_size(TXT_PRESS_ANY_KEY2, &sw, &sh, &aw);
411         gr_printf( CENTERSCREEN-(sw/2), y, TXT_PRESS_ANY_KEY2);
412        }
413         }
414
415   if (Countdown_seconds_left <=0)
416    kmatrix_reactor(TXT_REACTOR_EXPLODED);
417   else
418    {
419      sprintf((char *)&reactor_message, "%s: %d %s  ", TXT_TIME_REMAINING, Countdown_seconds_left, TXT_SECONDS);
420      kmatrix_reactor ((char *)&reactor_message);
421    }
422
423 }
424
425 void kmatrix_reactor (char *message)
426  {
427   static char oldmessage[50]={0};
428   int sw, sh, aw;
429
430   if ((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL))
431         return;
432
433   grd_curcanv->cv_font = SMALL_FONT;
434
435   if (oldmessage[0]!=0)
436    {
437     gr_set_fontcolor(gr_find_closest_color(0,0,0),-1);
438     gr_get_string_size(oldmessage, &sw, &sh, &aw);
439    // gr_printf( CENTERSCREEN-(sw/2), LHY(55+72+12), oldmessage);
440    }
441   gr_set_fontcolor(gr_find_closest_color(0,32,63),-1);
442   gr_get_string_size(message, &sw, &sh, &aw);
443   gr_printf( CENTERSCREEN-(sw/2), LHY(55+72+12), message);
444
445   strcpy ((char *)&oldmessage,message);
446  }
447
448 extern int PhallicLimit,PhallicMan;
449
450 void kmatrix_phallic ()
451  {
452   int sw, sh, aw;
453   char message[80];
454
455   if (!(Game_mode & GM_HOARD))
456         return;
457
458   if ((Game_mode & GM_MODEM) || (Game_mode & GM_SERIAL))
459         return;
460  
461   if (PhallicMan==-1)
462         strcpy (message,"There was no record set for this level.");
463   else
464         sprintf (message,"%s had the best record at %d points.",Players[PhallicMan].callsign,PhallicLimit);
465
466   grd_curcanv->cv_font = SMALL_FONT;
467   gr_set_fontcolor(gr_find_closest_color(63,63,63),-1);
468   gr_get_string_size(message, &sw, &sh, &aw);
469   gr_printf( CENTERSCREEN-(sw/2), LHY(55+72+3), message);
470  }
471
472
473 void load_stars(void);
474
475 WINDOS(dd_grs_canvas *StarBackCanvas,
476                         grs_canvas *StarBackCanvas
477 );              //,*SaveCanvas;
478
479
480 void kmatrix_redraw()
481 {
482         int i, color;
483         int sorted[MAX_NUM_NET_PLAYERS];
484 WINDOS(
485         dd_grs_canvas *tempcanvas,
486    grs_canvas *tempcanvas
487 );
488   
489    if (Game_mode & GM_MULTI_COOP)
490          {
491           kmatrix_redraw_coop();
492           return;
493          }
494         
495         multi_sort_kill_list();
496
497         WINDOS(
498            tempcanvas=dd_gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h ),
499         tempcanvas=gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h )
500         );
501
502    WINDOS(
503                 dd_gr_set_current_canvas(tempcanvas),
504                 gr_set_current_canvas (tempcanvas)
505         );
506
507         WINDOS (
508                 dd_gr_blt_notrans(StarBackCanvas, 0,0,0,0, tempcanvas,0,0,0,0),
509                 gr_bitmap (0,0,&StarBackCanvas->cv_bitmap)
510         );
511
512 WIN(DDGRLOCK(dd_grd_curcanv));
513         grd_curcanv->cv_font = MEDIUM3_FONT;
514
515         gr_string( 0x8000, LHY(10), TXT_KILL_MATRIX_TITLE       );
516
517         grd_curcanv->cv_font = SMALL_FONT;
518
519         multi_get_kill_list(sorted);
520
521         kmatrix_draw_names(sorted);
522
523         for (i=0; i<N_players; i++ )            {
524 //              mprintf((0, "Sorted kill list pos %d = %d.\n", i+1, sorted[i]));
525
526                 if (Game_mode & GM_TEAM)
527                         color = get_team(sorted[i]);
528                 else
529                         color = sorted[i];
530
531      if (Players[sorted[i]].connected==0)
532        gr_set_fontcolor(gr_find_closest_color(31,31,31),-1);
533      else
534        gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
535
536      kmatrix_draw_item( i, sorted );
537         }
538
539         kmatrix_draw_deaths(sorted);
540 WIN(DDGRUNLOCK(dd_grd_curcanv));
541
542 WINDOS(
543         dd_gr_set_current_canvas(NULL),
544         gr_set_current_canvas(NULL)
545 );
546
547 #if defined(POLY_ACC)
548     pa_save_clut();
549     pa_update_clut(gr_palette, 0, 256, 0);
550 #endif
551
552 PA_DFX (pa_set_frontbuffer_current());
553
554 WINDOS(
555         dd_gr_blt_notrans(tempcanvas, 0,0,0,0, dd_grd_curcanv, 0,0,0,0),
556         gr_bitmap (0,0,&tempcanvas->cv_bitmap)
557 );
558
559 PA_DFX (pa_set_backbuffer_current());
560
561 #if defined(POLY_ACC)
562     pa_restore_clut();
563 #endif
564
565         gr_palette_load(gr_palette);
566 WINDOS(
567         dd_gr_free_canvas(tempcanvas),
568         gr_free_canvas (tempcanvas)
569 );
570 }
571
572 void kmatrix_redraw_coop()
573 {
574         int i, color;
575         int sorted[MAX_NUM_NET_PLAYERS];
576
577 WINDOS(
578         dd_grs_canvas *tempcanvas,
579         grs_canvas *tempcanvas
580 );
581        
582         multi_sort_kill_list();
583
584 WINDOS(
585    tempcanvas=dd_gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h ),
586    tempcanvas=gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h )
587 );
588 WINDOS(
589         dd_gr_set_current_canvas(tempcanvas),
590    gr_set_current_canvas (tempcanvas)
591 );
592
593 WINDOS (
594         dd_gr_blt_notrans(StarBackCanvas, 0,0,0,0, tempcanvas,0,0,0,0),
595         gr_bitmap (0,0,&StarBackCanvas->cv_bitmap)
596 );
597
598
599
600 WIN(DDGRLOCK(dd_grd_curcanv));
601         grd_curcanv->cv_font = MEDIUM3_FONT;
602         gr_string( 0x8000, LHY(10), "COOPERATIVE SUMMARY"       );
603
604         grd_curcanv->cv_font = SMALL_FONT;
605
606         multi_get_kill_list(sorted);
607
608         kmatrix_draw_coop_names(sorted);
609
610         for (i=0; i<N_players; i++ )            {
611
612      color = sorted[i];
613
614      if (Players[sorted[i]].connected==0)
615        gr_set_fontcolor(gr_find_closest_color(31,31,31),-1);
616      else
617        gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
618
619      kmatrix_draw_coop_item( i, sorted );
620         }
621
622         kmatrix_draw_deaths(sorted);
623 WIN(DDGRUNLOCK(dd_grd_curcanv));
624
625 WINDOS(
626         dd_gr_set_current_canvas(NULL),
627         gr_set_current_canvas(NULL)
628 );
629
630 #if defined(POLY_ACC)
631     pa_save_clut();
632     pa_update_clut(gr_palette, 0, 256, 0);
633 #endif
634
635 PA_DFX (pa_set_frontbuffer_current());
636
637 WINDOS(
638         dd_gr_blt_notrans(tempcanvas, 0,0,0,0, dd_grd_curcanv, 0,0,0,0),
639         gr_bitmap (0,0,&tempcanvas->cv_bitmap)
640 );
641
642 PA_DFX (pa_set_backbuffer_current());
643
644 #if defined(POLY_ACC)
645     pa_restore_clut();
646 #endif
647
648         gr_palette_load(gr_palette);
649 WINDOS(
650         dd_gr_free_canvas(tempcanvas),
651         gr_free_canvas (tempcanvas)
652 );
653 }
654
655 #define MAX_VIEW_TIME   F1_0*15
656 #define ENDLEVEL_IDLE_TIME      F1_0*10
657
658 fix StartAbortMenuTime;
659
660
661 #ifdef MACINTOSH
662 extern void load_stars_palette();
663 #endif
664
665 extern void network_endlevel_poll3( int nitems, struct newmenu_item * menus, int * key, int citem );
666
667 void kmatrix_view(int network)
668 {                                                                                        
669    int i, k, done,choice;
670         fix entry_time = timer_get_approx_seconds();
671         int key;
672    int oldstates[MAX_PLAYERS];
673    int previous_seconds_left=-1;
674    int num_ready,num_escaped;
675
676         network=Game_mode & GM_NETWORK;
677
678    for (i=0;i<MAX_NUM_NET_PLAYERS;i++)
679         digi_kill_sound_linked_to_object (Players[i].objnum);
680         
681    set_screen_mode( SCREEN_MENU );
682
683         WINDOS(
684                 StarBackCanvas=dd_gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h ),
685                 StarBackCanvas=gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h )
686         );
687         WINDOS(
688                 dd_gr_set_current_canvas(StarBackCanvas),
689            gr_set_current_canvas(StarBackCanvas)
690         );
691         #ifdef MACINTOSH
692         if (virtual_memory_on) {
693                 load_stars_palette();           // horrible hack to prevent too much paging when doing endlevel syncing
694                 gr_clear_canvas( BM_XRGB(0, 0, 0) );
695         } else
696         #endif                                                  // note link to above if/else pair
697                 load_stars();
698   
699    WaitingForOthers=0;
700    kmatrix_redraw();
701
702         //@@gr_palette_fade_in( gr_palette,32, 0);
703         game_flush_inputs();
704
705         done = 0;
706
707    for (i=0;i<N_players;i++)
708     oldstates[i]=Players[i].connected;
709
710         if (network)
711            network_endlevel(&key);
712
713         while(!done)    {
714         #ifdef WINDOWS
715                 MSG msg;
716
717                 DoMessageStuff(&msg);
718
719                 DDGRRESTORE;
720
721         #endif
722
723       kmatrix_kills_changed = 0;
724       for (i=0; i<4; i++ )
725           if (joy_get_button_down_cnt(i)>0)
726                           {
727                                   if (is_D2_OEM)
728                                   {
729                                          if (Current_level_num==8)
730                                                 {
731                         Players[Player_num].connected=0;
732                                                  if (network)
733                                 network_send_endlevel_packet();
734                                                 WINDOS(
735                                                         dd_gr_free_canvas(StarBackCanvas),
736                                                    gr_free_canvas (StarBackCanvas)
737                                                 );
738                                             multi_leave_game();
739                                        Kmatrix_nomovie_message=0;
740                                        longjmp(LeaveGame, 0);
741                         return;
742                                                 }
743                                   }
744
745             Players[Player_num].connected=7;
746                                 if (network)
747                  network_send_endlevel_packet();
748                                 break;
749                           }                     
750         for (i=0; i<3; i++ )    
751           if (mouse_button_down_count(i)>0)
752                                 {
753                                   if (is_D2_OEM)
754                                   {
755                                          if (Current_level_num==8)
756                                                 {
757                         Players[Player_num].connected=0;
758                                                  if (network)
759                                 network_send_endlevel_packet();
760                                                 WINDOS(
761                                                         dd_gr_free_canvas(StarBackCanvas),
762                                                    gr_free_canvas (StarBackCanvas)
763                                                 );
764                                             multi_leave_game();
765                                        Kmatrix_nomovie_message=0;
766                                        longjmp(LeaveGame, 0);
767                         return;
768                                                 }
769                                   }
770                                         Players[Player_num].connected=7;
771                                    if (network)
772                        network_send_endlevel_packet();
773                                         break;
774                       }                 
775
776                 //see if redbook song needs to be restarted
777                 songs_check_redbook_repeat();
778
779                 k = key_inkey();
780                 switch( k )     {
781                         case KEY_ENTER:
782                         case KEY_SPACEBAR:
783                                   if ((Game_mode & GM_SERIAL) || (Game_mode & GM_MODEM))                
784                                         {
785                                                 done=1;
786                                                 break;
787                                         }
788
789                                   if (is_D2_OEM)
790                                   {
791                                          if (Current_level_num==8)
792                                                 {
793                         Players[Player_num].connected=0;
794                                                  if (network)
795                                 network_send_endlevel_packet();
796                                                 WINDOS(
797                                                         dd_gr_free_canvas(StarBackCanvas),
798                                                    gr_free_canvas (StarBackCanvas)
799                                                 );
800                                             multi_leave_game();
801                                        Kmatrix_nomovie_message=0;
802                                        longjmp(LeaveGame, 0);
803                         return;
804                                                 }
805                                   }
806
807               Players[Player_num].connected=7;
808                                   if (network)  
809                network_send_endlevel_packet();
810               break;
811                         case KEY_ESC:
812                                   if (Game_mode & GM_NETWORK)
813                                         {
814                                          StartAbortMenuTime=timer_get_approx_seconds();
815                                  choice=nm_messagebox1( NULL,network_endlevel_poll3, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
816                                         }
817                                   else
818                           choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
819               if (choice==0)
820                {
821                 Players[Player_num].connected=0;
822                                          if (network)
823                         network_send_endlevel_packet();
824                                                 WINDOS(
825                                                         dd_gr_free_canvas(StarBackCanvas),
826                                                    gr_free_canvas (StarBackCanvas)
827                                                 );
828                                     multi_leave_game();
829                                Kmatrix_nomovie_message=0;
830                                longjmp(LeaveGame, 0);
831                 return;
832                }
833               else
834                kmatrix_kills_changed=1;
835           
836                                   break;
837
838                         case KEY_PRINT_SCREEN:
839                                 save_screen_shot(0);
840                                 break;
841                         case KEY_BACKSP:
842                                 Int3();
843                                 break;
844                         default:
845                                 break;
846                 }
847                 if (timer_get_approx_seconds() >= (entry_time+MAX_VIEW_TIME) && Players[Player_num].connected!=7)
848                         {
849                                   if (is_D2_OEM)
850                                   {
851                                          if (Current_level_num==8)
852                                                 {
853                         Players[Player_num].connected=0;
854                                                  if (network)
855                                 network_send_endlevel_packet();
856                                                 WINDOS(
857                                                         dd_gr_free_canvas(StarBackCanvas),
858                                                    gr_free_canvas (StarBackCanvas)
859                                                 );
860                                             multi_leave_game();
861                                        Kmatrix_nomovie_message=0;
862                                        longjmp(LeaveGame, 0);
863                         return;
864                                                 }
865                                   }
866
867                          if ((Game_mode & GM_SERIAL) || (Game_mode & GM_MODEM))         
868                                 {
869                                         done=1;
870                                         break;
871                                 }
872           Players[Player_num].connected=7;
873                          if (network)
874                   network_send_endlevel_packet();
875                    }    
876
877                 if (network && (Game_mode & GM_NETWORK))
878                 {
879         network_endlevel_poll2(0, NULL, &key, 0);
880                       
881         for (num_escaped=0,num_ready=0,i=0;i<N_players;i++)
882           {
883             if (Players[i].connected && i!=Player_num)
884                {
885                 // Check timeout for idle players
886                 if (timer_get_approx_seconds() > LastPacketTime[i]+ENDLEVEL_IDLE_TIME)
887                    {
888                     mprintf((0, "idle timeout for player %d.\n", i));
889                                   Players[i].connected = 0;
890                     network_send_endlevel_sub(i);
891                    }
892                 }
893
894                if (Players[i].connected!=oldstates[i])
895                   {
896                    if (ConditionLetters[Players[i].connected]!=ConditionLetters[oldstates[i]])
897                      kmatrix_kills_changed=1;
898                    oldstates[i]=Players[i].connected;
899                                                  network_send_endlevel_packet();
900                   }
901                                         if (Players[i].connected==0 || Players[i].connected==7)
902                                           num_ready++;
903
904                if (Players[i].connected!=1)
905                    num_escaped++;
906           }
907
908          if (num_ready>=N_players)
909              done=1;
910          if (num_escaped>=N_players)
911              Countdown_seconds_left=-1;
912
913          if (previous_seconds_left != Countdown_seconds_left)
914             {
915              previous_seconds_left=Countdown_seconds_left;
916                                  kmatrix_kills_changed=1;
917                                 }
918
919          if ( kmatrix_kills_changed )
920             {
921              kmatrix_redraw();
922              kmatrix_kills_changed=0;
923                         }
924
925                 }
926         }
927
928   Players[Player_num].connected=7;
929
930   if (network)
931      network_send_endlevel_packet();  // make sure
932
933
934 // Restore background and exit
935         gr_palette_fade_out( gr_palette, 32, 0 );
936
937         game_flush_inputs();
938
939         WINDOS(
940                 dd_gr_free_canvas(StarBackCanvas),
941                 gr_free_canvas (StarBackCanvas)
942         );
943
944    Kmatrix_nomovie_message=0;
945
946 }