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)
319 printf("::: BUTTON EVENT: button %d %s\n", event->button,
320 event->type == EVENT_BUTTONPRESS ? "pressed" : "released");
323 motion_status = FALSE;
325 if (event->type == EVENT_BUTTONPRESS)
326 button_status = event->button;
328 button_status = MB_RELEASED;
330 HandleButton(event->x, event->y, button_status, event->button);
333 void HandleMotionEvent(MotionEvent *event)
335 if (!PointerInWindow(window))
336 return; /* window and pointer are on different screens */
338 if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR)
341 motion_status = TRUE;
343 HandleButton(event->x, event->y, button_status, button_status);
346 void HandleKeyEvent(KeyEvent *event)
348 int key_status = (event->type==EVENT_KEYPRESS ? KEY_PRESSED : KEY_RELEASED);
349 boolean with_modifiers = (game_status == GAME_MODE_PLAYING ? FALSE : TRUE);
350 Key key = GetEventKey(event, with_modifiers);
351 Key keymod = (with_modifiers ? GetEventKey(event, FALSE) : key);
354 printf("::: KEY EVENT: %d %s\n", GetEventKey(event, TRUE),
355 event->type == EVENT_KEYPRESS ? "pressed" : "released");
358 HandleKeyModState(keymod, key_status);
359 HandleKey(key, key_status);
362 void HandleFocusEvent(FocusChangeEvent *event)
364 static int old_joystick_status = -1;
366 if (event->type == EVENT_FOCUSOUT)
368 KeyboardAutoRepeatOn();
369 old_joystick_status = joystick.status;
370 joystick.status = JOYSTICK_NOT_AVAILABLE;
374 else if (event->type == EVENT_FOCUSIN)
376 /* When there are two Rocks'n'Diamonds windows which overlap and
377 the player moves the pointer from one game window to the other,
378 a 'FocusOut' event is generated for the window the pointer is
379 leaving and a 'FocusIn' event is generated for the window the
380 pointer is entering. In some cases, it can happen that the
381 'FocusIn' event is handled by the one game process before the
382 'FocusOut' event by the other game process. In this case the
383 X11 environment would end up with activated keyboard auto repeat,
384 because unfortunately this is a global setting and not (which
385 would be far better) set for each X11 window individually.
386 The effect would be keyboard auto repeat while playing the game
387 (game_status == GAME_MODE_PLAYING), which is not desired.
388 To avoid this special case, we just wait 1/10 second before
389 processing the 'FocusIn' event.
392 if (game_status == GAME_MODE_PLAYING)
395 KeyboardAutoRepeatOffUnlessAutoplay();
398 if (old_joystick_status != -1)
399 joystick.status = old_joystick_status;
403 void HandleClientMessageEvent(ClientMessageEvent *event)
405 if (CheckCloseWindowEvent(event))
409 void HandleButton(int mx, int my, int button, int button_nr)
411 static int old_mx = 0, old_my = 0;
425 if (HandleGadgets(mx, my, button))
427 /* do not handle this button event anymore */
428 mx = my = -32; /* force mouse event to be outside screen tiles */
431 /* do not use scroll wheel button events for anything other than gadgets */
432 if (IS_WHEEL_BUTTON(button_nr))
437 case GAME_MODE_TITLE:
438 HandleTitleScreen(mx, my, 0, 0, button);
442 HandleMainMenu(mx, my, 0, 0, button);
445 case GAME_MODE_PSEUDO_TYPENAME:
446 HandleTypeName(0, KSYM_Return);
449 case GAME_MODE_LEVELS:
450 HandleChooseLevel(mx, my, 0, 0, button);
453 case GAME_MODE_SCORES:
454 HandleHallOfFame(0, 0, 0, 0, button);
457 case GAME_MODE_EDITOR:
458 HandleLevelEditorIdle();
462 HandleInfoScreen(mx, my, 0, 0, button);
465 case GAME_MODE_SETUP:
466 HandleSetupScreen(mx, my, 0, 0, button);
469 case GAME_MODE_PLAYING:
471 if (button == MB_PRESSED && !motion_status && IN_GFX_SCREEN(mx, my))
472 DumpTile(LEVELX((mx - SX) / TILEX), LEVELY((my - SY) / TILEY));
481 static boolean is_string_suffix(char *string, char *suffix)
483 int string_len = strlen(string);
484 int suffix_len = strlen(suffix);
486 if (suffix_len > string_len)
489 return (strEqual(&string[string_len - suffix_len], suffix));
492 #define MAX_CHEAT_INPUT_LEN 32
494 static void HandleKeysSpecial(Key key)
496 static char cheat_input[2 * MAX_CHEAT_INPUT_LEN + 1] = "";
497 char letter = getCharFromKey(key);
498 int cheat_input_len = strlen(cheat_input);
504 if (cheat_input_len >= 2 * MAX_CHEAT_INPUT_LEN)
506 for (i = 0; i < MAX_CHEAT_INPUT_LEN + 1; i++)
507 cheat_input[i] = cheat_input[MAX_CHEAT_INPUT_LEN + i];
509 cheat_input_len = MAX_CHEAT_INPUT_LEN;
512 cheat_input[cheat_input_len++] = letter;
513 cheat_input[cheat_input_len] = '\0';
516 printf("::: '%s' [%d]\n", cheat_input, cheat_input_len);
519 if (game_status == GAME_MODE_MAIN)
521 if (is_string_suffix(cheat_input, ":insert-solution-tape") ||
522 is_string_suffix(cheat_input, ":ist"))
524 InsertSolutionTape();
526 else if (is_string_suffix(cheat_input, ":reload-graphics") ||
527 is_string_suffix(cheat_input, ":rg"))
529 ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS);
532 else if (is_string_suffix(cheat_input, ":reload-sounds") ||
533 is_string_suffix(cheat_input, ":rs"))
535 ReloadCustomArtwork(1 << ARTWORK_TYPE_SOUNDS);
538 else if (is_string_suffix(cheat_input, ":reload-music") ||
539 is_string_suffix(cheat_input, ":rm"))
541 ReloadCustomArtwork(1 << ARTWORK_TYPE_MUSIC);
544 else if (is_string_suffix(cheat_input, ":reload-artwork") ||
545 is_string_suffix(cheat_input, ":ra"))
547 ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS |
548 1 << ARTWORK_TYPE_SOUNDS |
549 1 << ARTWORK_TYPE_MUSIC);
552 else if (is_string_suffix(cheat_input, ":dump-level") ||
553 is_string_suffix(cheat_input, ":dl"))
557 else if (is_string_suffix(cheat_input, ":dump-tape") ||
558 is_string_suffix(cheat_input, ":dt"))
563 else if (game_status == GAME_MODE_PLAYING)
566 if (is_string_suffix(cheat_input, ".q"))
567 DEBUG_SetMaximumDynamite();
570 else if (game_status == GAME_MODE_EDITOR)
572 if (is_string_suffix(cheat_input, ":dump-brush") ||
573 is_string_suffix(cheat_input, ":DB"))
577 else if (is_string_suffix(cheat_input, ":DDB"))
584 void HandleKey(Key key, int key_status)
586 boolean anyTextGadgetActiveOrJustFinished = anyTextGadgetActive();
587 static struct SetupKeyboardInfo custom_key;
595 { &custom_key.left, DEFAULT_KEY_LEFT, JOY_LEFT },
596 { &custom_key.right, DEFAULT_KEY_RIGHT, JOY_RIGHT },
597 { &custom_key.up, DEFAULT_KEY_UP, JOY_UP },
598 { &custom_key.down, DEFAULT_KEY_DOWN, JOY_DOWN },
599 { &custom_key.snap, DEFAULT_KEY_SNAP, JOY_BUTTON_1 },
600 { &custom_key.drop, DEFAULT_KEY_DROP, JOY_BUTTON_2 }
605 if (game_status == GAME_MODE_PLAYING)
607 /* only needed for single-step tape recording mode */
608 static boolean clear_button_2[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
609 static boolean element_dropped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
612 for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
616 if (setup.input[pnr].use_joystick)
619 custom_key = setup.input[pnr].key;
621 for (i = 0; i < 6; i++)
622 if (key == *key_info[i].key_custom)
623 key_action |= key_info[i].action;
625 if (tape.single_step && clear_button_2[pnr])
627 stored_player[pnr].action &= ~KEY_BUTTON_2;
628 clear_button_2[pnr] = FALSE;
631 if (key_status == KEY_PRESSED)
632 stored_player[pnr].action |= key_action;
634 stored_player[pnr].action &= ~key_action;
636 if (tape.single_step && tape.recording && tape.pausing)
638 if (key_status == KEY_PRESSED &&
639 (key_action & (KEY_MOTION | KEY_BUTTON_1)))
641 TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
643 if (key_action & KEY_MOTION)
645 if (stored_player[pnr].action & KEY_BUTTON_2)
646 element_dropped[pnr] = TRUE;
649 else if (key_status == KEY_RELEASED &&
650 (key_action & KEY_BUTTON_2))
652 if (!element_dropped[pnr])
654 TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
656 stored_player[pnr].action |= KEY_BUTTON_2;
657 clear_button_2[pnr] = TRUE;
660 element_dropped[pnr] = FALSE;
663 else if (tape.recording && tape.pausing && (key_action & KEY_ACTION))
664 TapeTogglePause(TAPE_TOGGLE_MANUAL);
669 for (i = 0; i < 6; i++)
670 if (key == key_info[i].key_default)
671 joy |= key_info[i].action;
676 if (key_status == KEY_PRESSED)
677 key_joystick_mapping |= joy;
679 key_joystick_mapping &= ~joy;
684 if (game_status != GAME_MODE_PLAYING)
685 key_joystick_mapping = 0;
687 if (key_status == KEY_RELEASED)
690 if (key == KSYM_Return && GetKeyModState() & KMOD_Alt &&
691 video.fullscreen_available)
693 setup.fullscreen = !setup.fullscreen;
695 ToggleFullscreenIfNeeded();
700 if (game_status == GAME_MODE_PLAYING && AllPlayersGone &&
701 (key == KSYM_Return || key == setup.shortcut.toggle_pause))
703 CloseDoor(DOOR_CLOSE_1);
704 game_status = GAME_MODE_MAIN;
710 if (game_status == GAME_MODE_MAIN &&
711 (key == setup.shortcut.toggle_pause || key == KSYM_space))
713 StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE);
718 if (game_status == GAME_MODE_MAIN || game_status == GAME_MODE_PLAYING)
720 if (key == setup.shortcut.save_game)
722 else if (key == setup.shortcut.load_game)
724 else if (key == setup.shortcut.toggle_pause)
725 TapeTogglePause(TAPE_TOGGLE_MANUAL);
728 if (game_status == GAME_MODE_PLAYING && !network_playing)
730 int centered_player_nr_next = -999;
732 if (key == setup.shortcut.focus_player_all)
733 centered_player_nr_next = -1;
735 for (i = 0; i < MAX_PLAYERS; i++)
736 if (key == setup.shortcut.focus_player[i])
737 centered_player_nr_next = i;
739 if (centered_player_nr_next != -999)
741 game.centered_player_nr_next = centered_player_nr_next;
742 game.set_centered_player = TRUE;
746 tape.centered_player_nr_next = game.centered_player_nr_next;
747 tape.set_centered_player = TRUE;
752 HandleKeysSpecial(key);
754 if (HandleGadgetsKeyInput(key))
756 if (key != KSYM_Escape) /* always allow ESC key to be handled */
757 key = KSYM_UNDEFINED;
762 case GAME_MODE_PSEUDO_TYPENAME:
763 HandleTypeName(0, key);
766 case GAME_MODE_TITLE:
768 case GAME_MODE_LEVELS:
769 case GAME_MODE_SETUP:
776 /* !!! only use "space" key to start game from main menu !!! */
780 if (game_status == GAME_MODE_TITLE)
781 HandleTitleScreen(0,0, 0,0, MB_MENU_CHOICE);
782 else if (game_status == GAME_MODE_MAIN)
783 HandleMainMenu(0,0, 0,0, MB_MENU_CHOICE);
784 else if (game_status == GAME_MODE_LEVELS)
785 HandleChooseLevel(0,0, 0,0, MB_MENU_CHOICE);
786 else if (game_status == GAME_MODE_SETUP)
787 HandleSetupScreen(0,0, 0,0, MB_MENU_CHOICE);
788 else if (game_status == GAME_MODE_INFO)
789 HandleInfoScreen(0,0, 0,0, MB_MENU_CHOICE);
793 if (game_status == GAME_MODE_TITLE)
794 HandleTitleScreen(0,0, 0,0, MB_MENU_LEAVE);
795 else if (game_status == GAME_MODE_LEVELS)
796 HandleChooseLevel(0,0, 0,0, MB_MENU_LEAVE);
797 else if (game_status == GAME_MODE_SETUP)
798 HandleSetupScreen(0,0, 0,0, MB_MENU_LEAVE);
799 else if (game_status == GAME_MODE_INFO)
800 HandleInfoScreen(0,0, 0,0, MB_MENU_LEAVE);
804 if (game_status == GAME_MODE_LEVELS)
805 HandleChooseLevel(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
806 else if (game_status == GAME_MODE_SETUP)
807 HandleSetupScreen(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
808 else if (game_status == GAME_MODE_INFO)
809 HandleInfoScreen(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
813 if (game_status == GAME_MODE_LEVELS)
814 HandleChooseLevel(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
815 else if (game_status == GAME_MODE_SETUP)
816 HandleSetupScreen(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
817 else if (game_status == GAME_MODE_INFO)
818 HandleInfoScreen(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
823 GameFrameDelay = (GameFrameDelay == 500 ? GAME_FRAME_DELAY : 500);
832 case GAME_MODE_SCORES:
838 game_status = GAME_MODE_MAIN;
843 HandleHallOfFame(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
847 HandleHallOfFame(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
855 case GAME_MODE_EDITOR:
856 if (!anyTextGadgetActiveOrJustFinished || key == KSYM_Escape)
857 HandleLevelEditorKeyInput(key);
860 case GAME_MODE_PLAYING:
865 RequestQuitGame(setup.ask_on_escape);
883 if (GameFrameDelay == 500)
884 GameFrameDelay = GAME_FRAME_DELAY;
886 GameFrameDelay = 500;
889 GameFrameDelay = (key - KSYM_0) * 10;
890 printf("Game speed == %d%% (%d ms delay between two frames)\n",
891 GAME_FRAME_DELAY * 100 / GameFrameDelay, GameFrameDelay);
897 options.debug = FALSE;
898 printf("debug mode disabled\n");
902 options.debug = TRUE;
903 printf("debug mode enabled\n");
908 if (!global.fps_slowdown)
910 global.fps_slowdown = TRUE;
911 global.fps_slowdown_factor = 2;
912 printf("fps slowdown enabled -- display only every 2nd frame\n");
914 else if (global.fps_slowdown_factor == 2)
916 global.fps_slowdown_factor = 4;
917 printf("fps slowdown enabled -- display only every 4th frame\n");
921 global.fps_slowdown = FALSE;
922 global.fps_slowdown_factor = 1;
923 printf("fps slowdown disabled\n");
928 ScrollStepSize = TILEX/8;
929 printf("ScrollStepSize == %d (1/8)\n", ScrollStepSize);
933 ScrollStepSize = TILEX/4;
934 printf("ScrollStepSize == %d (1/4)\n", ScrollStepSize);
938 ScrollStepSize = TILEX/2;
939 printf("ScrollStepSize == %d (1/2)\n", ScrollStepSize);
943 ScrollStepSize = TILEX;
944 printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
948 printf("::: currently using game engine version %d\n",
949 game.engine_version);
960 if (key == KSYM_Escape)
962 game_status = GAME_MODE_MAIN;
972 if (button_status && game_status != GAME_MODE_PLAYING)
974 HandleButton(0, 0, -button_status, button_status);
979 #if defined(NETWORK_AVALIABLE)
987 static int HandleJoystickForAllPlayers()
992 for (i = 0; i < MAX_PLAYERS; i++)
997 if (!setup.input[i].use_joystick)
1001 joy_action = Joystick(i);
1002 result |= joy_action;
1004 if (!setup.input[i].use_joystick)
1007 stored_player[i].action = joy_action;
1013 void HandleJoystick()
1015 int joystick = HandleJoystickForAllPlayers();
1016 int keyboard = key_joystick_mapping;
1017 int joy = (joystick | keyboard);
1018 int left = joy & JOY_LEFT;
1019 int right = joy & JOY_RIGHT;
1020 int up = joy & JOY_UP;
1021 int down = joy & JOY_DOWN;
1022 int button = joy & JOY_BUTTON;
1023 int newbutton = (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED);
1024 int dx = (left ? -1 : right ? 1 : 0);
1025 int dy = (up ? -1 : down ? 1 : 0);
1029 case GAME_MODE_TITLE:
1030 case GAME_MODE_MAIN:
1031 case GAME_MODE_LEVELS:
1032 case GAME_MODE_SETUP:
1033 case GAME_MODE_INFO:
1035 static unsigned long joystickmove_delay = 0;
1037 if (joystick && !button &&
1038 !DelayReached(&joystickmove_delay, GADGET_FRAME_DELAY))
1039 newbutton = dx = dy = 0;
1041 if (game_status == GAME_MODE_TITLE)
1042 HandleTitleScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1043 else if (game_status == GAME_MODE_MAIN)
1044 HandleMainMenu(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1045 else if (game_status == GAME_MODE_LEVELS)
1046 HandleChooseLevel(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1047 else if (game_status == GAME_MODE_SETUP)
1048 HandleSetupScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1049 else if (game_status == GAME_MODE_INFO)
1050 HandleInfoScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1054 case GAME_MODE_SCORES:
1055 HandleHallOfFame(0,0, dx,dy, !newbutton);
1058 case GAME_MODE_EDITOR:
1059 HandleLevelEditorIdle();
1062 case GAME_MODE_PLAYING:
1063 if (tape.playing || keyboard)
1064 newbutton = ((joy & JOY_BUTTON) != 0);
1066 if (AllPlayersGone && newbutton)
1068 CloseDoor(DOOR_CLOSE_1);
1069 game_status = GAME_MODE_MAIN;