src/joystick/hidapi/SDL_hidapi_ps4.c
changeset 12641 64597a7e8771
parent 12503 806492103856
child 12787 0411f841b035
     1.1 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c	Sat Mar 16 17:47:59 2019 -0700
     1.2 +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c	Tue Mar 12 20:27:54 2019 -0400
     1.3 @@ -108,6 +108,7 @@
     1.4  } DS4EffectsState_t;
     1.5  
     1.6  typedef struct {
     1.7 +    SDL_JoystickID joystickID;
     1.8      SDL_bool is_dongle;
     1.9      SDL_bool is_bluetooth;
    1.10      SDL_bool audio_supported;
    1.11 @@ -272,10 +273,8 @@
    1.12      return SDL_TRUE;
    1.13  }
    1.14  
    1.15 -static int HIDAPI_DriverPS4_Rumble(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
    1.16 -
    1.17  static SDL_bool
    1.18 -HIDAPI_DriverPS4_Init(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context)
    1.19 +HIDAPI_DriverPS4_InitDriver(SDL_HIDAPI_DriverData *context, Uint16 vendor_id, Uint16 product_id, int *num_joysticks)
    1.20  {
    1.21      SDL_DriverPS4_Context *ctx;
    1.22  
    1.23 @@ -284,14 +283,14 @@
    1.24          SDL_OutOfMemory();
    1.25          return SDL_FALSE;
    1.26      }
    1.27 -    *context = ctx;
    1.28 +    context->context = ctx;
    1.29  
    1.30      /* Check for type of connection */
    1.31      ctx->is_dongle = (vendor_id == SONY_USB_VID && product_id == SONY_DS4_DONGLE_PID);
    1.32      if (ctx->is_dongle) {
    1.33          ctx->is_bluetooth = SDL_FALSE;
    1.34      } else if (vendor_id == SONY_USB_VID) {
    1.35 -        ctx->is_bluetooth = !CheckUSBConnected(dev);
    1.36 +        ctx->is_bluetooth = !CheckUSBConnected(context->device);
    1.37      } else {
    1.38          /* Third party controllers appear to all be wired */
    1.39          ctx->is_bluetooth = SDL_FALSE;
    1.40 @@ -314,8 +313,45 @@
    1.41          }
    1.42      }
    1.43  
    1.44 +    ctx->joystickID = SDL_GetNextJoystickInstanceID();
    1.45 +    *num_joysticks += 1;
    1.46 +    SDL_PrivateJoystickAdded(ctx->joystickID);
    1.47 +
    1.48 +    return SDL_TRUE;
    1.49 +}
    1.50 +
    1.51 +static void
    1.52 +HIDAPI_DriverPS4_QuitDriver(SDL_HIDAPI_DriverData *context, SDL_bool send_event, int *num_joysticks)
    1.53 +{
    1.54 +    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
    1.55 +
    1.56 +    *num_joysticks -= 1;
    1.57 +    if (send_event) {
    1.58 +        SDL_PrivateJoystickRemoved(ctx->joystickID);
    1.59 +    }
    1.60 +    SDL_free(context->context);
    1.61 +}
    1.62 +
    1.63 +static int
    1.64 +HIDAPI_DriverPS4_NumJoysticks(SDL_HIDAPI_DriverData *context)
    1.65 +{
    1.66 +    return 1;
    1.67 +}
    1.68 +
    1.69 +static SDL_JoystickID
    1.70 +HIDAPI_DriverPS4_InstanceIDForIndex(SDL_HIDAPI_DriverData *context, int index)
    1.71 +{
    1.72 +    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
    1.73 +    return ctx->joystickID;
    1.74 +}
    1.75 +
    1.76 +static int HIDAPI_DriverPS4_Rumble(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
    1.77 +
    1.78 +static SDL_bool
    1.79 +HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick)
    1.80 +{
    1.81      /* Initialize LED and effect state */
    1.82 -    HIDAPI_DriverPS4_Rumble(joystick, dev, ctx, 0, 0, 0);
    1.83 +    HIDAPI_DriverPS4_Rumble(context, joystick, 0, 0, 0);
    1.84  
    1.85      /* Initialize the joystick capabilities */
    1.86      joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
    1.87 @@ -326,9 +362,9 @@
    1.88  }
    1.89  
    1.90  static int
    1.91 -HIDAPI_DriverPS4_Rumble(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    1.92 +HIDAPI_DriverPS4_Rumble(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    1.93  {
    1.94 -    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context;
    1.95 +    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
    1.96      DS4EffectsState_t *effects;
    1.97      Uint8 data[78];
    1.98      int report_size, offset;
    1.99 @@ -386,7 +422,7 @@
   1.100          SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
   1.101      }
   1.102  
   1.103 -    if (hid_write(dev, data, report_size) != report_size) {
   1.104 +    if (hid_write(context->device, data, report_size) != report_size) {
   1.105          return SDL_SetError("Couldn't send rumble packet");
   1.106      }
   1.107  
   1.108 @@ -508,20 +544,25 @@
   1.109  }
   1.110  
   1.111  static SDL_bool
   1.112 -HIDAPI_DriverPS4_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
   1.113 +HIDAPI_DriverPS4_UpdateDriver(SDL_HIDAPI_DriverData *context, int *num_joysticks)
   1.114  {
   1.115 -    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context;
   1.116 +    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
   1.117 +    SDL_Joystick *joystick = SDL_JoystickFromInstanceID(ctx->joystickID);
   1.118      Uint8 data[USB_PACKET_LENGTH];
   1.119      int size;
   1.120  
   1.121 -    while ((size = hid_read_timeout(dev, data, sizeof(data), 0)) > 0) {
   1.122 +    if (joystick == NULL) {
   1.123 +        return SDL_TRUE; /* Nothing to do right now! */
   1.124 +    }
   1.125 +
   1.126 +    while ((size = hid_read_timeout(context->device, data, sizeof(data), 0)) > 0) {
   1.127          switch (data[0]) {
   1.128          case k_EPS4ReportIdUsbState:
   1.129 -            HIDAPI_DriverPS4_HandleStatePacket(joystick, dev, ctx, (PS4StatePacket_t *)&data[1]);
   1.130 +            HIDAPI_DriverPS4_HandleStatePacket(joystick, context->device, ctx, (PS4StatePacket_t *)&data[1]);
   1.131              break;
   1.132          case k_EPS4ReportIdBluetoothState:
   1.133              /* Bluetooth state packets have two additional bytes at the beginning */
   1.134 -            HIDAPI_DriverPS4_HandleStatePacket(joystick, dev, ctx, (PS4StatePacket_t *)&data[3]);
   1.135 +            HIDAPI_DriverPS4_HandleStatePacket(joystick, context->device, ctx, (PS4StatePacket_t *)&data[3]);
   1.136              break;
   1.137          default:
   1.138  #ifdef DEBUG_JOYSTICK
   1.139 @@ -534,29 +575,26 @@
   1.140      if (ctx->rumble_expiration) {
   1.141          Uint32 now = SDL_GetTicks();
   1.142          if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   1.143 -            HIDAPI_DriverPS4_Rumble(joystick, dev, context, 0, 0, 0);
   1.144 +            HIDAPI_DriverPS4_Rumble(context, joystick, 0, 0, 0);
   1.145          }
   1.146      }
   1.147  
   1.148      return (size >= 0);
   1.149  }
   1.150  
   1.151 -static void
   1.152 -HIDAPI_DriverPS4_Quit(SDL_Joystick *joystick, hid_device *dev, void *context)
   1.153 -{
   1.154 -    SDL_free(context);
   1.155 -}
   1.156 -
   1.157  SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
   1.158  {
   1.159      SDL_HINT_JOYSTICK_HIDAPI_PS4,
   1.160      SDL_TRUE,
   1.161      HIDAPI_DriverPS4_IsSupportedDevice,
   1.162      HIDAPI_DriverPS4_GetDeviceName,
   1.163 -    HIDAPI_DriverPS4_Init,
   1.164 -    HIDAPI_DriverPS4_Rumble,
   1.165 -    HIDAPI_DriverPS4_Update,
   1.166 -    HIDAPI_DriverPS4_Quit
   1.167 +    HIDAPI_DriverPS4_InitDriver,
   1.168 +    HIDAPI_DriverPS4_QuitDriver,
   1.169 +    HIDAPI_DriverPS4_UpdateDriver,
   1.170 +    HIDAPI_DriverPS4_NumJoysticks,
   1.171 +    HIDAPI_DriverPS4_InstanceIDForIndex,
   1.172 +    HIDAPI_DriverPS4_OpenJoystick,
   1.173 +    HIDAPI_DriverPS4_Rumble
   1.174  };
   1.175  
   1.176  #endif /* SDL_JOYSTICK_HIDAPI_PS4 */