1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-2006 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include "libgame/libgame.h"
27 #define DEBUG_EVENTS 0
30 static boolean cursor_inside_playfield = FALSE;
31 static boolean playfield_cursor_set = FALSE;
32 static unsigned long playfield_cursor_delay = 0;
35 /* event filter especially needed for SDL event filtering due to
36 delay problems with lots of mouse motion events when mouse button
37 not pressed (X11 can handle this with 'PointerMotionHintMask') */
39 int FilterMouseMotionEvents(const Event *event)
43 /* non-motion events are directly passed to event handler functions */
44 if (event->type != EVENT_MOTIONNOTIFY)
47 motion = (MotionEvent *)event;
48 cursor_inside_playfield = (motion->x >= SX && motion->x < SX + SXSIZE &&
49 motion->y >= SY && motion->y < SY + SYSIZE);
51 if (game_status == GAME_MODE_PLAYING && playfield_cursor_set)
53 SetMouseCursor(CURSOR_DEFAULT);
54 playfield_cursor_set = FALSE;
55 DelayReached(&playfield_cursor_delay, 0);
58 /* skip mouse motion events without pressed button outside level editor */
59 if (button_status == MB_RELEASED &&
60 game_status != GAME_MODE_EDITOR && game_status != GAME_MODE_PLAYING)
66 /* to prevent delay problems, skip mouse motion events if the very next
67 event is also a mouse motion event (and therefore effectively only
68 handling the last of a row of mouse motion events in the event queue) */
70 boolean SkipPressedMouseMotionEvent(const Event *event)
72 /* nothing to do if the current event is not a mouse motion event */
73 if (event->type != EVENT_MOTIONNOTIFY)
76 /* only skip motion events with pressed button outside level editor */
77 if (button_status == MB_RELEASED ||
78 game_status == GAME_MODE_EDITOR || game_status == GAME_MODE_PLAYING)
85 PeekEvent(&next_event);
87 /* if next event is also a mouse motion event, skip the current one */
88 if (next_event.type == EVENT_MOTIONNOTIFY)
95 /* this is only really needed for non-SDL targets to filter unwanted events;
96 when using SDL with properly installed event filter, this function can be
97 replaced with a simple "NextEvent()" call, but it doesn't hurt either */
99 static boolean NextValidEvent(Event *event)
101 while (PendingEvent())
103 boolean handle_this_event = FALSE;
107 if (FilterMouseMotionEvents(event))
108 handle_this_event = TRUE;
110 if (SkipPressedMouseMotionEvent(event))
111 handle_this_event = FALSE;
113 if (handle_this_event)
124 if (PendingEvent()) /* got event */
128 while (NextValidEvent(&event))
132 case EVENT_BUTTONPRESS:
133 case EVENT_BUTTONRELEASE:
134 HandleButtonEvent((ButtonEvent *) &event);
137 case EVENT_MOTIONNOTIFY:
138 HandleMotionEvent((MotionEvent *) &event);
142 case EVENT_KEYRELEASE:
143 HandleKeyEvent((KeyEvent *) &event);
147 HandleOtherEvents(&event);
154 /* when playing, display a special mouse pointer inside the playfield */
155 if (game_status == GAME_MODE_PLAYING && !tape.pausing)
157 if (!playfield_cursor_set && cursor_inside_playfield &&
158 DelayReached(&playfield_cursor_delay, 1000))
160 SetMouseCursor(CURSOR_PLAYFIELD);
161 playfield_cursor_set = TRUE;
164 else if (playfield_cursor_set)
166 SetMouseCursor(CURSOR_DEFAULT);
167 playfield_cursor_set = FALSE;
173 /* don't use all CPU time when idle; the main loop while playing
174 has its own synchronization and is CPU friendly, too */
176 if (game_status == GAME_MODE_PLAYING)
183 if (!PendingEvent()) /* delay only if no pending events */
187 /* refresh window contents from drawing buffer, if needed */
190 if (game_status == GAME_MODE_QUIT)
195 void HandleOtherEvents(Event *event)
200 HandleExposeEvent((ExposeEvent *) event);
203 case EVENT_UNMAPNOTIFY:
205 /* This causes the game to stop not only when iconified, but also
206 when on another virtual desktop, which might be not desired. */
207 SleepWhileUnmapped();
213 HandleFocusEvent((FocusChangeEvent *) event);
216 case EVENT_CLIENTMESSAGE:
217 HandleClientMessageEvent((ClientMessageEvent *) event);
220 #if defined(TARGET_SDL)
221 case SDL_JOYAXISMOTION:
222 case SDL_JOYBUTTONDOWN:
223 case SDL_JOYBUTTONUP:
224 HandleJoystickEvent(event);
233 void ClearEventQueue()
235 while (PendingEvent())
243 case EVENT_BUTTONRELEASE:
244 button_status = MB_RELEASED;
247 case EVENT_KEYRELEASE:
251 key_joystick_mapping = 0;
256 HandleOtherEvents(&event);
262 void ClearPlayerAction()
266 /* simulate key release events for still pressed keys */
267 key_joystick_mapping = 0;
268 for (i = 0; i < MAX_PLAYERS; i++)
269 stored_player[i].action = 0;
272 void SleepWhileUnmapped()
274 boolean window_unmapped = TRUE;
276 KeyboardAutoRepeatOn();
278 while (window_unmapped)
286 case EVENT_BUTTONRELEASE:
287 button_status = MB_RELEASED;
290 case EVENT_KEYRELEASE:
291 key_joystick_mapping = 0;
294 case EVENT_MAPNOTIFY:
295 window_unmapped = FALSE;
298 case EVENT_UNMAPNOTIFY:
299 /* this is only to surely prevent the 'should not happen' case
300 * of recursively looping between 'SleepWhileUnmapped()' and
301 * 'HandleOtherEvents()' which usually calls this funtion.
306 HandleOtherEvents(&event);
311 if (game_status == GAME_MODE_PLAYING)
312 KeyboardAutoRepeatOffUnlessAutoplay();
315 void HandleExposeEvent(ExposeEvent *event)
318 RedrawPlayfield(FALSE, event->x, event->y, event->width, event->height);
323 void HandleButtonEvent(ButtonEvent *event)
326 printf("::: BUTTON EVENT: button %d %s\n", event->button,
327 event->type == EVENT_BUTTONPRESS ? "pressed" : "released");
330 motion_status = FALSE;
332 if (event->type == EVENT_BUTTONPRESS)
333 button_status = event->button;
335 button_status = MB_RELEASED;
337 HandleButton(event->x, event->y, button_status, event->button);
340 void HandleMotionEvent(MotionEvent *event)
342 if (!PointerInWindow(window))
343 return; /* window and pointer are on different screens */
345 if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR)
348 motion_status = TRUE;
350 HandleButton(event->x, event->y, button_status, button_status);
353 void HandleKeyEvent(KeyEvent *event)
355 int key_status = (event->type==EVENT_KEYPRESS ? KEY_PRESSED : KEY_RELEASED);
356 boolean with_modifiers = (game_status == GAME_MODE_PLAYING ? FALSE : TRUE);
357 Key key = GetEventKey(event, with_modifiers);
358 Key keymod = (with_modifiers ? GetEventKey(event, FALSE) : key);
361 printf("::: KEY EVENT: %d %s\n", GetEventKey(event, TRUE),
362 event->type == EVENT_KEYPRESS ? "pressed" : "released");
365 HandleKeyModState(keymod, key_status);
366 HandleKey(key, key_status);
369 void HandleFocusEvent(FocusChangeEvent *event)
371 static int old_joystick_status = -1;
373 if (event->type == EVENT_FOCUSOUT)
375 KeyboardAutoRepeatOn();
376 old_joystick_status = joystick.status;
377 joystick.status = JOYSTICK_NOT_AVAILABLE;
381 else if (event->type == EVENT_FOCUSIN)
383 /* When there are two Rocks'n'Diamonds windows which overlap and
384 the player moves the pointer from one game window to the other,
385 a 'FocusOut' event is generated for the window the pointer is
386 leaving and a 'FocusIn' event is generated for the window the
387 pointer is entering. In some cases, it can happen that the
388 'FocusIn' event is handled by the one game process before the
389 'FocusOut' event by the other game process. In this case the
390 X11 environment would end up with activated keyboard auto repeat,
391 because unfortunately this is a global setting and not (which
392 would be far better) set for each X11 window individually.
393 The effect would be keyboard auto repeat while playing the game
394 (game_status == GAME_MODE_PLAYING), which is not desired.
395 To avoid this special case, we just wait 1/10 second before
396 processing the 'FocusIn' event.
399 if (game_status == GAME_MODE_PLAYING)
402 KeyboardAutoRepeatOffUnlessAutoplay();
405 if (old_joystick_status != -1)
406 joystick.status = old_joystick_status;
410 void HandleClientMessageEvent(ClientMessageEvent *event)
412 if (CheckCloseWindowEvent(event))
416 void HandleButton(int mx, int my, int button, int button_nr)
418 static int old_mx = 0, old_my = 0;
432 if (HandleGadgets(mx, my, button))
434 /* do not handle this button event anymore */
435 mx = my = -32; /* force mouse event to be outside screen tiles */
438 /* do not use scroll wheel button events for anything other than gadgets */
439 if (IS_WHEEL_BUTTON(button_nr))
444 case GAME_MODE_TITLE:
445 HandleTitleScreen(mx, my, 0, 0, button);
449 HandleMainMenu(mx, my, 0, 0, button);
452 case GAME_MODE_PSEUDO_TYPENAME:
453 HandleTypeName(0, KSYM_Return);
456 case GAME_MODE_LEVELS:
457 HandleChooseLevel(mx, my, 0, 0, button);
460 case GAME_MODE_SCORES:
461 HandleHallOfFame(0, 0, 0, 0, button);
464 case GAME_MODE_EDITOR:
465 HandleLevelEditorIdle();
469 HandleInfoScreen(mx, my, 0, 0, button);
472 case GAME_MODE_SETUP:
473 HandleSetupScreen(mx, my, 0, 0, button);
476 case GAME_MODE_PLAYING:
478 if (button == MB_PRESSED && !motion_status && IN_GFX_SCREEN(mx, my))
479 DumpTile(LEVELX((mx - SX) / TILEX), LEVELY((my - SY) / TILEY));
488 static boolean is_string_suffix(char *string, char *suffix)
490 int string_len = strlen(string);
491 int suffix_len = strlen(suffix);
493 if (suffix_len > string_len)
496 return (strEqual(&string[string_len - suffix_len], suffix));
499 #define MAX_CHEAT_INPUT_LEN 32
501 static void HandleKeysSpecial(Key key)
503 static char cheat_input[2 * MAX_CHEAT_INPUT_LEN + 1] = "";
504 char letter = getCharFromKey(key);
505 int cheat_input_len = strlen(cheat_input);
511 if (cheat_input_len >= 2 * MAX_CHEAT_INPUT_LEN)
513 for (i = 0; i < MAX_CHEAT_INPUT_LEN + 1; i++)
514 cheat_input[i] = cheat_input[MAX_CHEAT_INPUT_LEN + i];
516 cheat_input_len = MAX_CHEAT_INPUT_LEN;
519 cheat_input[cheat_input_len++] = letter;
520 cheat_input[cheat_input_len] = '\0';
523 printf("::: '%s' [%d]\n", cheat_input, cheat_input_len);
526 if (game_status == GAME_MODE_MAIN)
528 if (is_string_suffix(cheat_input, ":insert-solution-tape") ||
529 is_string_suffix(cheat_input, ":ist"))
531 InsertSolutionTape();
533 else if (is_string_suffix(cheat_input, ":reload-graphics") ||
534 is_string_suffix(cheat_input, ":rg"))
536 ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS);
539 else if (is_string_suffix(cheat_input, ":reload-sounds") ||
540 is_string_suffix(cheat_input, ":rs"))
542 ReloadCustomArtwork(1 << ARTWORK_TYPE_SOUNDS);
545 else if (is_string_suffix(cheat_input, ":reload-music") ||
546 is_string_suffix(cheat_input, ":rm"))
548 ReloadCustomArtwork(1 << ARTWORK_TYPE_MUSIC);
551 else if (is_string_suffix(cheat_input, ":reload-artwork") ||
552 is_string_suffix(cheat_input, ":ra"))
554 ReloadCustomArtwork(1 << ARTWORK_TYPE_GRAPHICS |
555 1 << ARTWORK_TYPE_SOUNDS |
556 1 << ARTWORK_TYPE_MUSIC);
559 else if (is_string_suffix(cheat_input, ":dump-level") ||
560 is_string_suffix(cheat_input, ":dl"))
564 else if (is_string_suffix(cheat_input, ":dump-tape") ||
565 is_string_suffix(cheat_input, ":dt"))
570 else if (game_status == GAME_MODE_PLAYING)
573 if (is_string_suffix(cheat_input, ".q"))
574 DEBUG_SetMaximumDynamite();
577 else if (game_status == GAME_MODE_EDITOR)
579 if (is_string_suffix(cheat_input, ":dump-brush") ||
580 is_string_suffix(cheat_input, ":DB"))
584 else if (is_string_suffix(cheat_input, ":DDB"))
591 void HandleKey(Key key, int key_status)
593 boolean anyTextGadgetActiveOrJustFinished = anyTextGadgetActive();
594 static struct SetupKeyboardInfo custom_key;
602 { &custom_key.left, DEFAULT_KEY_LEFT, JOY_LEFT },
603 { &custom_key.right, DEFAULT_KEY_RIGHT, JOY_RIGHT },
604 { &custom_key.up, DEFAULT_KEY_UP, JOY_UP },
605 { &custom_key.down, DEFAULT_KEY_DOWN, JOY_DOWN },
606 { &custom_key.snap, DEFAULT_KEY_SNAP, JOY_BUTTON_1 },
607 { &custom_key.drop, DEFAULT_KEY_DROP, JOY_BUTTON_2 }
612 if (game_status == GAME_MODE_PLAYING)
614 /* only needed for single-step tape recording mode */
615 static boolean clear_button_2[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
616 static boolean element_dropped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
619 for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
623 if (setup.input[pnr].use_joystick)
626 custom_key = setup.input[pnr].key;
628 for (i = 0; i < 6; i++)
629 if (key == *key_info[i].key_custom)
630 key_action |= key_info[i].action;
632 if (tape.single_step && clear_button_2[pnr])
634 stored_player[pnr].action &= ~KEY_BUTTON_2;
635 clear_button_2[pnr] = FALSE;
638 if (key_status == KEY_PRESSED)
639 stored_player[pnr].action |= key_action;
641 stored_player[pnr].action &= ~key_action;
643 if (tape.single_step && tape.recording && tape.pausing)
645 if (key_status == KEY_PRESSED &&
646 (key_action & (KEY_MOTION | KEY_BUTTON_1)))
648 TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
650 if (key_action & KEY_MOTION)
652 if (stored_player[pnr].action & KEY_BUTTON_2)
653 element_dropped[pnr] = TRUE;
656 else if (key_status == KEY_RELEASED &&
657 (key_action & KEY_BUTTON_2))
659 if (!element_dropped[pnr])
661 TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
663 stored_player[pnr].action |= KEY_BUTTON_2;
664 clear_button_2[pnr] = TRUE;
667 element_dropped[pnr] = FALSE;
670 else if (tape.recording && tape.pausing && (key_action & KEY_ACTION))
671 TapeTogglePause(TAPE_TOGGLE_MANUAL);
676 for (i = 0; i < 6; i++)
677 if (key == key_info[i].key_default)
678 joy |= key_info[i].action;
683 if (key_status == KEY_PRESSED)
684 key_joystick_mapping |= joy;
686 key_joystick_mapping &= ~joy;
691 if (game_status != GAME_MODE_PLAYING)
692 key_joystick_mapping = 0;
694 if (key_status == KEY_RELEASED)
697 if ((key == KSYM_Return || key == KSYM_KP_Enter) &&
698 (GetKeyModState() & KMOD_Alt) && video.fullscreen_available)
700 setup.fullscreen = !setup.fullscreen;
702 ToggleFullscreenIfNeeded();
708 if (game_status == GAME_MODE_PLAYING &&
709 local_player->LevelSolved_GameEnd &&
710 (key == KSYM_Return || key == setup.shortcut.toggle_pause))
712 if (game_status == GAME_MODE_PLAYING && AllPlayersGone &&
713 (key == KSYM_Return || key == setup.shortcut.toggle_pause))
721 if (game_status == GAME_MODE_MAIN &&
722 (key == setup.shortcut.toggle_pause || key == KSYM_space))
724 StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE);
729 if (game_status == GAME_MODE_MAIN || game_status == GAME_MODE_PLAYING)
731 if (key == setup.shortcut.save_game)
733 else if (key == setup.shortcut.load_game)
735 else if (key == setup.shortcut.toggle_pause)
736 TapeTogglePause(TAPE_TOGGLE_MANUAL);
739 if (game_status == GAME_MODE_PLAYING && !network_playing)
741 int centered_player_nr_next = -999;
743 if (key == setup.shortcut.focus_player_all)
744 centered_player_nr_next = -1;
746 for (i = 0; i < MAX_PLAYERS; i++)
747 if (key == setup.shortcut.focus_player[i])
748 centered_player_nr_next = i;
750 if (centered_player_nr_next != -999)
752 game.centered_player_nr_next = centered_player_nr_next;
753 game.set_centered_player = TRUE;
757 tape.centered_player_nr_next = game.centered_player_nr_next;
758 tape.set_centered_player = TRUE;
763 HandleKeysSpecial(key);
765 if (HandleGadgetsKeyInput(key))
767 if (key != KSYM_Escape) /* always allow ESC key to be handled */
768 key = KSYM_UNDEFINED;
773 case GAME_MODE_PSEUDO_TYPENAME:
774 HandleTypeName(0, key);
777 case GAME_MODE_TITLE:
779 case GAME_MODE_LEVELS:
780 case GAME_MODE_SETUP:
782 case GAME_MODE_SCORES:
787 if (game_status == GAME_MODE_TITLE)
788 HandleTitleScreen(0, 0, 0, 0, MB_MENU_CHOICE);
789 else if (game_status == GAME_MODE_MAIN)
790 HandleMainMenu(0, 0, 0, 0, MB_MENU_CHOICE);
791 else if (game_status == GAME_MODE_LEVELS)
792 HandleChooseLevel(0, 0, 0, 0, MB_MENU_CHOICE);
793 else if (game_status == GAME_MODE_SETUP)
794 HandleSetupScreen(0, 0, 0, 0, MB_MENU_CHOICE);
795 else if (game_status == GAME_MODE_INFO)
796 HandleInfoScreen(0, 0, 0, 0, MB_MENU_CHOICE);
797 else if (game_status == GAME_MODE_SCORES)
798 HandleHallOfFame(0, 0, 0, 0, MB_MENU_CHOICE);
802 if (game_status == GAME_MODE_TITLE)
803 HandleTitleScreen(0, 0, 0, 0, MB_MENU_LEAVE);
804 else if (game_status == GAME_MODE_LEVELS)
805 HandleChooseLevel(0, 0, 0, 0, MB_MENU_LEAVE);
806 else if (game_status == GAME_MODE_SETUP)
807 HandleSetupScreen(0, 0, 0, 0, MB_MENU_LEAVE);
808 else if (game_status == GAME_MODE_INFO)
809 HandleInfoScreen(0, 0, 0, 0, MB_MENU_LEAVE);
810 else if (game_status == GAME_MODE_SCORES)
811 HandleHallOfFame(0, 0, 0, 0, MB_MENU_LEAVE);
815 if (game_status == GAME_MODE_LEVELS)
816 HandleChooseLevel(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
817 else if (game_status == GAME_MODE_SETUP)
818 HandleSetupScreen(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
819 else if (game_status == GAME_MODE_INFO)
820 HandleInfoScreen(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
821 else if (game_status == GAME_MODE_SCORES)
822 HandleHallOfFame(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
826 if (game_status == GAME_MODE_LEVELS)
827 HandleChooseLevel(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
828 else if (game_status == GAME_MODE_SETUP)
829 HandleSetupScreen(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
830 else if (game_status == GAME_MODE_INFO)
831 HandleInfoScreen(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
832 else if (game_status == GAME_MODE_SCORES)
833 HandleHallOfFame(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
838 GameFrameDelay = (GameFrameDelay == 500 ? GAME_FRAME_DELAY : 500);
847 case GAME_MODE_EDITOR:
848 if (!anyTextGadgetActiveOrJustFinished || key == KSYM_Escape)
849 HandleLevelEditorKeyInput(key);
852 case GAME_MODE_PLAYING:
857 RequestQuitGame(setup.ask_on_escape);
875 if (GameFrameDelay == 500)
876 GameFrameDelay = GAME_FRAME_DELAY;
878 GameFrameDelay = 500;
881 GameFrameDelay = (key - KSYM_0) * 10;
882 printf("Game speed == %d%% (%d ms delay between two frames)\n",
883 GAME_FRAME_DELAY * 100 / GameFrameDelay, GameFrameDelay);
889 options.debug = FALSE;
890 printf("debug mode disabled\n");
894 options.debug = TRUE;
895 printf("debug mode enabled\n");
900 if (!global.fps_slowdown)
902 global.fps_slowdown = TRUE;
903 global.fps_slowdown_factor = 2;
904 printf("fps slowdown enabled -- display only every 2nd frame\n");
906 else if (global.fps_slowdown_factor == 2)
908 global.fps_slowdown_factor = 4;
909 printf("fps slowdown enabled -- display only every 4th frame\n");
913 global.fps_slowdown = FALSE;
914 global.fps_slowdown_factor = 1;
915 printf("fps slowdown disabled\n");
920 ScrollStepSize = TILEX/8;
921 printf("ScrollStepSize == %d (1/8)\n", ScrollStepSize);
925 ScrollStepSize = TILEX/4;
926 printf("ScrollStepSize == %d (1/4)\n", ScrollStepSize);
930 ScrollStepSize = TILEX/2;
931 printf("ScrollStepSize == %d (1/2)\n", ScrollStepSize);
935 ScrollStepSize = TILEX;
936 printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
940 printf("::: currently using game engine version %d\n",
941 game.engine_version);
952 if (key == KSYM_Escape)
954 game_status = GAME_MODE_MAIN;
964 if (button_status && game_status != GAME_MODE_PLAYING)
966 HandleButton(0, 0, -button_status, button_status);
971 #if defined(NETWORK_AVALIABLE)
979 static int HandleJoystickForAllPlayers()
984 for (i = 0; i < MAX_PLAYERS; i++)
989 if (!setup.input[i].use_joystick)
993 joy_action = Joystick(i);
994 result |= joy_action;
996 if (!setup.input[i].use_joystick)
999 stored_player[i].action = joy_action;
1005 void HandleJoystick()
1007 int joystick = HandleJoystickForAllPlayers();
1008 int keyboard = key_joystick_mapping;
1009 int joy = (joystick | keyboard);
1010 int left = joy & JOY_LEFT;
1011 int right = joy & JOY_RIGHT;
1012 int up = joy & JOY_UP;
1013 int down = joy & JOY_DOWN;
1014 int button = joy & JOY_BUTTON;
1015 int newbutton = (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED);
1016 int dx = (left ? -1 : right ? 1 : 0);
1017 int dy = (up ? -1 : down ? 1 : 0);
1021 case GAME_MODE_TITLE:
1022 case GAME_MODE_MAIN:
1023 case GAME_MODE_LEVELS:
1024 case GAME_MODE_SETUP:
1025 case GAME_MODE_INFO:
1027 static unsigned long joystickmove_delay = 0;
1029 if (joystick && !button &&
1030 !DelayReached(&joystickmove_delay, GADGET_FRAME_DELAY))
1031 newbutton = dx = dy = 0;
1033 if (game_status == GAME_MODE_TITLE)
1034 HandleTitleScreen(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1035 else if (game_status == GAME_MODE_MAIN)
1036 HandleMainMenu(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1037 else if (game_status == GAME_MODE_LEVELS)
1038 HandleChooseLevel(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1039 else if (game_status == GAME_MODE_SETUP)
1040 HandleSetupScreen(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1041 else if (game_status == GAME_MODE_INFO)
1042 HandleInfoScreen(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
1046 case GAME_MODE_SCORES:
1047 HandleHallOfFame(0, 0, dx, dy, !newbutton);
1050 case GAME_MODE_EDITOR:
1051 HandleLevelEditorIdle();
1054 case GAME_MODE_PLAYING:
1055 if (tape.playing || keyboard)
1056 newbutton = ((joy & JOY_BUTTON) != 0);
1059 if (local_player->LevelSolved_GameEnd && newbutton)
1061 if (AllPlayersGone && newbutton)