Commit a96b6f21049fd96ba715b2d03355cfa480c62cbf

Alex Szpakowski 2016-09-17T01:31:07

Added a new hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION. When set to "1", the orientation of the Apple TV remote affects the axes of the corresponding SDL joystick. It is "0" (disabled) by default.

diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index cd68d8d..806b63b 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -296,6 +296,16 @@ extern "C" {
 #define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS"
 
 /**
+ * \brief  A variable controlling whether the Apple TV remote's joystick axes
+ *         will automatically match the rotation of the remote.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - Remote orientation does not affect joystick axes (the default).
+ *    "1"       - Joystick axes are based on the orientation of the remote.
+ */
+#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"
+
+/**
  *  \brief  A variable controlling whether the Android / iOS built-in
  *  accelerometer should be listed as a joystick device, rather than listing
  *  actual joysticks only.
diff --git a/src/joystick/iphoneos/SDL_sysjoystick.m b/src/joystick/iphoneos/SDL_sysjoystick.m
index a9542dd..da92263 100644
--- a/src/joystick/iphoneos/SDL_sysjoystick.m
+++ b/src/joystick/iphoneos/SDL_sysjoystick.m
@@ -127,9 +127,13 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr
     }
 #if TARGET_OS_TV
     else if (controller.microGamepad) {
+        const char *hint = SDL_GetHint(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION);
+
         device->naxes = 2; /* treat the touch surface as two axes */
         device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
         device->nbuttons = 3; /* AX, pause button */
+
+        controller.microGamepad.allowsRotation = (hint != NULL && *hint != '0');
     }
 #endif /* TARGET_OS_TV */
 
@@ -248,6 +252,22 @@ SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
     return next;
 }
 
+#if TARGET_OS_TV
+static void
+SDL_AppleTVRemoteRotationHintChanged(void *udata, const char *name, const char *oldValue, const char *newValue)
+{
+    BOOL allowRotation = newValue != NULL && *newValue != '0';
+
+    @autoreleasepool {
+        for (GCController *controller in [GCController controllers]) {
+            if (controller.microGamepad) {
+                controller.microGamepad.allowsRotation = allowRotation;
+            }
+        }
+    }
+}
+#endif /* TARGET_OS_TV */
+
 /* Function to scan the system for joysticks.
  * Joystick 0 should be the system default joystick.
  * It should return 0, or -1 on an unrecoverable fatal error.
@@ -276,6 +296,11 @@ SDL_SYS_JoystickInit(void)
             SDL_SYS_AddJoystickDevice(controller, SDL_FALSE);
         }
 
+#if TARGET_OS_TV
+        SDL_AddHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
+                            SDL_AppleTVRemoteRotationHintChanged, NULL);
+#endif /* TARGET_OS_TV */
+
         connectObserver = [center addObserverForName:GCControllerDidConnectNotification
                                               object:nil
                                                queue:nil
@@ -656,6 +681,11 @@ SDL_SYS_JoystickQuit(void)
             [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
             disconnectObserver = nil;
         }
+
+#if TARGET_OS_TV
+        SDL_DelHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
+                            SDL_AppleTVRemoteRotationHintChanged, NULL);
+#endif /* TARGET_OS_TV */
 #endif /* SDL_JOYSTICK_MFI */
 
         while (deviceList != NULL) {