X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fevents.c;h=65b20da1cb634a22e5a6cc1e4c8ce39fdd8a1e9e;hp=18898fb2c8e1401c1a97d76580b6ddfc1a849914;hb=c9308ba3e7ddea2d7e44b4d98f0dfbb19e18f04f;hpb=bad67e8c9c6b1ba51f001b2a3f79e059e3e2e786 diff --git a/src/events.c b/src/events.c index 18898fb2..65b20da1 100644 --- a/src/events.c +++ b/src/events.c @@ -39,6 +39,12 @@ static int cursor_mode_last = CURSOR_DEFAULT; static unsigned int special_cursor_delay = 0; static unsigned int special_cursor_delay_value = 1000; + +/* forward declarations for internal use */ +static void HandleNoEvent(void); +static void HandleEventActions(void); + + /* event filter especially needed for SDL event filtering due to delay problems with lots of mouse motion events when mouse button not pressed (X11 can handle this with 'PointerMotionHintMask') */ @@ -318,10 +324,10 @@ void EventLoop(void) if (PendingEvent()) HandleEvents(); else - HandleMouseCursor(); + HandleNoEvent(); - /* also execute after pending events have been processed before */ - HandleNoEvent(); + /* execute event related actions after pending events have been processed */ + HandleEventActions(); /* don't use all CPU time when idle; the main loop while playing has its own synchronization and is CPU friendly, too */ @@ -476,6 +482,9 @@ void HandleButtonEvent(ButtonEvent *event) event->x, event->y); #endif + // for any mouse button event, disable playfield tile cursor + SetTileCursorEnabled(FALSE); + #if defined(HAS_SCREEN_KEYBOARD) if (video.shifted_up) event->y += video.shifted_up_pos; @@ -640,185 +649,162 @@ static struct Key key; } touch_info[NUM_TOUCH_FINGERS]; -void HandleFingerEvent(FingerEvent *event) +void HandleFingerEvent_VirtualButtons(FingerEvent *event) { - static Key motion_key_x = KSYM_UNDEFINED; - static Key motion_key_y = KSYM_UNDEFINED; - static Key button_key = KSYM_UNDEFINED; - static float motion_x1, motion_y1; - static float button_x1, button_y1; - static SDL_FingerID motion_id = -1; - static SDL_FingerID button_id = -1; - int move_trigger_distance_percent = setup.touch.move_distance; - int drop_trigger_distance_percent = setup.touch.drop_distance; - float move_trigger_distance = (float)move_trigger_distance_percent / 100; - float drop_trigger_distance = (float)drop_trigger_distance_percent / 100; - float event_x = event->x; - float event_y = event->y; - -#if DEBUG_EVENTS_FINGER - Error(ERR_DEBUG, "FINGER EVENT: finger was %s, touch ID %lld, finger ID %lld, x/y %f/%f, dx/dy %f/%f, pressure %f", - event->type == EVENT_FINGERPRESS ? "pressed" : - event->type == EVENT_FINGERRELEASE ? "released" : "moved", - event->touchId, - event->fingerId, - event->x, event->y, - event->dx, event->dy, - event->pressure); -#endif + float ypos = 1.0 - 1.0 / 3.0 * video.display_width / video.display_height; + float event_x = (event->x); + float event_y = (event->y - ypos) / (1 - ypos); + Key key = (event_x > 0 && event_x < 1.0 / 6.0 && + event_y > 2.0 / 3.0 && event_y < 1 ? + setup.input[0].key.snap : + event_x > 1.0 / 6.0 && event_x < 1.0 / 3.0 && + event_y > 2.0 / 3.0 && event_y < 1 ? + setup.input[0].key.drop : + event_x > 7.0 / 9.0 && event_x < 8.0 / 9.0 && + event_y > 0 && event_y < 1.0 / 3.0 ? + setup.input[0].key.up : + event_x > 6.0 / 9.0 && event_x < 7.0 / 9.0 && + event_y > 1.0 / 3.0 && event_y < 2.0 / 3.0 ? + setup.input[0].key.left : + event_x > 8.0 / 9.0 && event_x < 1 && + event_y > 1.0 / 3.0 && event_y < 2.0 / 3.0 ? + setup.input[0].key.right : + event_x > 7.0 / 9.0 && event_x < 8.0 / 9.0 && + event_y > 2.0 / 3.0 && event_y < 1 ? + setup.input[0].key.down : + KSYM_UNDEFINED); + int key_status = (event->type == EVENT_FINGERRELEASE ? KEY_RELEASED : + KEY_PRESSED); + char *key_status_name = (key_status == KEY_RELEASED ? "KEY_RELEASED" : + "KEY_PRESSED"); + int i; - if (game_status != GAME_MODE_PLAYING) - return; + // for any touch input event, enable overlay buttons (if activated) + SetOverlayEnabled(TRUE); - if (strEqual(setup.touch.control_type, TOUCH_CONTROL_FOLLOW_FINGER)) - return; + Error(ERR_DEBUG, "::: key '%s' was '%s' [fingerId: %lld]", + getKeyNameFromKey(key), key_status_name, event->fingerId); - if (strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS)) + // check if we already know this touch event's finger id + for (i = 0; i < NUM_TOUCH_FINGERS; i++) { - int key_status = (event->type == EVENT_FINGERRELEASE ? KEY_RELEASED : - KEY_PRESSED); - float ypos = 1.0 - 1.0 / 3.0 * video.display_width / video.display_height; - - event_y = (event_y - ypos) / (1 - ypos); - - Key key = (event_x > 0 && event_x < 1.0 / 6.0 && - event_y > 2.0 / 3.0 && event_y < 1 ? - setup.input[0].key.snap : - event_x > 1.0 / 6.0 && event_x < 1.0 / 3.0 && - event_y > 2.0 / 3.0 && event_y < 1 ? - setup.input[0].key.drop : - event_x > 7.0 / 9.0 && event_x < 8.0 / 9.0 && - event_y > 0 && event_y < 1.0 / 3.0 ? - setup.input[0].key.up : - event_x > 6.0 / 9.0 && event_x < 7.0 / 9.0 && - event_y > 1.0 / 3.0 && event_y < 2.0 / 3.0 ? - setup.input[0].key.left : - event_x > 8.0 / 9.0 && event_x < 1 && - event_y > 1.0 / 3.0 && event_y < 2.0 / 3.0 ? - setup.input[0].key.right : - event_x > 7.0 / 9.0 && event_x < 8.0 / 9.0 && - event_y > 2.0 / 3.0 && event_y < 1 ? - setup.input[0].key.down : - KSYM_UNDEFINED); - - char *key_status_name = (key_status == KEY_RELEASED ? "KEY_RELEASED" : - "KEY_PRESSED"); - int i; - - // for any touch input event, enable overlay buttons (if activated) - SetOverlayEnabled(TRUE); - - Error(ERR_DEBUG, "::: key '%s' was '%s' [fingerId: %lld]", - getKeyNameFromKey(key), key_status_name, event->fingerId); - - // check if we already know this touch event's finger id - for (i = 0; i < NUM_TOUCH_FINGERS; i++) + if (touch_info[i].touched && + touch_info[i].finger_id == event->fingerId) { - if (touch_info[i].touched && - touch_info[i].finger_id == event->fingerId) - { - // Error(ERR_DEBUG, "MARK 1: %d", i); + // Error(ERR_DEBUG, "MARK 1: %d", i); - break; - } + break; } + } - if (i >= NUM_TOUCH_FINGERS) + if (i >= NUM_TOUCH_FINGERS) + { + if (key_status == KEY_PRESSED) { - if (key_status == KEY_PRESSED) - { - int oldest_pos = 0, oldest_counter = touch_info[0].counter; + int oldest_pos = 0, oldest_counter = touch_info[0].counter; - // unknown finger id -- get new, empty slot, if available - for (i = 0; i < NUM_TOUCH_FINGERS; i++) + // unknown finger id -- get new, empty slot, if available + for (i = 0; i < NUM_TOUCH_FINGERS; i++) + { + if (touch_info[i].counter < oldest_counter) { - if (touch_info[i].counter < oldest_counter) - { - oldest_pos = i; - oldest_counter = touch_info[i].counter; + oldest_pos = i; + oldest_counter = touch_info[i].counter; - // Error(ERR_DEBUG, "MARK 2: %d", i); - } - - if (!touch_info[i].touched) - { - // Error(ERR_DEBUG, "MARK 3: %d", i); - - break; - } + // Error(ERR_DEBUG, "MARK 2: %d", i); } - if (i >= NUM_TOUCH_FINGERS) + if (!touch_info[i].touched) { - // all slots allocated -- use oldest slot - i = oldest_pos; + // Error(ERR_DEBUG, "MARK 3: %d", i); - // Error(ERR_DEBUG, "MARK 4: %d", i); + break; } } - else - { - // release of previously unknown key (should not happen) - if (key != KSYM_UNDEFINED) - { - HandleKey(key, KEY_RELEASED); + if (i >= NUM_TOUCH_FINGERS) + { + // all slots allocated -- use oldest slot + i = oldest_pos; - Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [1]", - getKeyNameFromKey(key), "KEY_RELEASED", i); - } + // Error(ERR_DEBUG, "MARK 4: %d", i); } } - - if (i < NUM_TOUCH_FINGERS) + else { - if (key_status == KEY_PRESSED) - { - if (touch_info[i].key != key) - { - if (touch_info[i].key != KSYM_UNDEFINED) - { - HandleKey(touch_info[i].key, KEY_RELEASED); - - Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [2]", - getKeyNameFromKey(touch_info[i].key), "KEY_RELEASED", i); - } - - if (key != KSYM_UNDEFINED) - { - HandleKey(key, KEY_PRESSED); + // release of previously unknown key (should not happen) - Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [3]", - getKeyNameFromKey(key), "KEY_PRESSED", i); - } - } + if (key != KSYM_UNDEFINED) + { + HandleKey(key, KEY_RELEASED); - touch_info[i].touched = TRUE; - touch_info[i].finger_id = event->fingerId; - touch_info[i].counter = Counter(); - touch_info[i].key = key; + Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [1]", + getKeyNameFromKey(key), "KEY_RELEASED", i); } - else + } + } + + if (i < NUM_TOUCH_FINGERS) + { + if (key_status == KEY_PRESSED) + { + if (touch_info[i].key != key) { if (touch_info[i].key != KSYM_UNDEFINED) { HandleKey(touch_info[i].key, KEY_RELEASED); - Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [4]", + Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [2]", getKeyNameFromKey(touch_info[i].key), "KEY_RELEASED", i); } - touch_info[i].touched = FALSE; - touch_info[i].finger_id = 0; - touch_info[i].counter = 0; - touch_info[i].key = 0; + if (key != KSYM_UNDEFINED) + { + HandleKey(key, KEY_PRESSED); + + Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [3]", + getKeyNameFromKey(key), "KEY_PRESSED", i); + } } + + touch_info[i].touched = TRUE; + touch_info[i].finger_id = event->fingerId; + touch_info[i].counter = Counter(); + touch_info[i].key = key; } + else + { + if (touch_info[i].key != KSYM_UNDEFINED) + { + HandleKey(touch_info[i].key, KEY_RELEASED); - return; + Error(ERR_DEBUG, "=> key == '%s', key_status == '%s' [slot %d] [4]", + getKeyNameFromKey(touch_info[i].key), "KEY_RELEASED", i); + } + + touch_info[i].touched = FALSE; + touch_info[i].finger_id = 0; + touch_info[i].counter = 0; + touch_info[i].key = 0; + } } +} - // use touch direction control +void HandleFingerEvent_WipeGestures(FingerEvent *event) +{ + static Key motion_key_x = KSYM_UNDEFINED; + static Key motion_key_y = KSYM_UNDEFINED; + static Key button_key = KSYM_UNDEFINED; + static float motion_x1, motion_y1; + static float button_x1, button_y1; + static SDL_FingerID motion_id = -1; + static SDL_FingerID button_id = -1; + int move_trigger_distance_percent = setup.touch.move_distance; + int drop_trigger_distance_percent = setup.touch.drop_distance; + float move_trigger_distance = (float)move_trigger_distance_percent / 100; + float drop_trigger_distance = (float)drop_trigger_distance_percent / 100; + float event_x = event->x; + float event_y = event->y; if (event->type == EVENT_FINGERPRESS) { @@ -953,24 +939,224 @@ void HandleFingerEvent(FingerEvent *event) } } -static void HandleFollowFinger(int mx, int my, int button) +void HandleFingerEvent(FingerEvent *event) +{ +#if DEBUG_EVENTS_FINGER + Error(ERR_DEBUG, "FINGER EVENT: finger was %s, touch ID %lld, finger ID %lld, x/y %f/%f, dx/dy %f/%f, pressure %f", + event->type == EVENT_FINGERPRESS ? "pressed" : + event->type == EVENT_FINGERRELEASE ? "released" : "moved", + event->touchId, + event->fingerId, + event->x, event->y, + event->dx, event->dy, + event->pressure); +#endif + + if (game_status != GAME_MODE_PLAYING) + return; + + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + return; + + if (strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS)) + HandleFingerEvent_VirtualButtons(event); + else if (strEqual(setup.touch.control_type, TOUCH_CONTROL_WIPE_GESTURES)) + HandleFingerEvent_WipeGestures(event); +} + +#endif + +static void HandleButtonOrFinger_WipeGestures_MM(int mx, int my, int button) +{ + static int old_mx = 0, old_my = 0; + static int last_button = MB_LEFTBUTTON; + static boolean touched = FALSE; + static boolean tapped = FALSE; + + // screen tile was tapped (but finger not touching the screen anymore) + // (this point will also be reached without receiving a touch event) + if (tapped && !touched) + { + SetPlayerMouseAction(old_mx, old_my, MB_RELEASED); + + tapped = FALSE; + } + + // stop here if this function was not triggered by a touch event + if (button == -1) + return; + + if (button == MB_PRESSED && IN_GFX_FIELD_PLAY(mx, my)) + { + // finger started touching the screen + + touched = TRUE; + tapped = TRUE; + + if (!motion_status) + { + old_mx = mx; + old_my = my; + + ClearPlayerMouseAction(); + + Error(ERR_DEBUG, "---------- TOUCH ACTION STARTED ----------"); + } + } + else if (button == MB_RELEASED && touched) + { + // finger stopped touching the screen + + touched = FALSE; + + if (tapped) + SetPlayerMouseAction(old_mx, old_my, last_button); + else + SetPlayerMouseAction(old_mx, old_my, MB_RELEASED); + + Error(ERR_DEBUG, "---------- TOUCH ACTION STOPPED ----------"); + } + + if (touched) + { + // finger moved while touching the screen + + int old_x = getLevelFromScreenX(old_mx); + int old_y = getLevelFromScreenY(old_my); + int new_x = getLevelFromScreenX(mx); + int new_y = getLevelFromScreenY(my); + + if (new_x != old_x || new_y != old_y) + tapped = FALSE; + + if (new_x != old_x) + { + // finger moved left or right from (horizontal) starting position + + int button_nr = (new_x < old_x ? MB_LEFTBUTTON : MB_RIGHTBUTTON); + + SetPlayerMouseAction(old_mx, old_my, button_nr); + + last_button = button_nr; + + Error(ERR_DEBUG, "---------- TOUCH ACTION: ROTATING ----------"); + } + else + { + // finger stays at or returned to (horizontal) starting position + + SetPlayerMouseAction(old_mx, old_my, MB_RELEASED); + + Error(ERR_DEBUG, "---------- TOUCH ACTION PAUSED ----------"); + } + } +} + +static void HandleButtonOrFinger_FollowFinger_MM(int mx, int my, int button) +{ + static int old_mx = 0, old_my = 0; + static int last_button = MB_LEFTBUTTON; + static boolean touched = FALSE; + static boolean tapped = FALSE; + + // screen tile was tapped (but finger not touching the screen anymore) + // (this point will also be reached without receiving a touch event) + if (tapped && !touched) + { + SetPlayerMouseAction(old_mx, old_my, MB_RELEASED); + + tapped = FALSE; + } + + // stop here if this function was not triggered by a touch event + if (button == -1) + return; + + if (button == MB_PRESSED && IN_GFX_FIELD_PLAY(mx, my)) + { + // finger started touching the screen + + touched = TRUE; + tapped = TRUE; + + if (!motion_status) + { + old_mx = mx; + old_my = my; + + ClearPlayerMouseAction(); + + Error(ERR_DEBUG, "---------- TOUCH ACTION STARTED ----------"); + } + } + else if (button == MB_RELEASED && touched) + { + // finger stopped touching the screen + + touched = FALSE; + + if (tapped) + SetPlayerMouseAction(old_mx, old_my, last_button); + else + SetPlayerMouseAction(old_mx, old_my, MB_RELEASED); + + Error(ERR_DEBUG, "---------- TOUCH ACTION STOPPED ----------"); + } + + if (touched) + { + // finger moved while touching the screen + + int old_x = getLevelFromScreenX(old_mx); + int old_y = getLevelFromScreenY(old_my); + int new_x = getLevelFromScreenX(mx); + int new_y = getLevelFromScreenY(my); + + if (new_x != old_x || new_y != old_y) + { + // finger moved away from starting position + + int button_nr = getButtonFromTouchPosition(old_x, old_y, mx, my); + + // quickly alternate between clicking and releasing for maximum speed + if (FrameCounter % 2 == 0) + button_nr = MB_RELEASED; + + SetPlayerMouseAction(old_mx, old_my, button_nr); + + if (button_nr) + last_button = button_nr; + + tapped = FALSE; + + Error(ERR_DEBUG, "---------- TOUCH ACTION: ROTATING ----------"); + } + else + { + // finger stays at or returned to starting position + + SetPlayerMouseAction(old_mx, old_my, MB_RELEASED); + + Error(ERR_DEBUG, "---------- TOUCH ACTION PAUSED ----------"); + } + } +} + +static void HandleButtonOrFinger_FollowFinger(int mx, int my, int button) { static int old_mx = 0, old_my = 0; static Key motion_key_x = KSYM_UNDEFINED; static Key motion_key_y = KSYM_UNDEFINED; + static boolean touched = FALSE; static boolean started_on_player = FALSE; static boolean player_is_dropping = FALSE; static int player_drop_count = 0; static int last_player_x = -1; static int last_player_y = -1; - if (!strEqual(setup.touch.control_type, TOUCH_CONTROL_FOLLOW_FINGER)) - return; - if (button == MB_PRESSED && IN_GFX_FIELD_PLAY(mx, my)) { - touch_info[0].touched = TRUE; - touch_info[0].key = 0; + touched = TRUE; old_mx = mx; old_my = my; @@ -989,10 +1175,9 @@ static void HandleFollowFinger(int mx, int my, int button) Error(ERR_DEBUG, "---------- TOUCH ACTION STARTED ----------"); } } - else if (button == MB_RELEASED && touch_info[0].touched) + else if (button == MB_RELEASED && touched) { - touch_info[0].touched = FALSE; - touch_info[0].key = 0; + touched = FALSE; old_mx = 0; old_my = 0; @@ -1024,7 +1209,7 @@ static void HandleFollowFinger(int mx, int my, int button) Error(ERR_DEBUG, "---------- TOUCH ACTION STOPPED ----------"); } - if (touch_info[0].touched) + if (touched) { int src_x = local_player->jx; int src_y = local_player->jy; @@ -1119,6 +1304,27 @@ static void HandleFollowFinger(int mx, int my, int button) } } +static void HandleButtonOrFinger(int mx, int my, int button) +{ + if (game_status != GAME_MODE_PLAYING) + return; + + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + { + if (strEqual(setup.touch.control_type, TOUCH_CONTROL_WIPE_GESTURES)) + HandleButtonOrFinger_WipeGestures_MM(mx, my, button); + else if (strEqual(setup.touch.control_type, TOUCH_CONTROL_FOLLOW_FINGER)) + HandleButtonOrFinger_FollowFinger_MM(mx, my, button); + } + else + { + if (strEqual(setup.touch.control_type, TOUCH_CONTROL_FOLLOW_FINGER)) + HandleButtonOrFinger_FollowFinger(mx, my, button); + } +} + +#if defined(TARGET_SDL2) + static boolean checkTextInputKeyModState() { // when playing, only handle raw key events and ignore text input @@ -1269,6 +1475,7 @@ void HandleButton(int mx, int my, int button, int button_nr) { static int old_mx = 0, old_my = 0; boolean button_hold = FALSE; + boolean handle_gadgets = TRUE; if (button_nr < 0) { @@ -1285,23 +1492,18 @@ void HandleButton(int mx, int my, int button, int button_nr) #if defined(PLATFORM_ANDROID) // when playing, only handle gadgets when using "follow finger" controls - boolean handle_gadgets = + // or when using touch controls in combination with the MM game engine + handle_gadgets = (game_status != GAME_MODE_PLAYING || + level.game_engine_type == GAME_ENGINE_TYPE_MM || strEqual(setup.touch.control_type, TOUCH_CONTROL_FOLLOW_FINGER)); +#endif - if (handle_gadgets && - HandleGadgets(mx, my, button)) + if (handle_gadgets && HandleGadgets(mx, my, button)) { /* do not handle this button event anymore */ mx = my = -32; /* force mouse event to be outside screen tiles */ } -#else - if (HandleGadgets(mx, my, button)) - { - /* do not handle this button event anymore */ - mx = my = -32; /* force mouse event to be outside screen tiles */ - } -#endif if (HandleGlobalAnimClicks(mx, my, button)) { @@ -1355,11 +1557,10 @@ void HandleButton(int mx, int my, int button, int button_nr) break; case GAME_MODE_PLAYING: - SetPlayerMouseAction(mx, my, button); - -#if defined(TARGET_SDL2) - HandleFollowFinger(mx, my, button); -#endif + if (!strEqual(setup.touch.control_type, TOUCH_CONTROL_OFF)) + HandleButtonOrFinger(mx, my, button); + else + SetPlayerMouseAction(mx, my, button); #ifdef DEBUG if (button == MB_PRESSED && !motion_status && !button_hold && @@ -1660,6 +1861,10 @@ void HandleKey(Key key, int key_status) if (key_status == KEY_PRESSED && key_action & KEY_ACTION) TapeTogglePause(TAPE_TOGGLE_MANUAL); } + + // for MM style levels, handle in-game keyboard input in HandleJoystick() + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + joy |= key_action; } } else @@ -1923,6 +2128,18 @@ void HandleKey(Key key, int key_status) } void HandleNoEvent() +{ + HandleMouseCursor(); + + switch (game_status) + { + case GAME_MODE_PLAYING: + HandleButtonOrFinger(-1, -1, -1); + break; + } +} + +void HandleEventActions() { // if (button_status && game_status != GAME_MODE_PLAYING) if (button_status && (game_status != GAME_MODE_PLAYING || @@ -1951,17 +2168,42 @@ void HandleNoEvent() HandleLevelEditorIdle(); break; -#if defined(TARGET_SDL2) - case GAME_MODE_PLAYING: - HandleFollowFinger(-1, -1, -1); - break; -#endif - default: break; } } +static void HandleTileCursor(int dx, int dy, int button) +{ + if (!dx || !button) + ClearPlayerMouseAction(); + + if (!dx && !dy) + return; + + if (button) + { + SetPlayerMouseAction(tile_cursor.x, tile_cursor.y, + (dx < 0 ? MB_LEFTBUTTON : + dx > 0 ? MB_RIGHTBUTTON : MB_RELEASED)); + } + else + { + int old_xpos = tile_cursor.xpos; + int old_ypos = tile_cursor.ypos; + int new_xpos = old_xpos; + int new_ypos = old_ypos; + + if (IN_LEV_FIELD(old_xpos + dx, old_ypos)) + new_xpos = old_xpos + dx; + + if (IN_LEV_FIELD(old_xpos, old_ypos + dy)) + new_ypos = old_ypos + dy; + + SetTileCursorTargetXY(new_xpos, new_ypos); + } +} + static int HandleJoystickForAllPlayers() { int i; @@ -1997,9 +2239,13 @@ static int HandleJoystickForAllPlayers() void HandleJoystick() { + static unsigned int joytest_delay = 0; + static unsigned int joytest_delay_value = GADGET_FRAME_DELAY; + static int joytest_last = 0; int joystick = HandleJoystickForAllPlayers(); int keyboard = key_joystick_mapping; int joy = (joystick | keyboard); + int joytest = joystick; int left = joy & JOY_LEFT; int right = joy & JOY_RIGHT; int up = joy & JOY_UP; @@ -2015,6 +2261,31 @@ void HandleJoystick() return; } + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + { + // when playing MM style levels, also use delay for keyboard events + if (game_status == GAME_MODE_PLAYING) + joytest |= keyboard; + + // for any joystick or keyboard event, enable playfield tile cursor + if (dx || dy || button) + SetTileCursorEnabled(TRUE); + } + + if (joytest && !button && !DelayReached(&joytest_delay, joytest_delay_value)) + { + /* delay joystick/keyboard actions if axes/keys continually pressed */ + newbutton = dx = dy = 0; + } + else + { + /* first start with longer delay, then continue with shorter delay */ + joytest_delay_value = + (joytest != joytest_last ? GADGET_FRAME_DELAY_FIRST : GADGET_FRAME_DELAY); + } + + joytest_last = joytest; + switch (game_status) { case GAME_MODE_TITLE: @@ -2023,26 +2294,8 @@ void HandleJoystick() case GAME_MODE_LEVELNR: case GAME_MODE_SETUP: case GAME_MODE_INFO: + case GAME_MODE_SCORES: { - static unsigned int joystickmove_delay = 0; - static unsigned int joystickmove_delay_value = GADGET_FRAME_DELAY; - static int joystick_last = 0; - - if (joystick && !button && - !DelayReached(&joystickmove_delay, joystickmove_delay_value)) - { - /* delay joystick actions if buttons/axes continually pressed */ - newbutton = dx = dy = 0; - } - else - { - /* start with longer delay, then continue with shorter delay */ - if (joystick != joystick_last) - joystickmove_delay_value = GADGET_FRAME_DELAY_FIRST; - else - joystickmove_delay_value = GADGET_FRAME_DELAY; - } - if (game_status == GAME_MODE_TITLE) HandleTitleScreen(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); else if (game_status == GAME_MODE_MAIN) @@ -2055,16 +2308,12 @@ void HandleJoystick() HandleSetupScreen(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); else if (game_status == GAME_MODE_INFO) HandleInfoScreen(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); - - joystick_last = joystick; + else if (game_status == GAME_MODE_SCORES) + HandleHallOfFame(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); break; } - case GAME_MODE_SCORES: - HandleHallOfFame(0, 0, dx, dy, !newbutton); - break; - case GAME_MODE_PLAYING: if (tape.playing || keyboard) newbutton = ((joy & JOY_BUTTON) != 0); @@ -2082,6 +2331,9 @@ void HandleJoystick() TapeTogglePause(TAPE_TOGGLE_MANUAL); } + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + HandleTileCursor(dx, dy, button); + break; default: