5fd56c0be23b556247a511e3621118d75428daec
[rocksndiamonds.git] / src / events.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  (c) 1995-98 Artsoft Entertainment                       *
5 *              Holger Schemel                              *
6 *              Oststrasse 11a                              *
7 *              33604 Bielefeld                             *
8 *              phone: ++49 +521 290471                     *
9 *              email: aeglos@valinor.owl.de                *
10 *----------------------------------------------------------*
11 *  events.c                                                *
12 ***********************************************************/
13
14 #include "events.h"
15 #include "init.h"
16 #include "screens.h"
17 #include "tools.h"
18 #include "game.h"
19 #include "editor.h"
20 #include "misc.h"
21 #include "tape.h"
22 #include "joystick.h"
23 #include "network.h"
24
25 void EventLoop(void)
26 {
27   while(1)
28   {
29     if (XPending(display))      /* got event from X server */
30     {
31       XEvent event;
32
33       XNextEvent(display, &event);
34
35       switch(event.type)
36       {
37         case ButtonPress:
38         case ButtonRelease:
39           HandleButtonEvent((XButtonEvent *) &event);
40           break;
41
42         case MotionNotify:
43           HandleMotionEvent((XMotionEvent *) &event);
44           break;
45
46         case KeyPress:
47         case KeyRelease:
48           HandleKeyEvent((XKeyEvent *) &event);
49           break;
50
51         default:
52           HandleOtherEvents(&event);
53           break;
54       }
55     }
56
57     HandleNoXEvent();
58
59     /* don't use all CPU time when idle; the main loop while playing
60        has its own synchronization and is CPU friendly, too */
61
62     if (game_status != PLAYING)
63     {
64       XSync(display, FALSE);
65       Delay(10);
66     }
67
68
69
70 #if 0
71     else                        /* got no event, but don't be lazy... */
72     {
73       HandleNoXEvent();
74
75       /* don't use all CPU time when idle; the main loop while playing
76          has its own synchronization and is CPU friendly, too */
77
78       if (game_status != PLAYING)
79       {
80         XSync(display, FALSE);
81         Delay(10);
82       }
83     }
84 #endif
85
86
87
88     if (game_status == EXITGAME)
89       return;
90   }
91 }
92
93 void HandleOtherEvents(XEvent *event)
94 {
95   switch(event->type)
96   {
97     case Expose:
98       HandleExposeEvent((XExposeEvent *) event);
99       break;
100
101     case UnmapNotify:
102       SleepWhileUnmapped();
103       break;
104
105     case FocusIn:
106     case FocusOut:
107       HandleFocusEvent((XFocusChangeEvent *) event);
108       break;
109
110     case ClientMessage:
111       HandleClientMessageEvent((XClientMessageEvent *) event);
112       break;
113
114     default:
115       break;
116   }
117 }
118
119 void ClearEventQueue()
120 {
121   while(XPending(display))
122   {
123     XEvent event;
124
125     XNextEvent(display, &event);
126
127     switch(event.type)
128     {
129       case ButtonRelease:
130         button_status = MB_RELEASED;
131         break;
132
133       case KeyRelease:
134         key_joystick_mapping = 0;
135         break;
136
137       default:
138         HandleOtherEvents(&event);
139         break;
140     }
141   }
142 }
143
144 void SleepWhileUnmapped()
145 {
146   boolean window_unmapped = TRUE;
147
148   XAutoRepeatOn(display);
149
150   while(window_unmapped)
151   {
152     XEvent event;
153
154     XNextEvent(display, &event);
155
156     switch(event.type)
157     {
158       case ButtonRelease:
159         button_status = MB_RELEASED;
160         break;
161
162       case KeyRelease:
163         key_joystick_mapping = 0;
164         break;
165
166       case MapNotify:
167         window_unmapped = FALSE;
168         break;
169
170       case UnmapNotify:
171         /* this is only to surely prevent the 'should not happen' case
172          * of recursively looping between 'SleepWhileUnmapped()' and
173          * 'HandleOtherEvents()' which usually calls this funtion.
174          */
175         break;
176
177       default:
178         HandleOtherEvents(&event);
179         break;
180     }
181   }
182
183   if (game_status==PLAYING)
184     XAutoRepeatOff(display);
185 }
186
187 void HandleExposeEvent(XExposeEvent *event)
188 {
189   int x = event->x, y = event->y;
190   int width = event->width, height = event->height;
191
192   if (setup.direct_draw_on && game_status==PLAYING)
193   {
194     int xx,yy;
195     int x1 = (x-SX)/TILEX, y1 = (y-SY)/TILEY;
196     int x2 = (x-SX+width)/TILEX, y2 = (y-SY+height)/TILEY;
197
198     SetDrawtoField(DRAW_BACKBUFFER);
199
200     for(xx=0; xx<SCR_FIELDX; xx++)
201       for(yy=0; yy<SCR_FIELDY; yy++)
202         if (xx>=x1 && xx<=x2 && yy>=y1 && yy<=y2)
203           DrawScreenField(xx,yy);
204     DrawAllPlayers();
205
206     SetDrawtoField(DRAW_DIRECT);
207   }
208
209   if (setup.soft_scrolling_on && game_status == PLAYING)
210   {
211     int fx = FX, fy = FY;
212
213     fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
214     fy += (ScreenMovDir & (MV_UP|MV_DOWN)    ? ScreenGfxPos : 0);
215
216     XCopyArea(display,fieldbuffer,backbuffer,gc,
217               fx,fy, SXSIZE,SYSIZE,
218               SX,SY);
219   }
220
221   XCopyArea(display,drawto,window,gc, x,y, width,height, x,y);
222
223   XFlush(display);
224 }
225
226 void HandleButtonEvent(XButtonEvent *event)
227 {
228   motion_status = FALSE;
229
230   if (event->type==ButtonPress)
231     button_status = event->button;
232   else
233     button_status = MB_RELEASED;
234
235   HandleButton(event->x, event->y, button_status);
236 }
237
238 void HandleMotionEvent(XMotionEvent *event)
239 {
240   motion_status = TRUE;
241
242   HandleButton(event->x, event->y, button_status);
243 }
244
245 void HandleKeyEvent(XKeyEvent *event)
246 {
247   int key_status = (event->type == KeyPress ? KEY_PRESSED : KEY_RELEASED);
248   unsigned int event_state = (game_status != PLAYING ? event->state : 0);
249   KeySym key = XLookupKeysym(event, event_state);
250
251   HandleKey(key, key_status);
252 }
253
254 void HandleFocusEvent(XFocusChangeEvent *event)
255 {
256   static int old_joystick_status = -1;
257
258   if (event->type == FocusOut)
259   {
260     XAutoRepeatOn(display);
261     old_joystick_status = joystick_status;
262     joystick_status = JOYSTICK_OFF;
263     key_joystick_mapping = 0;
264   }
265   else if (event->type == FocusIn)
266   {
267     if (game_status == PLAYING)
268       XAutoRepeatOff(display);
269     if (old_joystick_status != -1)
270       joystick_status = old_joystick_status;
271   }
272 }
273
274 void HandleClientMessageEvent(XClientMessageEvent *event)
275 {
276   if ((event->window == window) &&
277       (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
278     CloseAllAndExit(0);
279 }
280
281 void HandleButton(int mx, int my, int button)
282 {
283   static int old_mx = 0, old_my = 0;
284
285   if (mx<0 || my<0)
286   {
287     mx = old_mx;
288     my = old_my;
289   }
290   else
291   {
292     old_mx = mx;
293     old_my = my;
294
295     HandleVideoButtons(mx,my,button);
296     HandleSoundButtons(mx,my,button);
297     HandleGameButtons(mx,my,button);
298   }
299
300 #ifdef DEBUG
301   if (game_status == PLAYING && !button)
302   {
303     int sx = (mx - SX) / TILEX;
304     int sy = (my - SY) / TILEY;
305
306     if (IN_VIS_FIELD(sx,sy))
307     {
308       int x = LEVELX(sx);
309       int y = LEVELY(sy);
310
311       printf("INFO: Feld[%d][%d] == %d\n", x,y, Feld[x][y]);
312       printf("      Store[%d][%d] == %d\n", x,y, Store[x][y]);
313       printf("      Store2[%d][%d] == %d\n", x,y, Store2[x][y]);
314       printf("      StorePlayer[%d][%d] == %d\n", x,y, StorePlayer[x][y]);
315       printf("      MovPos[%d][%d] == %d\n", x,y, MovPos[x][y]);
316       printf("      MovDir[%d][%d] == %d\n", x,y, MovDir[x][y]);
317       printf("      MovDelay[%d][%d] == %d\n", x,y, MovDelay[x][y]);
318       printf("\n");
319     }
320   }
321 #endif
322
323   switch(game_status)
324   {
325     case MAINMENU:
326       HandleMainMenu(mx,my,0,0,button);
327       break;
328
329     case TYPENAME:
330       HandleTypeName(0,XK_Return);
331       break;
332
333     case CHOOSELEVEL:
334       HandleChooseLevel(mx,my,0,0,button);
335       break;
336
337     case HALLOFFAME:
338       HandleHallOfFame(button);
339       break;
340
341     case LEVELED:
342       LevelEd(mx,my,button);
343       break;
344
345     case HELPSCREEN:
346       HandleHelpScreen(button);
347       break;
348
349     case SETUP:
350       HandleSetupScreen(mx,my,0,0,button);
351       break;
352
353     case SETUPINPUT:
354       HandleSetupInputScreen(mx,my,0,0,button);
355       break;
356
357     case PLAYING:
358
359       /* --> NoXEvent() will follow */
360
361       /*
362       HandleGameActions(0);
363       */
364
365       break;
366
367     default:
368       break;
369   }
370 }
371
372 void HandleKey(KeySym key, int key_status)
373 {
374   int joy = 0;
375   static struct SetupKeyboardInfo custom_key;
376   static struct
377   {
378     KeySym *keysym_custom;
379     KeySym keysym_default;
380     byte action;
381   } key_info[] =
382   {
383     { &custom_key.left,  DEFAULT_KEY_LEFT,  JOY_LEFT     },
384     { &custom_key.right, DEFAULT_KEY_RIGHT, JOY_RIGHT    },
385     { &custom_key.up,    DEFAULT_KEY_UP,    JOY_UP       },
386     { &custom_key.down,  DEFAULT_KEY_DOWN,  JOY_DOWN     },
387     { &custom_key.snap,  DEFAULT_KEY_SNAP,  JOY_BUTTON_1 },
388     { &custom_key.bomb,  DEFAULT_KEY_BOMB,  JOY_BUTTON_2 }
389   };
390
391   if (game_status == PLAYING)
392   {
393     int pnr;
394
395     for (pnr=0; pnr<MAX_PLAYERS; pnr++)
396     {
397       int i;
398       byte key_action = 0;
399
400       if (setup.input[pnr].use_joystick)
401         continue;
402
403       custom_key = setup.input[pnr].key;
404
405       for (i=0; i<6; i++)
406         if (key == *key_info[i].keysym_custom)
407           key_action |= key_info[i].action;
408
409       if (key_status == KEY_PRESSED)
410       {
411         if (network_playing)
412           local_player->action |= key_action;
413         else
414           stored_player[pnr].action |= key_action;
415       }
416       else
417       {
418         if (network_playing)
419           local_player->action &= ~key_action;
420         else
421           stored_player[pnr].action &= ~key_action;
422       }
423     }
424   }
425   else
426   {
427     int i;
428
429     for (i=0; i<6; i++)
430       if (key == key_info[i].keysym_default)
431         joy |= key_info[i].action;
432   }
433
434
435 #if 0
436
437
438   /* Map cursor keys to joystick directions */
439
440   switch(key)
441   {
442     case XK_Left:               /* normale Richtungen */
443 #ifdef XK_KP_Left
444     case XK_KP_Left:
445 #endif
446     case XK_KP_4:
447 #ifndef MSDOS
448     case XK_J:
449 #endif
450     case XK_j:
451       joy |= JOY_LEFT;
452       break;
453
454     case XK_Right:
455 #ifdef XK_KP_Right
456     case XK_KP_Right:
457 #endif
458     case XK_KP_6:
459 #ifndef MSDOS
460     case XK_K:
461 #endif
462     case XK_k:
463       joy |= JOY_RIGHT;
464       break;
465
466     case XK_Up:
467 #ifdef XK_KP_Up
468     case XK_KP_Up:
469 #endif
470     case XK_KP_8:
471 #ifndef MSDOS
472     case XK_I:
473 #endif
474     case XK_i:
475       joy |= JOY_UP;
476       break;
477
478     case XK_Down:
479 #ifdef XK_KP_Down
480     case XK_KP_Down:
481 #endif
482     case XK_KP_2:
483 #ifndef MSDOS
484     case XK_M:
485 #endif
486     case XK_m:
487       joy |= JOY_DOWN;
488       break;
489
490 #ifdef XK_KP_Home
491     case XK_KP_Home:            /* Diagonalrichtungen */
492 #endif
493     case XK_KP_7:
494       joy |= JOY_UP | JOY_LEFT;
495       break;
496
497 #ifdef XK_KP_Page_Up
498     case XK_KP_Page_Up:
499 #endif
500     case XK_KP_9:
501       joy = JOY_UP | JOY_RIGHT;
502       break;
503
504 #ifdef XK_KP_End
505     case XK_KP_End:
506 #endif
507     case XK_KP_1:
508       joy |= JOY_DOWN | JOY_LEFT;
509       break;
510
511 #ifdef XK_KP_Page_Down
512     case XK_KP_Page_Down:
513 #endif
514     case XK_KP_3:
515       joy |= JOY_DOWN | JOY_RIGHT;
516       break;
517
518 #ifndef MSDOS
519     case XK_S:                  /* Feld entfernen */
520 #endif
521     case XK_s:
522       joy |= JOY_BUTTON_1 | JOY_LEFT;
523       break;
524
525 #ifndef MSDOS
526     case XK_D:
527 #endif
528     case XK_d:
529       joy |= JOY_BUTTON_1 | JOY_RIGHT;
530       break;
531
532 #ifndef MSDOS
533     case XK_E:
534 #endif
535     case XK_e:
536       joy |= JOY_BUTTON_1 | JOY_UP;
537       break;
538
539 #ifndef MSDOS
540     case XK_X:
541 #endif
542     case XK_x:
543       joy |= JOY_BUTTON_1 | JOY_DOWN;
544       break;
545
546     case XK_Shift_L:            /* Linker Feuerknopf */
547 #ifndef MSDOS
548     case XK_Control_L:
549     case XK_Alt_L:
550     case XK_Meta_L:
551 #endif
552       joy |= JOY_BUTTON_1;
553       break;
554
555     case XK_Shift_R:            /* Rechter Feuerknopf */
556 #ifndef MSDOS
557     case XK_Control_R:
558     case XK_Alt_R:
559     case XK_Meta_R:
560     case XK_Mode_switch:
561     case XK_Multi_key:
562     case XK_B:                  /* (Bombe legen) */
563 #endif
564     case XK_b:
565       joy |= JOY_BUTTON_2;
566       break;
567
568     default:
569       break;
570   }
571
572
573 #endif
574
575
576   if (joy)
577   {
578     if (key_status == KEY_PRESSED)
579       key_joystick_mapping |= joy;
580     else
581       key_joystick_mapping &= ~joy;
582
583     HandleJoystick();
584   }
585
586   if (game_status != PLAYING)
587     key_joystick_mapping = 0;
588
589   if (key_status == KEY_RELEASED)
590     return;
591
592   if (key==XK_Return && game_status==PLAYING && AllPlayersGone)
593   {
594     CloseDoor(DOOR_CLOSE_1);
595     game_status = MAINMENU;
596     DrawMainMenu();
597     return;
598   }
599
600   if (key==XK_Escape && game_status!=MAINMENU)  /* quick quit to MAINMENU */
601   {
602     CloseDoor(DOOR_CLOSE_1 | DOOR_NO_DELAY);
603     game_status = MAINMENU;
604     DrawMainMenu();
605     return;
606   }
607
608   if (game_status==PLAYING && (tape.playing || tape.pausing))
609     return;
610
611   switch(game_status)
612   {
613     case TYPENAME:
614       HandleTypeName(0,key);
615       break;
616
617     case MAINMENU:
618     case CHOOSELEVEL:
619     case SETUP:
620     case SETUPINPUT:
621       switch(key)
622       {
623         case XK_Return:
624           if (game_status==MAINMENU)
625             HandleMainMenu(0,0,0,0,MB_MENU_CHOICE);
626           else if (game_status==CHOOSELEVEL)
627             HandleChooseLevel(0,0,0,0,MB_MENU_CHOICE);
628           else if (game_status==SETUP)
629             HandleSetupScreen(0,0,0,0,MB_MENU_CHOICE);
630           else if (game_status==SETUPINPUT)
631             HandleSetupInputScreen(0,0,0,0,MB_MENU_CHOICE);
632           break;
633
634         default:
635           break;
636       }
637       break;
638
639     case HELPSCREEN:
640       HandleHelpScreen(MB_RELEASED);
641       break;
642
643     case HALLOFFAME:
644       switch(key)
645       {
646         case XK_Return:
647           game_status = MAINMENU;
648           DrawMainMenu();
649           BackToFront();
650           break;
651
652         default:
653           break;
654       }
655       break;
656
657     case LEVELED:
658       LevelNameTyping(key);
659       break;
660
661     case PLAYING:
662     {
663       switch(key)
664       {
665
666 #ifdef DEBUG
667         case XK_0:
668         case XK_1:
669         case XK_2:
670         case XK_3:
671         case XK_4:
672         case XK_5:
673         case XK_6:
674         case XK_7:
675         case XK_8:
676         case XK_9:
677           if (key == XK_0)
678             GameFrameDelay = 500;
679           else
680             GameFrameDelay = (key - XK_0) * 10;
681           printf("Game speed == %d%% (%d ms delay between two frames)\n",
682                  GAME_FRAME_DELAY * 100 / GameFrameDelay, GameFrameDelay);
683           break;
684
685
686 #if 0
687         case XK_a:
688           if (ScrollStepSize == TILEX/8)
689             ScrollStepSize = TILEX/4;
690           else
691             ScrollStepSize = TILEX/8;
692           printf("ScrollStepSize == %d\n", ScrollStepSize);
693           break;
694 #endif
695
696         case XK_f:
697           ScrollStepSize = TILEX/8;
698           printf("ScrollStepSize == %d (1/8)\n", ScrollStepSize);
699           break;
700
701         case XK_g:
702           ScrollStepSize = TILEX/4;
703           printf("ScrollStepSize == %d (1/4)\n", ScrollStepSize);
704           break;
705
706         case XK_h:
707           ScrollStepSize = TILEX/2;
708           printf("ScrollStepSize == %d (1/2)\n", ScrollStepSize);
709           break;
710
711         case XK_l:
712           ScrollStepSize = TILEX;
713           printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
714           break;
715
716 #ifndef MSDOS
717         case XK_Q:
718 #endif
719         case XK_q:
720           local_player->dynamite = 1000;
721           break;
722
723
724
725 #if 0
726
727         case XK_x:
728
729           {
730             int i,j,k, num_steps = 8, step_size = TILEX / num_steps;
731             static long scroll_delay=0;
732             long scroll_delay_value = 4*4 / num_steps;
733
734             printf("Scroll test\n");
735
736             for(i=0;i<3;i++)
737             {
738               for(j=0;j<SCR_FIELDX;j++)
739               {
740                 for(k=0;k<num_steps;k++)
741                 {
742                   int xxx = j*TILEX+k*step_size;
743                   int done = 0;
744
745                   while(!done)
746                   {
747                     if (DelayReached(&scroll_delay, scroll_delay_value))
748                     {
749                       XCopyArea(display,fieldbuffer,window,gc,
750                                 SX+xxx,SY,
751                                 SXSIZE-xxx,SYSIZE,
752                                 SX,SY);
753                       XCopyArea(display,fieldbuffer,window,gc,
754                                 SX,SY,
755                                 xxx,SYSIZE,
756                                 SX+SXSIZE-xxx,SY);
757   
758                       XFlush(display);
759                       XSync(display,FALSE);
760
761                       done = 1;
762                     }
763                     else
764                     {
765                       Delay(1);
766                     }
767                   }
768   
769                   /*
770                   Delay(160 / num_steps);
771                   */
772                   /*
773                   Delay(120 / num_steps);
774                   */
775                 }
776               }
777             }
778           }
779
780           break;
781
782         case XK_y:
783           /*
784           {
785             printf("FX = %d, FY = %d\n", FX,FY);
786
787             XCopyArea(display,fieldbuffer,window,gc,
788                       0,0,
789                       MIN(WIN_XSIZE,FXSIZE),MIN(WIN_YSIZE,FYSIZE),
790                       0,0);
791             XFlush(display);
792             XSync(display,FALSE);
793             Delay(1000);
794           }
795           */
796
797           printf("direct_draw_on == %d\n", setup.direct_draw_on);
798
799           break;
800
801         case XK_z:
802           {
803             int i;
804
805             for(i=0; i<MAX_PLAYERS; i++)
806             {
807               printf("Player %d:\n", i);
808               printf("  jx == %d, jy == %d\n",
809                      stored_player[i].jx, stored_player[i].jy);
810               printf("  last_jx == %d, last_jy == %d\n",
811                      stored_player[i].last_jx, stored_player[i].last_jy);
812             }
813             printf("\n");
814           }
815
816           break;
817
818         case XK_t:
819           {
820             char *color[] = { "yellow", "red", "green", "blue" };
821
822             do
823               TestPlayer = (TestPlayer + 1) % MAX_PLAYERS;
824             while(!stored_player[TestPlayer].active);
825
826             printf("TestPlayer = %d (%s player)\n",
827                    TestPlayer, color[TestPlayer]);
828           }
829
830           break;
831 #endif
832 #endif
833
834         default:
835           break;
836       }
837       break;
838     }
839     default:
840       break;
841   }
842 }
843
844 void HandleNoXEvent()
845 {
846   if (button_status && game_status != PLAYING)
847   {
848     HandleButton(-1,-1,button_status);
849     return;
850   }
851
852   if (options.network)
853     HandleNetworking();
854
855   switch(game_status)
856   {
857     case MAINMENU:
858     case CHOOSELEVEL:
859     case HALLOFFAME:
860     case HELPSCREEN:
861     case SETUP:
862     case SETUPINPUT:
863       HandleJoystick();
864       break;
865
866     case PLAYING:
867       HandleJoystick();
868
869       /*
870       HandleGameActions(0);
871       */
872
873       break;
874
875     default:
876       break;
877   }
878 }
879
880 void HandleJoystick()
881 {
882   int joystick  = Joystick();
883   int keyboard  = key_joystick_mapping;
884   int joy       = (joystick | keyboard);
885   int left      = joy & JOY_LEFT;
886   int right     = joy & JOY_RIGHT;
887   int up        = joy & JOY_UP;
888   int down      = joy & JOY_DOWN;
889   int button    = joy & JOY_BUTTON;
890   int newbutton = (JoystickButton() == JOY_BUTTON_NEW_PRESSED);
891   int dx        = (left ? -1    : right ? 1     : 0);
892   int dy        = (up   ? -1    : down  ? 1     : 0);
893
894   switch(game_status)
895   {
896     case MAINMENU:
897     case CHOOSELEVEL:
898     case SETUP:
899     case SETUPINPUT:
900     {
901       static long joystickmove_delay = 0;
902
903       if (joystick && !button && !DelayReached(&joystickmove_delay,150))
904         newbutton = dx = dy = 0;
905
906       if (game_status==MAINMENU)
907         HandleMainMenu(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
908       else if (game_status==CHOOSELEVEL)
909         HandleChooseLevel(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
910       else if (game_status==SETUP)
911         HandleSetupScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
912       else if (game_status==SETUPINPUT)
913         HandleSetupInputScreen(0,0,dx,dy,
914                                newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
915       break;
916     }
917
918     case HALLOFFAME:
919       HandleHallOfFame(!newbutton);
920       break;
921
922     case HELPSCREEN:
923       HandleHelpScreen(!newbutton);
924       break;
925
926     case PLAYING:
927       if (tape.playing || keyboard)
928         newbutton = ((joy & JOY_BUTTON) != 0);
929
930       if (AllPlayersGone && newbutton)
931       {
932         CloseDoor(DOOR_CLOSE_1);
933         game_status = MAINMENU;
934         DrawMainMenu();
935         return;
936       }
937
938       /*
939       if (tape.pausing || AllPlayersGone)
940       {
941         int i;
942
943         for (i=0; i<MAX_PLAYERS; i++)
944           stored_player[i].action = 0;
945       }
946       */
947
948       HandleGameActions();
949       break;
950
951     default:
952       break;
953   }
954 }