X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fevents.c;h=5b1e5771c671ca48ae568bdd221dd8100799966f;hp=25d243b7b105f5beb368b203e7195ee97a1bc450;hb=47da774c66f9325f9d27cddb5a697514154e2de9;hpb=ad543757bee23838b7f1a58bd1eca6192a37af5e diff --git a/src/events.c b/src/events.c index 25d243b7..5b1e5771 100644 --- a/src/events.c +++ b/src/events.c @@ -247,6 +247,19 @@ void HandleOtherEvents(Event *event) break; #if defined(TARGET_SDL) +#if defined(TARGET_SDL2) + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + // for any game controller button event, disable overlay buttons + SetOverlayEnabled(FALSE); + + HandleSpecialGameControllerButtons(event); + + /* FALL THROUGH */ + case SDL_CONTROLLERDEVICEADDED: + case SDL_CONTROLLERDEVICEREMOVED: + case SDL_CONTROLLERAXISMOTION: +#endif case SDL_JOYAXISMOTION: case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: @@ -343,6 +356,13 @@ void ClearEventQueue() ClearPlayerAction(); break; +#if defined(TARGET_SDL2) + case SDL_CONTROLLERBUTTONUP: + HandleJoystickEvent(&event); + ClearPlayerAction(); + break; +#endif + default: HandleOtherEvents(&event); break; @@ -358,6 +378,8 @@ void ClearPlayerAction() key_joystick_mapping = 0; for (i = 0; i < MAX_PLAYERS; i++) stored_player[i].action = 0; + + ClearJoystickState(); } void SleepWhileUnmapped() @@ -382,6 +404,13 @@ void SleepWhileUnmapped() key_joystick_mapping = 0; break; +#if defined(TARGET_SDL2) + case SDL_CONTROLLERBUTTONUP: + HandleJoystickEvent(&event); + key_joystick_mapping = 0; + break; +#endif + case EVENT_MAPNOTIFY: window_unmapped = FALSE; break; @@ -645,6 +674,9 @@ void HandleFingerEvent(FingerEvent *event) "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); @@ -1125,9 +1157,16 @@ void HandleKeyEvent(KeyEvent *event) #endif #if defined(PLATFORM_ANDROID) - // always map the "back" button to the "escape" key on Android devices if (key == KSYM_Back) + { + // always map the "back" button to the "escape" key on Android devices key = KSYM_Escape; + } + else + { + // for any key event other than "back" button, disable overlay buttons + SetOverlayEnabled(FALSE); + } #endif HandleKeyModState(keymod, key_status); @@ -1233,6 +1272,12 @@ void HandleButton(int mx, int my, int button, int button_nr) } #endif + if (HandleGlobalAnimClicks(mx, my, button)) + { + /* do not handle this button event anymore */ + mx = my = -32; /* force mouse event to be outside screen tiles */ + } + if (button_hold && game_status == GAME_MODE_PLAYING && tape.pausing) return; @@ -1496,13 +1541,20 @@ void HandleKey(Key key, int key_status) int joy = 0; int i; +#if defined(TARGET_SDL2) + /* map special keys (media keys / remote control buttons) to default keys */ + if (key == KSYM_PlayPause) + key = KSYM_space; + else if (key == KSYM_Select) + key = KSYM_Return; +#endif + + HandleSpecialGameControllerKeys(key, key_status); + if (game_status == GAME_MODE_PLAYING) { /* only needed for single-step tape recording mode */ - static boolean clear_snap_button[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE }; - static boolean clear_drop_button[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE }; - static boolean element_snapped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE }; - static boolean element_dropped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE }; + static boolean has_snapped[MAX_PLAYERS] = { FALSE, FALSE, FALSE, FALSE }; int pnr; for (pnr = 0; pnr < MAX_PLAYERS; pnr++) @@ -1528,22 +1580,6 @@ void HandleKey(Key key, int key_status) key_action |= key_info[i].action | JOY_BUTTON_SNAP; } - /* clear delayed snap and drop actions in single step mode (see below) */ - if (tape.single_step) - { - if (clear_snap_button[pnr]) - { - stored_player[pnr].action &= ~KEY_BUTTON_SNAP; - clear_snap_button[pnr] = FALSE; - } - - if (clear_drop_button[pnr]) - { - stored_player[pnr].action &= ~KEY_BUTTON_DROP; - clear_drop_button[pnr] = FALSE; - } - } - if (key_status == KEY_PRESSED) stored_player[pnr].action |= key_action; else @@ -1555,63 +1591,29 @@ void HandleKey(Key key, int key_status) { TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - /* if snap key already pressed, don't snap when releasing (below) */ + /* if snap key already pressed, keep pause mode when releasing */ if (stored_player[pnr].action & KEY_BUTTON_SNAP) - element_snapped[pnr] = TRUE; - - /* if drop key already pressed, don't drop when releasing (below) */ - if (stored_player[pnr].action & KEY_BUTTON_DROP) - element_dropped[pnr] = TRUE; + has_snapped[pnr] = TRUE; } else if (key_status == KEY_PRESSED && key_action & KEY_BUTTON_DROP) { - if (level.game_engine_type == GAME_ENGINE_TYPE_EM || - level.game_engine_type == GAME_ENGINE_TYPE_SP) - { - - if (level.game_engine_type == GAME_ENGINE_TYPE_SP && - getRedDiskReleaseFlag_SP() == 0) - stored_player[pnr].action &= ~KEY_BUTTON_DROP; + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + if (level.game_engine_type == GAME_ENGINE_TYPE_SP && + getRedDiskReleaseFlag_SP() == 0) + { + /* add a single inactive frame before dropping starts */ + stored_player[pnr].action &= ~KEY_BUTTON_DROP; + stored_player[pnr].force_dropping = TRUE; } } - else if (key_status == KEY_RELEASED && key_action & KEY_BUTTON) + else if (key_status == KEY_RELEASED && key_action & KEY_BUTTON_SNAP) { - if (key_action & KEY_BUTTON_SNAP) - { - /* if snap key was released without moving (see above), snap now */ - if (!element_snapped[pnr]) - { - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - - stored_player[pnr].action |= KEY_BUTTON_SNAP; - - /* clear delayed snap button on next event */ - clear_snap_button[pnr] = TRUE; - } - - element_snapped[pnr] = FALSE; - } - - if (key_action & KEY_BUTTON_DROP && - level.game_engine_type == GAME_ENGINE_TYPE_RND) - { - /* if drop key was released without moving (see above), drop now */ - if (!element_dropped[pnr]) - { - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - - if (level.game_engine_type != GAME_ENGINE_TYPE_SP || - getRedDiskReleaseFlag_SP() != 0) - stored_player[pnr].action |= KEY_BUTTON_DROP; - - /* clear delayed drop button on next event */ - clear_drop_button[pnr] = TRUE; - } + /* if snap key was pressed without direction, leave pause mode */ + if (!has_snapped[pnr]) + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - element_dropped[pnr] = FALSE; - } + has_snapped[pnr] = FALSE; } } else if (tape.recording && tape.pausing) @@ -1697,6 +1699,15 @@ void HandleKey(Key key, int key_status) return; } + if (HandleGlobalAnimClicks(-1, -1, (key == KSYM_space || + key == KSYM_Return || + key == KSYM_Escape))) + { + /* do not handle this key event anymore */ + if (key != KSYM_Escape) /* always allow ESC key to be handled */ + return; + } + if (game_status == GAME_MODE_PLAYING && AllPlayersGone && (key == KSYM_Return || key == setup.shortcut.toggle_pause)) { @@ -1915,23 +1926,30 @@ static int HandleJoystickForAllPlayers() { int i; int result = 0; + boolean no_joysticks_configured = TRUE; + boolean use_as_joystick_nr = (game_status != GAME_MODE_PLAYING); + static byte joy_action_last[MAX_PLAYERS]; + + for (i = 0; i < MAX_PLAYERS; i++) + if (setup.input[i].use_joystick) + no_joysticks_configured = FALSE; + + /* if no joysticks configured, map connected joysticks to players */ + if (no_joysticks_configured) + use_as_joystick_nr = TRUE; for (i = 0; i < MAX_PLAYERS; i++) { byte joy_action = 0; - /* - if (!setup.input[i].use_joystick) - continue; - */ - - joy_action = Joystick(i); + joy_action = JoystickExt(i, use_as_joystick_nr); result |= joy_action; - if (!setup.input[i].use_joystick) - continue; + if ((setup.input[i].use_joystick || no_joysticks_configured) && + joy_action != joy_action_last[i]) + stored_player[i].action = joy_action; - stored_player[i].action = joy_action; + joy_action_last[i] = joy_action; } return result; @@ -1951,6 +1969,12 @@ void HandleJoystick() int dx = (left ? -1 : right ? 1 : 0); int dy = (up ? -1 : down ? 1 : 0); + if (HandleGlobalAnimClicks(-1, -1, newbutton)) + { + /* do not handle this button event anymore */ + return; + } + switch (game_status) { case GAME_MODE_TITLE: @@ -1961,10 +1985,23 @@ void HandleJoystick() case GAME_MODE_INFO: { 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, GADGET_FRAME_DELAY)) + !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); @@ -1978,6 +2015,9 @@ 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; + break; } @@ -1996,9 +2036,69 @@ void HandleJoystick() return; } + if (tape.recording && tape.pausing) + { + if (joystick & JOY_ACTION) + TapeTogglePause(TAPE_TOGGLE_MANUAL); + } + break; default: break; } } + +void HandleSpecialGameControllerButtons(Event *event) +{ +#if defined(TARGET_SDL2) + switch (event->type) + { + case SDL_CONTROLLERBUTTONDOWN: + if (event->cbutton.button == SDL_CONTROLLER_BUTTON_START) + HandleKey(KSYM_space, KEY_PRESSED); + else if (event->cbutton.button == SDL_CONTROLLER_BUTTON_BACK) + HandleKey(KSYM_Escape, KEY_PRESSED); + + break; + + case SDL_CONTROLLERBUTTONUP: + if (event->cbutton.button == SDL_CONTROLLER_BUTTON_START) + HandleKey(KSYM_space, KEY_RELEASED); + else if (event->cbutton.button == SDL_CONTROLLER_BUTTON_BACK) + HandleKey(KSYM_Escape, KEY_RELEASED); + + break; + } +#endif +} + +void HandleSpecialGameControllerKeys(Key key, int key_status) +{ +#if defined(TARGET_SDL2) +#if defined(KSYM_Rewind) && defined(KSYM_FastForward) + int button = SDL_CONTROLLER_BUTTON_INVALID; + + /* map keys to joystick buttons (special hack for Amazon Fire TV remote) */ + if (key == KSYM_Rewind) + button = SDL_CONTROLLER_BUTTON_A; + else if (key == KSYM_FastForward || key == KSYM_Menu) + button = SDL_CONTROLLER_BUTTON_B; + + if (button != SDL_CONTROLLER_BUTTON_INVALID) + { + Event event; + + event.type = (key_status == KEY_PRESSED ? SDL_CONTROLLERBUTTONDOWN : + SDL_CONTROLLERBUTTONUP); + + event.cbutton.which = 0; /* first joystick (Amazon Fire TV remote) */ + event.cbutton.button = button; + event.cbutton.state = (key_status == KEY_PRESSED ? SDL_PRESSED : + SDL_RELEASED); + + HandleJoystickEvent(&event); + } +#endif +#endif +}