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:
ClearPlayerAction();
break;
+#if defined(TARGET_SDL2)
+ case SDL_CONTROLLERBUTTONUP:
+ HandleJoystickEvent(&event);
+ ClearPlayerAction();
+ break;
+#endif
+
default:
HandleOtherEvents(&event);
break;
key_joystick_mapping = 0;
for (i = 0; i < MAX_PLAYERS; i++)
stored_player[i].action = 0;
+
+ ClearJoystickState();
}
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;
"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);
#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);
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++)
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
{
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)
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))
{
{
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;
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:
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);
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;
}
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
+}