src/joystick/hidapi/SDL_hidapi_ps4.c
changeset 12641 64597a7e8771
parent 12503 806492103856
child 12787 0411f841b035
equal deleted inserted replaced
12640:b708d2c3fe08 12641:64597a7e8771
   106     Uint8 ucVolumeMic;
   106     Uint8 ucVolumeMic;
   107     Uint8 ucVolumeSpeaker;
   107     Uint8 ucVolumeSpeaker;
   108 } DS4EffectsState_t;
   108 } DS4EffectsState_t;
   109 
   109 
   110 typedef struct {
   110 typedef struct {
       
   111     SDL_JoystickID joystickID;
   111     SDL_bool is_dongle;
   112     SDL_bool is_dongle;
   112     SDL_bool is_bluetooth;
   113     SDL_bool is_bluetooth;
   113     SDL_bool audio_supported;
   114     SDL_bool audio_supported;
   114     SDL_bool rumble_supported;
   115     SDL_bool rumble_supported;
   115     Uint8 volume;
   116     Uint8 volume;
   270         return SDL_FALSE;
   271         return SDL_FALSE;
   271     }
   272     }
   272     return SDL_TRUE;
   273     return SDL_TRUE;
   273 }
   274 }
   274 
   275 
   275 static int HIDAPI_DriverPS4_Rumble(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
       
   276 
       
   277 static SDL_bool
   276 static SDL_bool
   278 HIDAPI_DriverPS4_Init(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context)
   277 HIDAPI_DriverPS4_InitDriver(SDL_HIDAPI_DriverData *context, Uint16 vendor_id, Uint16 product_id, int *num_joysticks)
   279 {
   278 {
   280     SDL_DriverPS4_Context *ctx;
   279     SDL_DriverPS4_Context *ctx;
   281 
   280 
   282     ctx = (SDL_DriverPS4_Context *)SDL_calloc(1, sizeof(*ctx));
   281     ctx = (SDL_DriverPS4_Context *)SDL_calloc(1, sizeof(*ctx));
   283     if (!ctx) {
   282     if (!ctx) {
   284         SDL_OutOfMemory();
   283         SDL_OutOfMemory();
   285         return SDL_FALSE;
   284         return SDL_FALSE;
   286     }
   285     }
   287     *context = ctx;
   286     context->context = ctx;
   288 
   287 
   289     /* Check for type of connection */
   288     /* Check for type of connection */
   290     ctx->is_dongle = (vendor_id == SONY_USB_VID && product_id == SONY_DS4_DONGLE_PID);
   289     ctx->is_dongle = (vendor_id == SONY_USB_VID && product_id == SONY_DS4_DONGLE_PID);
   291     if (ctx->is_dongle) {
   290     if (ctx->is_dongle) {
   292         ctx->is_bluetooth = SDL_FALSE;
   291         ctx->is_bluetooth = SDL_FALSE;
   293     } else if (vendor_id == SONY_USB_VID) {
   292     } else if (vendor_id == SONY_USB_VID) {
   294         ctx->is_bluetooth = !CheckUSBConnected(dev);
   293         ctx->is_bluetooth = !CheckUSBConnected(context->device);
   295     } else {
   294     } else {
   296         /* Third party controllers appear to all be wired */
   295         /* Third party controllers appear to all be wired */
   297         ctx->is_bluetooth = SDL_FALSE;
   296         ctx->is_bluetooth = SDL_FALSE;
   298     }
   297     }
   299 #ifdef DEBUG_PS4
   298 #ifdef DEBUG_PS4
   312         } else {
   311         } else {
   313             ctx->rumble_supported = SDL_TRUE;
   312             ctx->rumble_supported = SDL_TRUE;
   314         }
   313         }
   315     }
   314     }
   316 
   315 
       
   316     ctx->joystickID = SDL_GetNextJoystickInstanceID();
       
   317     *num_joysticks += 1;
       
   318     SDL_PrivateJoystickAdded(ctx->joystickID);
       
   319 
       
   320     return SDL_TRUE;
       
   321 }
       
   322 
       
   323 static void
       
   324 HIDAPI_DriverPS4_QuitDriver(SDL_HIDAPI_DriverData *context, SDL_bool send_event, int *num_joysticks)
       
   325 {
       
   326     SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
       
   327 
       
   328     *num_joysticks -= 1;
       
   329     if (send_event) {
       
   330         SDL_PrivateJoystickRemoved(ctx->joystickID);
       
   331     }
       
   332     SDL_free(context->context);
       
   333 }
       
   334 
       
   335 static int
       
   336 HIDAPI_DriverPS4_NumJoysticks(SDL_HIDAPI_DriverData *context)
       
   337 {
       
   338     return 1;
       
   339 }
       
   340 
       
   341 static SDL_JoystickID
       
   342 HIDAPI_DriverPS4_InstanceIDForIndex(SDL_HIDAPI_DriverData *context, int index)
       
   343 {
       
   344     SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
       
   345     return ctx->joystickID;
       
   346 }
       
   347 
       
   348 static int HIDAPI_DriverPS4_Rumble(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
       
   349 
       
   350 static SDL_bool
       
   351 HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick)
       
   352 {
   317     /* Initialize LED and effect state */
   353     /* Initialize LED and effect state */
   318     HIDAPI_DriverPS4_Rumble(joystick, dev, ctx, 0, 0, 0);
   354     HIDAPI_DriverPS4_Rumble(context, joystick, 0, 0, 0);
   319 
   355 
   320     /* Initialize the joystick capabilities */
   356     /* Initialize the joystick capabilities */
   321     joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
   357     joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
   322     joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
   358     joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
   323     joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
   359     joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
   324 
   360 
   325     return SDL_TRUE;
   361     return SDL_TRUE;
   326 }
   362 }
   327 
   363 
   328 static int
   364 static int
   329 HIDAPI_DriverPS4_Rumble(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   365 HIDAPI_DriverPS4_Rumble(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   330 {
   366 {
   331     SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context;
   367     SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
   332     DS4EffectsState_t *effects;
   368     DS4EffectsState_t *effects;
   333     Uint8 data[78];
   369     Uint8 data[78];
   334     int report_size, offset;
   370     int report_size, offset;
   335 
   371 
   336     if (!ctx->rumble_supported) {
   372     if (!ctx->rumble_supported) {
   384         unCRC = crc32(0, &ubHdr, 1);
   420         unCRC = crc32(0, &ubHdr, 1);
   385         unCRC = crc32(unCRC, data, (Uint32)(report_size - sizeof(unCRC)));
   421         unCRC = crc32(unCRC, data, (Uint32)(report_size - sizeof(unCRC)));
   386         SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
   422         SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
   387     }
   423     }
   388 
   424 
   389     if (hid_write(dev, data, report_size) != report_size) {
   425     if (hid_write(context->device, data, report_size) != report_size) {
   390         return SDL_SetError("Couldn't send rumble packet");
   426         return SDL_SetError("Couldn't send rumble packet");
   391     }
   427     }
   392 
   428 
   393     if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   429     if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   394         ctx->rumble_expiration = SDL_GetTicks() + duration_ms;
   430         ctx->rumble_expiration = SDL_GetTicks() + duration_ms;
   506 
   542 
   507     SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state));
   543     SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state));
   508 }
   544 }
   509 
   545 
   510 static SDL_bool
   546 static SDL_bool
   511 HIDAPI_DriverPS4_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
   547 HIDAPI_DriverPS4_UpdateDriver(SDL_HIDAPI_DriverData *context, int *num_joysticks)
   512 {
   548 {
   513     SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context;
   549     SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)context->context;
       
   550     SDL_Joystick *joystick = SDL_JoystickFromInstanceID(ctx->joystickID);
   514     Uint8 data[USB_PACKET_LENGTH];
   551     Uint8 data[USB_PACKET_LENGTH];
   515     int size;
   552     int size;
   516 
   553 
   517     while ((size = hid_read_timeout(dev, data, sizeof(data), 0)) > 0) {
   554     if (joystick == NULL) {
       
   555         return SDL_TRUE; /* Nothing to do right now! */
       
   556     }
       
   557 
       
   558     while ((size = hid_read_timeout(context->device, data, sizeof(data), 0)) > 0) {
   518         switch (data[0]) {
   559         switch (data[0]) {
   519         case k_EPS4ReportIdUsbState:
   560         case k_EPS4ReportIdUsbState:
   520             HIDAPI_DriverPS4_HandleStatePacket(joystick, dev, ctx, (PS4StatePacket_t *)&data[1]);
   561             HIDAPI_DriverPS4_HandleStatePacket(joystick, context->device, ctx, (PS4StatePacket_t *)&data[1]);
   521             break;
   562             break;
   522         case k_EPS4ReportIdBluetoothState:
   563         case k_EPS4ReportIdBluetoothState:
   523             /* Bluetooth state packets have two additional bytes at the beginning */
   564             /* Bluetooth state packets have two additional bytes at the beginning */
   524             HIDAPI_DriverPS4_HandleStatePacket(joystick, dev, ctx, (PS4StatePacket_t *)&data[3]);
   565             HIDAPI_DriverPS4_HandleStatePacket(joystick, context->device, ctx, (PS4StatePacket_t *)&data[3]);
   525             break;
   566             break;
   526         default:
   567         default:
   527 #ifdef DEBUG_JOYSTICK
   568 #ifdef DEBUG_JOYSTICK
   528             SDL_Log("Unknown PS4 packet: 0x%.2x\n", data[0]);
   569             SDL_Log("Unknown PS4 packet: 0x%.2x\n", data[0]);
   529 #endif
   570 #endif
   532     }
   573     }
   533 
   574 
   534     if (ctx->rumble_expiration) {
   575     if (ctx->rumble_expiration) {
   535         Uint32 now = SDL_GetTicks();
   576         Uint32 now = SDL_GetTicks();
   536         if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   577         if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   537             HIDAPI_DriverPS4_Rumble(joystick, dev, context, 0, 0, 0);
   578             HIDAPI_DriverPS4_Rumble(context, joystick, 0, 0, 0);
   538         }
   579         }
   539     }
   580     }
   540 
   581 
   541     return (size >= 0);
   582     return (size >= 0);
   542 }
       
   543 
       
   544 static void
       
   545 HIDAPI_DriverPS4_Quit(SDL_Joystick *joystick, hid_device *dev, void *context)
       
   546 {
       
   547     SDL_free(context);
       
   548 }
   583 }
   549 
   584 
   550 SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
   585 SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
   551 {
   586 {
   552     SDL_HINT_JOYSTICK_HIDAPI_PS4,
   587     SDL_HINT_JOYSTICK_HIDAPI_PS4,
   553     SDL_TRUE,
   588     SDL_TRUE,
   554     HIDAPI_DriverPS4_IsSupportedDevice,
   589     HIDAPI_DriverPS4_IsSupportedDevice,
   555     HIDAPI_DriverPS4_GetDeviceName,
   590     HIDAPI_DriverPS4_GetDeviceName,
   556     HIDAPI_DriverPS4_Init,
   591     HIDAPI_DriverPS4_InitDriver,
   557     HIDAPI_DriverPS4_Rumble,
   592     HIDAPI_DriverPS4_QuitDriver,
   558     HIDAPI_DriverPS4_Update,
   593     HIDAPI_DriverPS4_UpdateDriver,
   559     HIDAPI_DriverPS4_Quit
   594     HIDAPI_DriverPS4_NumJoysticks,
       
   595     HIDAPI_DriverPS4_InstanceIDForIndex,
       
   596     HIDAPI_DriverPS4_OpenJoystick,
       
   597     HIDAPI_DriverPS4_Rumble
   560 };
   598 };
   561 
   599 
   562 #endif /* SDL_JOYSTICK_HIDAPI_PS4 */
   600 #endif /* SDL_JOYSTICK_HIDAPI_PS4 */
   563 
   601 
   564 #endif /* SDL_JOYSTICK_HIDAPI */
   602 #endif /* SDL_JOYSTICK_HIDAPI */