Replaced SDL_HINT_APPLE_TV_REMOTE_SWIPES_AS_ARROW_KEYS with SDL_HINT_TV_REMOTE_AS_JOYSTICK which controls whether remotes on iOS and Android are interpreted as joysticks (the default) or as return/escape/arrow keys.

This commit is contained in:
Sam Lantinga 2018-02-06 15:03:38 -08:00
parent 6ed184ec69
commit f59b9c8b13
4 changed files with 89 additions and 52 deletions

View file

@ -355,16 +355,6 @@ extern "C" {
*/
#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"
/**
* \brief A variable controlling whether the Apple TV remote swipes are
* translated into arrow key events
*
* This variable can be set to the following values:
* "0" - Swipes are not translated into arrow key events
* "1" - Swipes are translated into arrow key events (the default)
*/
#define SDL_HINT_APPLE_TV_REMOTE_SWIPES_AS_ARROW_KEYS "SDL_APPLE_TV_REMOTE_SWIPES_AS_ARROW_KEYS"
/**
* \brief A variable controlling whether the home indicator bar on iPhone X
* should be hidden.
@ -378,15 +368,24 @@ extern "C" {
/**
* \brief A variable controlling whether the Android / iOS built-in
* accelerometer should be listed as a joystick device, rather than listing
* actual joysticks only.
* accelerometer should be listed as a joystick device.
*
* This variable can be set to the following values:
* "0" - List only real joysticks and accept input from them
* "1" - List real joysticks along with the accelerometer as if it were a 3 axis joystick (the default).
* "0" - The accelerometer is not listed as a joystick
* "1" - The accelerometer is available as a 3 axis joystick (the default).
*/
#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK"
/**
* \brief A variable controlling whether the Android / iOS remotes
* should be listed as joystick devices, instead of sending keyboard events.
*
* This variable can be set to the following values:
* "0" - Remotes send enter/escape/arrow key events
* "1" - Remotes are available as 2 axis, 2 button joysticks (the default).
*/
#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK"
/**
* \brief A variable that lets you disable the detection and use of Xinput gamepad devices
*

View file

@ -80,8 +80,7 @@ keycode_to_SDL(int keycode)
{
/* FIXME: If this function gets too unwieldy in the future, replace with a lookup table */
int button = 0;
switch(keycode)
{
switch (keycode) {
/* Some gamepad buttons (API 9) */
case AKEYCODE_BUTTON_A:
button = SDL_CONTROLLER_BUTTON_A;
@ -179,7 +178,30 @@ keycode_to_SDL(int keycode)
*/
SDL_assert(button < ANDROID_MAX_NBUTTONS);
return button;
}
static SDL_Scancode
button_to_scancode(int button)
{
switch (button) {
case SDL_CONTROLLER_BUTTON_A:
return SDL_SCANCODE_RETURN;
case SDL_CONTROLLER_BUTTON_B:
return SDL_SCANCODE_ESCAPE;
case SDL_CONTROLLER_BUTTON_BACK:
return SDL_SCANCODE_ESCAPE;
case SDL_CONTROLLER_BUTTON_DPAD_UP:
return SDL_SCANCODE_UP;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
return SDL_SCANCODE_DOWN;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
return SDL_SCANCODE_LEFT;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
return SDL_SCANCODE_RIGHT;
}
/* Unsupported button */
return SDL_SCANCODE_UNKNOWN;
}
int
@ -191,6 +213,8 @@ Android_OnPadDown(int device_id, int keycode)
item = JoystickByDeviceId(device_id);
if (item && item->joystick) {
SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED);
} else {
SDL_SendKeyboardKey(SDL_PRESSED, button_to_scancode(button));
}
return 0;
}
@ -207,6 +231,8 @@ Android_OnPadUp(int device_id, int keycode)
item = JoystickByDeviceId(device_id);
if (item && item->joystick) {
SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED);
} else {
SDL_SendKeyboardKey(SDL_RELEASED, button_to_scancode(button));
}
return 0;
}
@ -252,8 +278,15 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, SDL_bool
{
SDL_JoystickGUID guid;
SDL_joylist_item *item;
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
/* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
if (naxes < 2 && nhats < 1) {
return -1;
}
}
if(JoystickByDeviceId(device_id) != NULL || name == NULL) {
if (JoystickByDeviceId(device_id) != NULL || name == NULL) {
return -1;
}

View file

@ -150,6 +150,15 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
{
SDL_JoystickDeviceItem *device = deviceList;
#if TARGET_OS_TV
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
/* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
if (controller && !controller.extendedGamepad && !controller.gamepad && controller.microGamepad) {
return;
}
}
#endif
while (device != NULL) {
if (device->controller == controller) {
return;
@ -157,13 +166,11 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
device = device->next;
}
device = (SDL_JoystickDeviceItem *) SDL_malloc(sizeof(SDL_JoystickDeviceItem));
device = (SDL_JoystickDeviceItem *) SDL_calloc(1, sizeof(SDL_JoystickDeviceItem));
if (device == NULL) {
return;
}
SDL_zerop(device);
device->accelerometer = accelerometer;
device->instance_id = instancecounter++;
@ -277,11 +284,11 @@ static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickG
}
*device_instance = device->instance_id = instancecounter++;
device->name = SDL_strdup(name);
device->guid = guid;
SDL_GetSteamControllerInputs(&device->nbuttons,
&device->naxes,
&device->nhats);
device->name = SDL_strdup(name);
device->guid = guid;
SDL_GetSteamControllerInputs(&device->nbuttons,
&device->naxes,
&device->nhats);
device->m_bSteamController = SDL_TRUE;
if (deviceList == NULL) {
@ -305,10 +312,10 @@ static void SteamControllerDisconnectedCallback(int device_instance)
{
SDL_JoystickDeviceItem *item;
for (item = deviceList; item; item = item->next) {
for (item = deviceList; item; item = item->next) {
if (item->instance_id == device_instance) {
SDL_SYS_RemoveJoystickDevice(item);
break;
SDL_SYS_RemoveJoystickDevice(item);
break;
}
}
}
@ -608,9 +615,6 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick)
SDL_PrivateJoystickAxis(joystick, i, axes[i]);
}
/* Apparently the dpad values are not accurate enough to be useful. */
/* hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad); */
Uint8 buttons[] = {
gamepad.buttonA.isPressed,
gamepad.buttonX.isPressed,
@ -620,8 +624,6 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick)
updateplayerindex |= (joystick->buttons[i] != buttons[i]);
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
}
/* TODO: Figure out what to do with reportsAbsoluteDpadValues */
}
#endif /* TARGET_OS_TV */

View file

@ -44,7 +44,7 @@
{
if ((self = [super initWithFrame:frame])) {
#if TARGET_OS_TV
if (SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_SWIPES_AS_ARROW_KEYS, SDL_TRUE)) {
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
/* Apple TV Remote touchpad swipe gestures. */
UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
@ -237,10 +237,10 @@
return SDL_SCANCODE_RIGHT;
case UIPressTypeSelect:
/* HIG says: "primary button behavior" */
return SDL_SCANCODE_SELECT;
return SDL_SCANCODE_RETURN;
case UIPressTypeMenu:
/* HIG says: "returns to previous screen" */
return SDL_SCANCODE_MENU;
return SDL_SCANCODE_ESCAPE;
case UIPressTypePlayPause:
/* HIG says: "secondary button behavior" */
return SDL_SCANCODE_PAUSE;
@ -251,31 +251,34 @@
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
}
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
}
}
[super pressesBegan:presses withEvent:event];
}
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
}
[super pressesEnded:presses withEvent:event];
}
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
}
[super pressesCancelled:presses withEvent:event];
}