1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include "libgame/libgame.h"
27 static boolean cursor_inside_playfield = FALSE;
28 static boolean playfield_cursor_set = FALSE;
29 static unsigned long playfield_cursor_delay = 0;
32 /* event filter especially needed for SDL event filtering due to
33 delay problems with lots of mouse motion events when mouse button
34 not pressed (X11 can handle this with 'PointerMotionHintMask') */
36 int FilterMouseMotionEvents(const Event *event)
40 /* non-motion events are directly passed to event handler functions */
41 if (event->type != EVENT_MOTIONNOTIFY)
44 motion = (MotionEvent *)event;
45 cursor_inside_playfield = (motion->x >= SX && motion->x < SX + SXSIZE &&
46 motion->y >= SY && motion->y < SY + SYSIZE);
48 if (game_status == GAME_MODE_PLAYING && playfield_cursor_set)
50 SetMouseCursor(CURSOR_DEFAULT);
51 playfield_cursor_set = FALSE;
52 DelayReached(&playfield_cursor_delay, 0);
55 /* skip mouse motion events without pressed button outside level editor */
56 if (button_status == MB_RELEASED &&
57 game_status != GAME_MODE_EDITOR && game_status != GAME_MODE_PLAYING)
63 /* to prevent delay problems, skip mouse motion events if the very next
64 event is also a mouse motion event (and therefore effectively only
65 handling the last of a row of mouse motion events in the event queue) */
67 boolean SkipPressedMouseMotionEvent(const Event *event)
69 /* nothing to do if the current event is not a mouse motion event */
70 if (event->type != EVENT_MOTIONNOTIFY)
73 /* only skip motion events with pressed button outside level editor */
74 if (button_status == MB_RELEASED ||
75 game_status == GAME_MODE_EDITOR || game_status == GAME_MODE_PLAYING)
82 PeekEvent(&next_event);
84 /* if next event is also a mouse motion event, skip the current one */
85 if (next_event.type == EVENT_MOTIONNOTIFY)
92 /* this is only really needed for non-SDL targets to filter unwanted events;
93 when using SDL with properly installed event filter, this function can be
94 replaced with a simple "NextEvent()" call, but it doesn't hurt either */
96 static boolean NextValidEvent(Event *event)
98 while (PendingEvent())
100 boolean handle_this_event = FALSE;
104 if (FilterMouseMotionEvents(event))
105 handle_this_event = TRUE;
107 if (SkipPressedMouseMotionEvent(event))
108 handle_this_event = FALSE;
110 if (handle_this_event)
121 if (PendingEvent()) /* got event */
125 while (NextValidEvent(&event))
129 case EVENT_BUTTONPRESS:
130 case EVENT_BUTTONRELEASE:
131 HandleButtonEvent((ButtonEvent *) &event);
134 case EVENT_MOTIONNOTIFY:
135 HandleMotionEvent((MotionEvent *) &event);
139 case EVENT_KEYRELEASE:
140 HandleKeyEvent((KeyEvent *) &event);
144 HandleOtherEvents(&event);
151 /* when playing, display a special mouse pointer inside the playfield */
152 if (game_status == GAME_MODE_PLAYING && !tape.pausing)
154 if (!playfield_cursor_set && cursor_inside_playfield &&
155 DelayReached(&playfield_cursor_delay, 1000))
157 SetMouseCursor(CURSOR_PLAYFIELD);
158 playfield_cursor_set = TRUE;
161 else if (playfield_cursor_set)
163 SetMouseCursor(CURSOR_DEFAULT);
164 playfield_cursor_set = FALSE;
170 /* don't use all CPU time when idle; the main loop while playing
171 has its own synchronization and is CPU friendly, too */
173 if (game_status == GAME_MODE_PLAYING)
180 if (!PendingEvent()) /* delay only if no pending events */
184 /* refresh window contents from drawing buffer, if needed */
187 if (game_status == GAME_MODE_QUIT)
192 void HandleOtherEvents(Event *event)
197 HandleExposeEvent((ExposeEvent *) event);
200 case EVENT_UNMAPNOTIFY:
202 /* This causes the game to stop not only when iconified, but also
203 when on another virtual desktop, which might be not desired. */
204 SleepWhileUnmapped();
210 HandleFocusEvent((FocusChangeEvent *) event);
213 case EVENT_CLIENTMESSAGE:
214 HandleClientMessageEvent((ClientMessageEvent *) event);
217 #if defined(TARGET_SDL)
218 case SDL_JOYAXISMOTION:
219 case SDL_JOYBUTTONDOWN:
220 case SDL_JOYBUTTONUP:
221 HandleJoystickEvent(event);
230 void ClearEventQueue()
232 while (PendingEvent())
240 case EVENT_BUTTONRELEASE:
241 button_status = MB_RELEASED;
244 case EVENT_KEYRELEASE:
245 key_joystick_mapping = 0;
249 HandleOtherEvents(&event);
255 void ClearPlayerAction()
259 /* simulate key release events for still pressed keys */
260 key_joystick_mapping = 0;
261 for (i = 0; i < MAX_PLAYERS; i++)
262 stored_player[i].action = 0;
265 void SleepWhileUnmapped()
267 boolean window_unmapped = TRUE;
269 KeyboardAutoRepeatOn();
271 while (window_unmapped)
279 case EVENT_BUTTONRELEASE:
280 button_status = MB_RELEASED;
283 case EVENT_KEYRELEASE:
284 key_joystick_mapping = 0;
287 case EVENT_MAPNOTIFY:
288 window_unmapped = FALSE;
291 case EVENT_UNMAPNOTIFY:
292 /* this is only to surely prevent the 'should not happen' case
293 * of recursively looping between 'SleepWhileUnmapped()' and
294 * 'HandleOtherEvents()' which usually calls this funtion.
299 HandleOtherEvents(&event);
304 if (game_status == GAME_MODE_PLAYING)
305 KeyboardAutoRepeatOffUnlessAutoplay();
308 void HandleExposeEvent(ExposeEvent *event)
311 RedrawPlayfield(FALSE, event->x, event->y, event->width, event->height);
316 void HandleButtonEvent(ButtonEvent *event)
318 motion_status = FALSE;
320 if (event->type == EVENT_BUTTONPRESS)
321 button_status = event->button;
323 button_status = MB_RELEASED;
325 HandleButton(event->x, event->y, button_status);
328 void HandleMotionEvent(MotionEvent *event)
330 if (!PointerInWindow(window))
331 return; /* window and pointer are on different screens */
333 if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR)
336 motion_status = TRUE;
338 HandleButton(event->x, event->y, button_status);
341 void HandleKeyEvent(KeyEvent *event)
343 int key_status = (event->type==EVENT_KEYPRESS ? KEY_PRESSED : KEY_RELEASED);
344 boolean with_modifiers = (game_status == GAME_MODE_PLAYING ? FALSE : TRUE);
345 Key key = GetEventKey(event, with_modifiers);
346 Key keymod = (with_modifiers ? GetEventKey(event, FALSE) : key);
348 HandleKeyModState(keymod, key_status);
349 HandleKey(key, key_status);
352 void HandleFocusEvent(FocusChangeEvent *event)
354 static int old_joystick_status = -1;
356 if (event->type == EVENT_FOCUSOUT)
358 KeyboardAutoRepeatOn();
359 old_joystick_status = joystick.status;
360 joystick.status = JOYSTICK_NOT_AVAILABLE;
364 else if (event->type == EVENT_FOCUSIN)
366 /* When there are two Rocks'n'Diamonds windows which overlap and
367 the player moves the pointer from one game window to the other,
368 a 'FocusOut' event is generated for the window the pointer is
369 leaving and a 'FocusIn' event is generated for the window the
370 pointer is entering. In some cases, it can happen that the
371 'FocusIn' event is handled by the one game process before the
372 'FocusOut' event by the other game process. In this case the
373 X11 environment would end up with activated keyboard auto repeat,
374 because unfortunately this is a global setting and not (which
375 would be far better) set for each X11 window individually.
376 The effect would be keyboard auto repeat while playing the game
377 (game_status == GAME_MODE_PLAYING), which is not desired.
378 To avoid this special case, we just wait 1/10 second before
379 processing the 'FocusIn' event.
382 if (game_status == GAME_MODE_PLAYING)
385 KeyboardAutoRepeatOffUnlessAutoplay();
388 if (old_joystick_status != -1)
389 joystick.status = old_joystick_status;
393 void HandleClientMessageEvent(ClientMessageEvent *event)
395 if (CheckCloseWindowEvent(event))
399 void HandleButton(int mx, int my, int button)
401 static int old_mx = 0, old_my = 0;
415 if (HandleGadgets(mx, my, button))
417 /* do not handle this button event anymore */
418 mx = my = -32; /* force mouse event to be outside screen tiles */
423 case GAME_MODE_TITLE:
424 HandleTitleScreen(mx,my, 0,0, button);
428 HandleMainMenu(mx,my, 0,0, button);
431 case GAME_MODE_PSEUDO_TYPENAME:
432 HandleTypeName(0, KSYM_Return);
435 case GAME_MODE_LEVELS:
436 HandleChooseLevel(mx,my, 0,0, button);
439 case GAME_MODE_SCORES:
440 HandleHallOfFame(0,0, 0,0, button);
443 case GAME_MODE_EDITOR:
444 HandleLevelEditorIdle();
448 HandleInfoScreen(mx,my, 0,0, button);
451 case GAME_MODE_SETUP:
452 HandleSetupScreen(mx,my, 0,0, button);
455 case GAME_MODE_PLAYING:
457 if (button == MB_PRESSED && !motion_status && IN_GFX_SCREEN(mx, my))
458 DumpTile(LEVELX((mx - SX) / TILEX), LEVELY((my - SY) / TILEY));
467 static boolean is_string_suffix(char *string, char *suffix)
469 int string_len = strlen(string);
470 int suffix_len = strlen(suffix);
472 if (suffix_len > string_len)
475 return (strEqual(&string[string_len - suffix_len], suffix));
478 #define MAX_CHEAT_INPUT_LEN 32
480 static void HandleKeysSpecial(Key key)
482 static char cheat_input[2 * MAX_CHEAT_INPUT_LEN + 1] = "";
483 char letter = getCharFromKey(key);
484 int cheat_input_len = strlen(cheat_input);
490 if (cheat_input_len >= 2 * MAX_CHEAT_INPUT_LEN)
492 for (i = 0; i < MAX_CHEAT_INPUT_LEN + 1; i++)
493 cheat_input[i] = cheat_input[MAX_CHEAT_INPUT_LEN + i];
495 cheat_input_len = MAX_CHEAT_INPUT_LEN;
498 cheat_input[cheat_input_len++] = letter;
499 cheat_input[cheat_input_len] = '\0';
502 printf("::: '%s' [%d]\n", cheat_input, cheat_input_len);
505 if (game_status == GAME_MODE_MAIN)
507 if (is_string_suffix(cheat_input, ":insert-solution-tape") ||
508 is_string_suffix(cheat_input, ":ist"))
510 InsertSolutionTape();
512 else if (is_string_suffix(cheat_input, ":reload-graphics") ||
513 is_string_suffix(cheat_input, ":rg"))
515 ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS);
518 else if (is_string_suffix(cheat_input, ":reload-sounds") ||
519 is_string_suffix(cheat_input, ":rs"))
521 ReloadCustomArtwork(1 << ARTWORK_TYPE_SOUNDS);
524 else if (is_string_suffix(cheat_input, ":reload-music") ||
525 is_string_suffix(cheat_input, ":rm"))
527 ReloadCustomArtwork(1 << ARTWORK_TYPE_MUSIC);
530 else if (is_string_suffix(cheat_input, ":reload-artwork") ||
531 is_string_suffix(cheat_input, ":ra"))
533 ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS |
534 1 << ARTWORK_TYPE_SOUNDS |
535 1 << ARTWORK_TYPE_MUSIC);
538 else if (is_string_suffix(cheat_input, ":dump-level") ||
539 is_string_suffix(cheat_input, ":dl"))
543 else if (is_string_suffix(cheat_input, ":dump-tape") ||
544 is_string_suffix(cheat_input, ":dt"))
549 else if (game_status == GAME_MODE_PLAYING)
552 if (is_string_suffix(cheat_input, ".q"))
553 DEBUG_SetMaximumDynamite();
556 else if (game_status == GAME_MODE_EDITOR)
558 if (is_string_suffix(cheat_input, ":dump-brush") ||
559 is_string_suffix(cheat_input, ":DB"))
563 else if (is_string_suffix(cheat_input, ":DDB"))
570 void HandleKey(Key key, int key_status)
572 boolean anyTextGadgetActiveOrJustFinished = anyTextGadgetActive();
573 static struct SetupKeyboardInfo custom_key;
581 { &custom_key.left, DEFAULT_KEY_LEFT, JOY_LEFT },
582 { &custom_key.right, DEFAULT_KEY_RIGHT, JOY_RIGHT },
583 { &custom_key.up, DEFAULT_KEY_UP, JOY_UP },
584 { &custom_key.down, DEFAULT_KEY_DOWN, JOY_DOWN },
585 { &custom_key.snap, DEFAULT_KEY_SNAP, JOY_BUTTON_1 },
586 { &custom_key.drop, DEFAULT_KEY_DROP, JOY_BUTTON_2 }
591 if (game_status == GAME_MODE_PLAYING)
593 /* only needed for single-step tape recording mode */
594 static boolean clear_button_2[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
595 static boolean element_dropped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
598 for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
602 if (setup.input[pnr].use_joystick)
605 custom_key = setup.input[pnr].key;
607 for (i = 0; i < 6; i++)
608 if (key == *key_info[i].key_custom)
609 key_action |= key_info[i].action;
611 if (tape.single_step && clear_button_2[pnr])
613 stored_player[pnr].action &= ~KEY_BUTTON_2;
614 clear_button_2[pnr] = FALSE;
617 if (key_status == KEY_PRESSED)
618 stored_player[pnr].action |= key_action;
620 stored_player[pnr].action &= ~key_action;
622 if (tape.single_step && tape.recording && tape.pausing)
624 if (key_status == KEY_PRESSED &&
625 (key_action & (KEY_MOTION | KEY_BUTTON_1)))
627 TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
629 if (key_action & KEY_MOTION)
631 if (stored_player[pnr].action & KEY_BUTTON_2)
632 element_dropped[pnr] = TRUE;
635 else if (key_status == KEY_RELEASED &&
636 (key_action & KEY_BUTTON_2))
638 if (!element_dropped[pnr])
640 TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
642 stored_player[pnr].action |= KEY_BUTTON_2;
643 clear_button_2[pnr] = TRUE;
646 element_dropped[pnr] = FALSE;
649 else if (tape.recording && tape.pausing && (key_action & KEY_ACTION))
650 TapeTogglePause(TAPE_TOGGLE_MANUAL);
655 for (i = 0; i < 6; i++)
656 if (key == key_info[i].key_default)
657 joy |= key_info[i].action;
662 if (key_status == KEY_PRESSED)
663 key_joystick_mapping |= joy;
665 key_joystick_mapping &= ~joy;
670 if (game_status != GAME_MODE_PLAYING)
671 key_joystick_mapping = 0;
673 if (key_status == KEY_RELEASED)
676 if (game_status == GAME_MODE_PLAYING && AllPlayersGone &&
677 (key == KSYM_Return || key == setup.shortcut.toggle_pause))
679 CloseDoor(DOOR_CLOSE_1);
680 game_status = GAME_MODE_MAIN;
686 if (game_status == GAME_MODE_MAIN &&
687 (key == setup.shortcut.toggle_pause || key == KSYM_space))
689 StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE);
694 if (game_status == GAME_MODE_MAIN || game_status == GAME_MODE_PLAYING)
696 if (key == setup.shortcut.save_game)
698 else if (key == setup.shortcut.load_game)
700 else if (key == setup.shortcut.toggle_pause)
701 TapeTogglePause(TAPE_TOGGLE_MANUAL);
704 if (game_status == GAME_MODE_PLAYING && !network_playing)
706 int centered_player_nr_next = -999;
708 if (key == setup.shortcut.focus_player_all)
709 centered_player_nr_next = -1;
711 for (i = 0; i < MAX_PLAYERS; i++)
712 if (key == setup.shortcut.focus_player[i])
713 centered_player_nr_next = i;
715 if (centered_player_nr_next != -999)
717 game.centered_player_nr_next = centered_player_nr_next;
718 game.set_centered_player = TRUE;
722 tape.centered_player_nr_next = game.centered_player_nr_next;
723 tape.set_centered_player = TRUE;
728 HandleKeysSpecial(key);
730 if (HandleGadgetsKeyInput(key))
732 if (key != KSYM_Escape) /* always allow ESC key to be handled */
733 key = KSYM_UNDEFINED;
738 case GAME_MODE_PSEUDO_TYPENAME:
739 HandleTypeName(0, key);
742 case GAME_MODE_TITLE:
744 case GAME_MODE_LEVELS:
745 case GAME_MODE_SETUP:
752 /* !!! only use "space" key to start game from main menu !!! */
756 if (game_status == GAME_MODE_TITLE)
757 HandleTitleScreen(0,0, 0,0, MB_MENU_CHOICE);
758 else if (game_status == GAME_MODE_MAIN)
759 HandleMainMenu(0,0, 0,0, MB_MENU_CHOICE);
760 else if (game_status == GAME_MODE_LEVELS)
761 HandleChooseLevel(0,0, 0,0, MB_MENU_CHOICE);
762 else if (game_status == GAME_MODE_SETUP)
763 HandleSetupScreen(0,0, 0,0, MB_MENU_CHOICE);
764 else if (game_status == GAME_MODE_INFO)
765 HandleInfoScreen(0,0, 0,0, MB_MENU_CHOICE);
769 if (game_status == GAME_MODE_TITLE)
770 HandleTitleScreen(0,0, 0,0, MB_MENU_LEAVE);
771 else if (game_status == GAME_MODE_LEVELS)
772 HandleChooseLevel(0,0, 0,0, MB_MENU_LEAVE);
773 else if (game_status == GAME_MODE_SETUP)
774 HandleSetupScreen(0,0, 0,0, MB_MENU_LEAVE);
775 else if (game_status == GAME_MODE_INFO)
776 HandleInfoScreen(0,0, 0,0, MB_MENU_LEAVE);
780 if (game_status == GAME_MODE_LEVELS)
781 HandleChooseLevel(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
782 else if (game_status == GAME_MODE_SETUP)
783 HandleSetupScreen(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
784 else if (game_status == GAME_MODE_INFO)
785 HandleInfoScreen(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
789 if (game_status == GAME_MODE_LEVELS)
790 HandleChooseLevel(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
791 else if (game_status == GAME_MODE_SETUP)
792 HandleSetupScreen(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
793 else if (game_status == GAME_MODE_INFO)
794 HandleInfoScreen(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
799 GameFrameDelay = (GameFrameDelay == 500 ? GAME_FRAME_DELAY : 500);
808 case GAME_MODE_SCORES:
814 game_status = GAME_MODE_MAIN;
819 HandleHallOfFame(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
823 HandleHallOfFame(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
831 case GAME_MODE_EDITOR:
832 if (!anyTextGadgetActiveOrJustFinished || key == KSYM_Escape)
833 HandleLevelEditorKeyInput(key);
836 case GAME_MODE_PLAYING:
841 RequestQuitGame(setup.ask_on_escape);
859 if (GameFrameDelay == 500)
860 GameFrameDelay = GAME_FRAME_DELAY;
862 GameFrameDelay = 500;
865 GameFrameDelay = (key - KSYM_0) * 10;
866 printf("Game speed == %d%% (%d ms delay between two frames)\n",
867 GAME_FRAME_DELAY * 100 / GameFrameDelay, GameFrameDelay);
873 options.debug = FALSE;
874 printf("debug mode disabled\n");
878 options.debug = TRUE;
879 printf("debug mode enabled\n");
884 if (!global.fps_slowdown)
886 global.fps_slowdown = TRUE;
887 global.fps_slowdown_factor = 2;
888 printf("fps slowdown enabled -- display only every 2nd frame\n");
890 else if (global.fps_slowdown_factor == 2)
892 global.fps_slowdown_factor = 4;
893 printf("fps slowdown enabled -- display only every 4th frame\n");
897 global.fps_slowdown = FALSE;
898 global.fps_slowdown_factor = 1;
899 printf("fps slowdown disabled\n");
904 ScrollStepSize = TILEX/8;
905 printf("ScrollStepSize == %d (1/8)\n", ScrollStepSize);
909 ScrollStepSize = TILEX/4;
910 printf("ScrollStepSize == %d (1/4)\n", ScrollStepSize);
914 ScrollStepSize = TILEX/2;
915 printf("ScrollStepSize == %d (1/2)\n", ScrollStepSize);
919 ScrollStepSize = TILEX;
920 printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
924 printf("::: currently using game engine version %d\n",
925 game.engine_version);
936 if (key == KSYM_Escape)
938 game_status = GAME_MODE_MAIN;
948 if (button_status && game_status != GAME_MODE_PLAYING)
950 HandleButton(0, 0, -button_status);
954 #if defined(NETWORK_AVALIABLE)
962 static int HandleJoystickForAllPlayers()
967 for (i = 0; i < MAX_PLAYERS; i++)
972 if (!setup.input[i].use_joystick)
976 joy_action = Joystick(i);
977 result |= joy_action;
979 if (!setup.input[i].use_joystick)
982 stored_player[i].action = joy_action;
988 void HandleJoystick()
990 int joystick = HandleJoystickForAllPlayers();
991 int keyboard = key_joystick_mapping;
992 int joy = (joystick | keyboard);
993 int left = joy & JOY_LEFT;
994 int right = joy & JOY_RIGHT;
995 int up = joy & JOY_UP;
996 int down = joy & JOY_DOWN;
997 int button = joy & JOY_BUTTON;
998 int newbutton = (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED);
999 int dx = (left ? -1 : right ? 1 : 0);
1000 int dy = (up ? -1 : down ? 1 : 0);
1004 case GAME_MODE_TITLE:
1005 case GAME_MODE_MAIN:
1006 case GAME_MODE_LEVELS:
1007 case GAME_MODE_SETUP:
1008 case GAME_MODE_INFO:
1010 static unsigned long joystickmove_delay = 0;
1012 if (joystick && !button &&
1013 !DelayReached(&joystickmove_delay, GADGET_FRAME_DELAY))
1014 newbutton = dx = dy = 0;
1016 if (game_status == GAME_MODE_TITLE)
1017 HandleTitleScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1018 else if (game_status == GAME_MODE_MAIN)
1019 HandleMainMenu(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1020 else if (game_status == GAME_MODE_LEVELS)
1021 HandleChooseLevel(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1022 else if (game_status == GAME_MODE_SETUP)
1023 HandleSetupScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1024 else if (game_status == GAME_MODE_INFO)
1025 HandleInfoScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1029 case GAME_MODE_SCORES:
1030 HandleHallOfFame(0,0, dx,dy, !newbutton);
1033 case GAME_MODE_EDITOR:
1034 HandleLevelEditorIdle();
1037 case GAME_MODE_PLAYING:
1038 if (tape.playing || keyboard)
1039 newbutton = ((joy & JOY_BUTTON) != 0);
1041 if (AllPlayersGone && newbutton)
1043 CloseDoor(DOOR_CLOSE_1);
1044 game_status = GAME_MODE_MAIN;