src/joystick/iphoneos/SDL_sysjoystick.m
changeset 10340 5724f5087acd
parent 10228 9a277db2806d
child 10341 75ac5b0ed013
     1.1 --- a/src/joystick/iphoneos/SDL_sysjoystick.m	Tue Sep 13 19:51:10 2016 -0300
     1.2 +++ b/src/joystick/iphoneos/SDL_sysjoystick.m	Tue Sep 13 22:18:06 2016 -0300
     1.3 @@ -33,7 +33,13 @@
     1.4  #include "../SDL_sysjoystick.h"
     1.5  #include "../SDL_joystick_c.h"
     1.6  
     1.7 +#if !SDL_EVENTS_DISABLED
     1.8 +#include "../../events/SDL_events_c.h"
     1.9 +#endif
    1.10 +
    1.11 +#if !TARGET_OS_TV
    1.12  #import <CoreMotion/CoreMotion.h>
    1.13 +#endif
    1.14  
    1.15  #ifdef SDL_JOYSTICK_MFI
    1.16  #import <GameController/GameController.h>
    1.17 @@ -42,8 +48,10 @@
    1.18  static id disconnectObserver = nil;
    1.19  #endif /* SDL_JOYSTICK_MFI */
    1.20  
    1.21 +#if !TARGET_OS_TV
    1.22  static const char *accelerometerName = "iOS Accelerometer";
    1.23  static CMMotionManager *motionManager = nil;
    1.24 +#endif /* !TARGET_OS_TV */
    1.25  
    1.26  static SDL_JoystickDeviceItem *deviceList = NULL;
    1.27  
    1.28 @@ -102,6 +110,11 @@
    1.29      } else if (controller.gamepad) {
    1.30          device->guid.data[10] = 2;
    1.31      }
    1.32 +#if TARGET_OS_TV
    1.33 +    else if (controller.microGamepad) {
    1.34 +        device->guid.data[10] = 3;
    1.35 +    }
    1.36 +#endif /* TARGET_OS_TV */
    1.37  
    1.38      if (controller.extendedGamepad) {
    1.39          device->naxes = 6; /* 2 thumbsticks and 2 triggers */
    1.40 @@ -112,12 +125,19 @@
    1.41          device->nhats = 1; /* d-pad */
    1.42          device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
    1.43      }
    1.44 -    /* TODO: Handle micro profiles on tvOS. */
    1.45 +#if TARGET_OS_TV
    1.46 +    else if (controller.microGamepad) {
    1.47 +        device->naxes = 2; /* treat the touch surface as two axes */
    1.48 +        device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
    1.49 +        device->nbuttons = 3; /* AX, pause button */
    1.50 +    }
    1.51 +#endif /* TARGET_OS_TV */
    1.52  
    1.53      /* This will be set when the first button press of the controller is
    1.54       * detected. */
    1.55      controller.playerIndex = -1;
    1.56 -#endif
    1.57 +
    1.58 +#endif /* SDL_JOYSTICK_MFI */
    1.59  }
    1.60  
    1.61  static void
    1.62 @@ -143,6 +163,10 @@
    1.63      device->instance_id = instancecounter++;
    1.64  
    1.65      if (accelerometer) {
    1.66 +#if TARGET_OS_TV
    1.67 +        SDL_free(device);
    1.68 +        return;
    1.69 +#else
    1.70          device->name = SDL_strdup(accelerometerName);
    1.71          device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
    1.72          device->nhats = 0;
    1.73 @@ -150,6 +174,7 @@
    1.74  
    1.75          /* Use the accelerometer name as a GUID. */
    1.76          SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
    1.77 +#endif /* TARGET_OS_TV */
    1.78      } else if (controller) {
    1.79          SDL_SYS_AddMFIJoystickDevice(device, controller);
    1.80      }
    1.81 @@ -232,12 +257,14 @@
    1.82  {
    1.83      @autoreleasepool {
    1.84          NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    1.85 +
    1.86 +#if !TARGET_OS_TV
    1.87          const char *hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK);
    1.88 -
    1.89          if (!hint || SDL_atoi(hint)) {
    1.90              /* Default behavior, accelerometer as joystick */
    1.91              SDL_SYS_AddJoystickDevice(nil, SDL_TRUE);
    1.92          }
    1.93 +#endif /* !TARGET_OS_TV */
    1.94  
    1.95  #ifdef SDL_JOYSTICK_MFI
    1.96          /* GameController.framework was added in iOS 7. */
    1.97 @@ -326,6 +353,7 @@
    1.98  
    1.99      @autoreleasepool {
   1.100          if (device->accelerometer) {
   1.101 +#if !TARGET_OS_TV
   1.102              if (motionManager == nil) {
   1.103                  motionManager = [[CMMotionManager alloc] init];
   1.104              }
   1.105 @@ -333,6 +361,7 @@
   1.106              /* Shorter times between updates can significantly increase CPU usage. */
   1.107              motionManager.accelerometerUpdateInterval = 0.1;
   1.108              [motionManager startAccelerometerUpdates];
   1.109 +#endif /* !TARGET_OS_TV */
   1.110          } else {
   1.111  #ifdef SDL_JOYSTICK_MFI
   1.112              GCController *controller = device->controller;
   1.113 @@ -358,6 +387,7 @@
   1.114  static void
   1.115  SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
   1.116  {
   1.117 +#if !TARGET_OS_TV
   1.118      const float maxgforce = SDL_IPHONE_MAX_GFORCE;
   1.119      const SInt16 maxsint16 = 0x7FFF;
   1.120      CMAcceleration accel;
   1.121 @@ -395,6 +425,7 @@
   1.122      SDL_PrivateJoystickAxis(joystick, 0,  (accel.x / maxgforce) * maxsint16);
   1.123      SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
   1.124      SDL_PrivateJoystickAxis(joystick, 2,  (accel.z / maxgforce) * maxsint16);
   1.125 +#endif /* !TARGET_OS_TV */
   1.126  }
   1.127  
   1.128  #ifdef SDL_JOYSTICK_MFI
   1.129 @@ -426,7 +457,7 @@
   1.130  static void
   1.131  SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick)
   1.132  {
   1.133 -#ifdef SDL_JOYSTICK_MFI
   1.134 +#if SDL_JOYSTICK_MFI
   1.135      @autoreleasepool {
   1.136          GCController *controller = joystick->hwdata->controller;
   1.137          Uint8 hatstate = SDL_HAT_CENTERED;
   1.138 @@ -482,13 +513,43 @@
   1.139              };
   1.140  
   1.141              hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad);
   1.142 +            SDL_PrivateJoystickHat(joystick, 0, hatstate);
   1.143  
   1.144              for (i = 0; i < SDL_arraysize(buttons); i++) {
   1.145                  updateplayerindex |= (joystick->buttons[i] != buttons[i]);
   1.146                  SDL_PrivateJoystickButton(joystick, i, buttons[i]);
   1.147              }
   1.148          }
   1.149 -        /* TODO: Handle micro profiles on tvOS. */
   1.150 +#if TARGET_OS_TV
   1.151 +        else if (controller.microGamepad) {
   1.152 +            GCMicroGamepad *gamepad = controller.microGamepad;
   1.153 +
   1.154 +            Sint16 axes[] = {
   1.155 +                (Sint16) (gamepad.dpad.xAxis.value * 32767),
   1.156 +                (Sint16) (gamepad.dpad.yAxis.value * -32767),
   1.157 +            };
   1.158 +
   1.159 +            for (i = 0; i < SDL_arraysize(axes); i++) {
   1.160 +                updateplayerindex |= (joystick->axes[i] != axes[i]);
   1.161 +                SDL_PrivateJoystickAxis(joystick, i, axes[i]);
   1.162 +            }
   1.163 +
   1.164 +            /* Apparently the dpad values are not accurate enough to be useful. */
   1.165 +            /* hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad); */
   1.166 +
   1.167 +            Uint8 buttons[] = {
   1.168 +                gamepad.buttonA.isPressed,
   1.169 +                gamepad.buttonX.isPressed,
   1.170 +            };
   1.171 +
   1.172 +            for (i = 0; i < SDL_arraysize(buttons); i++) {
   1.173 +                updateplayerindex |= (joystick->buttons[i] != buttons[i]);
   1.174 +                SDL_PrivateJoystickButton(joystick, i, buttons[i]);
   1.175 +            }
   1.176 +
   1.177 +            /* TODO: Figure out what to do with reportsAbsoluteDpadValues */
   1.178 +        }
   1.179 +#endif /* TARGET_OS_TV */
   1.180  
   1.181          if (joystick->nhats > 0) {
   1.182              updateplayerindex |= (joystick->hats[0] != hatstate);
   1.183 @@ -528,7 +589,7 @@
   1.184              }
   1.185          }
   1.186      }
   1.187 -#endif
   1.188 +#endif /* SDL_JOYSTICK_MFI */
   1.189  }
   1.190  
   1.191  /* Function to update the state of a joystick - called as a device poll.
   1.192 @@ -566,7 +627,9 @@
   1.193  
   1.194      @autoreleasepool {
   1.195          if (device->accelerometer) {
   1.196 +#if !TARGET_OS_TV
   1.197              [motionManager stopAccelerometerUpdates];
   1.198 +#endif /* !TARGET_OS_TV */
   1.199          } else if (device->controller) {
   1.200  #ifdef SDL_JOYSTICK_MFI
   1.201              GCController *controller = device->controller;
   1.202 @@ -600,7 +663,9 @@
   1.203              SDL_SYS_RemoveJoystickDevice(deviceList);
   1.204          }
   1.205  
   1.206 +#if !TARGET_OS_TV
   1.207          motionManager = nil;
   1.208 +#endif /* !TARGET_OS_TV */
   1.209      }
   1.210  
   1.211      numjoysticks = 0;