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;
if (new_window_width != video.window_width ||
new_window_height != video.window_height)
{
- int new_xpercent = (100 * new_window_width / video.screen_width);
- int new_ypercent = (100 * new_window_height / video.screen_height);
+ int new_xpercent = 100.0 * new_window_width / video.screen_width + .5;
+ int new_ypercent = 100.0 * new_window_height / video.screen_height + .5;
// (extreme window scaling allowed, but cannot be saved permanently)
video.window_scaling_percent = MIN(new_xpercent, new_ypercent);
"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);
}
#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;
(mod_key_pressed == setup.debug.frame_delay_use_mod_key))
{
GameFrameDelay = (GameFrameDelay != setup.debug.frame_delay[i] ?
- setup.debug.frame_delay[i] : GAME_FRAME_DELAY);
+ setup.debug.frame_delay[i] : setup.game_frame_delay);
if (!setup.debug.frame_delay_game_only)
MenuFrameDelay = GameFrameDelay;
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 element_dropped[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
int pnr;
+ /* initialize unifying snap and drop buttons (EM engine) */
+ game_em.use_single_button = game_em.use_single_button_initial;
+
for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
{
byte key_action = 0;
if (tape.single_step && tape.recording && tape.pausing)
{
+ /* do not unify snap and drop buttons in single-step mode (EM engine) */
+ game_em.use_single_button = FALSE;
+
if (key_status == KEY_PRESSED && key_action & KEY_MOTION)
{
TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
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
+}