src/joystick/hidapi/SDL_hidapi_xboxone.c
changeset 12641 64597a7e8771
parent 12503 806492103856
child 12787 0411f841b035
equal deleted inserted replaced
12640:b708d2c3fe08 12641:64597a7e8771
   122     { 0x24c6, 0x542a, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init) },
   122     { 0x24c6, 0x542a, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init) },
   123     { 0x24c6, 0x543a, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init) },
   123     { 0x24c6, 0x543a, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init) },
   124 };
   124 };
   125 
   125 
   126 typedef struct {
   126 typedef struct {
       
   127     SDL_JoystickID joystickID;
   127     Uint8 sequence;
   128     Uint8 sequence;
   128     Uint8 last_state[USB_PACKET_LENGTH];
   129     Uint8 last_state[USB_PACKET_LENGTH];
   129     Uint32 rumble_expiration;
   130     Uint32 rumble_expiration;
   130 } SDL_DriverXboxOne_Context;
   131 } SDL_DriverXboxOne_Context;
   131 
   132 
   141 {
   142 {
   142     return HIDAPI_XboxControllerName(vendor_id, product_id);
   143     return HIDAPI_XboxControllerName(vendor_id, product_id);
   143 }
   144 }
   144 
   145 
   145 static SDL_bool
   146 static SDL_bool
   146 HIDAPI_DriverXboxOne_Init(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context)
   147 HIDAPI_DriverXboxOne_InitDriver(SDL_HIDAPI_DriverData *context, Uint16 vendor_id, Uint16 product_id, int *num_joysticks)
   147 {
   148 {
   148     SDL_DriverXboxOne_Context *ctx;
   149     SDL_DriverXboxOne_Context *ctx;
   149     int i;
   150     int i;
   150     Uint8 init_packet[USB_PACKET_LENGTH];
   151     Uint8 init_packet[USB_PACKET_LENGTH];
   151 
   152 
   152     ctx = (SDL_DriverXboxOne_Context *)SDL_calloc(1, sizeof(*ctx));
   153     ctx = (SDL_DriverXboxOne_Context *)SDL_calloc(1, sizeof(*ctx));
   153     if (!ctx) {
   154     if (!ctx) {
   154         SDL_OutOfMemory();
   155         SDL_OutOfMemory();
   155         return SDL_FALSE;
   156         return SDL_FALSE;
   156     }
   157     }
   157     *context = ctx;
   158     context->context = ctx;
   158 
   159 
   159     /* Send the controller init data */
   160     /* Send the controller init data */
   160     for (i = 0; i < SDL_arraysize(xboxone_init_packets); ++i) {
   161     for (i = 0; i < SDL_arraysize(xboxone_init_packets); ++i) {
   161         const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[i];
   162         const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[i];
   162         if (!packet->vendor_id || (vendor_id == packet->vendor_id && product_id == packet->product_id)) {
   163         if (!packet->vendor_id || (vendor_id == packet->vendor_id && product_id == packet->product_id)) {
   163             SDL_memcpy(init_packet, packet->data, packet->size);
   164             SDL_memcpy(init_packet, packet->data, packet->size);
   164             init_packet[2] = ctx->sequence++;
   165             init_packet[2] = ctx->sequence++;
   165             if (hid_write(dev, init_packet, packet->size) != packet->size) {
   166             if (hid_write(context->device, init_packet, packet->size) != packet->size) {
   166                 SDL_SetError("Couldn't write Xbox One initialization packet");
   167                 SDL_SetError("Couldn't write Xbox One initialization packet");
   167                 SDL_free(ctx);
   168                 SDL_free(ctx);
   168                 return SDL_FALSE;
   169                 return SDL_FALSE;
   169             }
   170             }
   170         }
   171         }
   171     }
   172     }
   172 
   173 
       
   174     ctx->joystickID = SDL_GetNextJoystickInstanceID();
       
   175     *num_joysticks += 1;
       
   176     SDL_PrivateJoystickAdded(ctx->joystickID);
       
   177 
       
   178     return SDL_TRUE;
       
   179 }
       
   180 
       
   181 static SDL_bool
       
   182 HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick)
       
   183 {
   173     /* Initialize the joystick capabilities */
   184     /* Initialize the joystick capabilities */
   174     joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
   185     joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
   175     joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
   186     joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
   176     joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
   187     joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
   177 
   188 
   178     return SDL_TRUE;
   189     return SDL_TRUE;
   179 }
   190 }
   180 
   191 
       
   192 static void
       
   193 HIDAPI_DriverXboxOne_QuitDriver(SDL_HIDAPI_DriverData *context, SDL_bool send_event, int *num_joysticks)
       
   194 {
       
   195     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context->context;
       
   196 
       
   197     *num_joysticks -= 1;
       
   198     if (send_event) {
       
   199         SDL_PrivateJoystickRemoved(ctx->joystickID);
       
   200     }
       
   201     SDL_free(context->context);
       
   202 }
       
   203 
   181 static int
   204 static int
   182 HIDAPI_DriverXboxOne_Rumble(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   205 HIDAPI_DriverXboxOne_NumJoysticks(SDL_HIDAPI_DriverData *context)
   183 {
   206 {
   184     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context;
   207     return 1;
       
   208 }
       
   209 
       
   210 static SDL_JoystickID
       
   211 HIDAPI_DriverXboxOne_InstanceIDForIndex(SDL_HIDAPI_DriverData *context, int index)
       
   212 {
       
   213     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context->context;
       
   214     return ctx->joystickID;
       
   215 }
       
   216 
       
   217 static int
       
   218 HIDAPI_DriverXboxOne_Rumble(SDL_HIDAPI_DriverData *context, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
       
   219 {
       
   220     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context->context;
   185     Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
   221     Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
   186 
   222 
   187     /* The Rock Candy Xbox One Controller limits the range of
   223     /* The Rock Candy Xbox One Controller limits the range of
   188          low frequency rumble strength in the range of [0 - 0x99]
   224          low frequency rumble strength in the range of [0 - 0x99]
   189          high frequency rumble strength in the range of [0 - 0x82]
   225          high frequency rumble strength in the range of [0 - 0x82]
   192     */
   228     */
   193     rumble_packet[2] = ctx->sequence++;
   229     rumble_packet[2] = ctx->sequence++;
   194     rumble_packet[8] = (low_frequency_rumble >> 9);
   230     rumble_packet[8] = (low_frequency_rumble >> 9);
   195     rumble_packet[9] = (high_frequency_rumble >> 9);
   231     rumble_packet[9] = (high_frequency_rumble >> 9);
   196 
   232 
   197     if (hid_write(dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
   233     if (hid_write(context->device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
   198         return SDL_SetError("Couldn't send rumble packet");
   234         return SDL_SetError("Couldn't send rumble packet");
   199     }
   235     }
   200 
   236 
   201     if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   237     if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   202         ctx->rumble_expiration = SDL_GetTicks() + duration_ms;
   238         ctx->rumble_expiration = SDL_GetTicks() + duration_ms;
   265 
   301 
   266     SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   302     SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
   267 }
   303 }
   268 
   304 
   269 static SDL_bool
   305 static SDL_bool
   270 HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick, hid_device *dev, void *context)
   306 HIDAPI_DriverXboxOne_UpdateDriver(SDL_HIDAPI_DriverData *context, int *num_joysticks)
   271 {
   307 {
   272     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context;
   308     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context->context;
       
   309     SDL_Joystick *joystick = SDL_JoystickFromInstanceID(ctx->joystickID);
   273     Uint8 data[USB_PACKET_LENGTH];
   310     Uint8 data[USB_PACKET_LENGTH];
   274     int size;
   311     int size;
   275 
   312 
   276     while ((size = hid_read_timeout(dev, data, sizeof(data), 0)) > 0) {
   313     if (joystick == NULL) {
       
   314         return SDL_TRUE; /* Nothing to do right now! */
       
   315     }
       
   316 
       
   317     while ((size = hid_read_timeout(context->device, data, sizeof(data), 0)) > 0) {
   277         switch (data[0]) {
   318         switch (data[0]) {
   278         case 0x20:
   319         case 0x20:
   279             HIDAPI_DriverXboxOne_HandleStatePacket(joystick, dev, ctx, data, size);
   320             HIDAPI_DriverXboxOne_HandleStatePacket(joystick, context->device, ctx, data, size);
   280             break;
   321             break;
   281         case 0x07:
   322         case 0x07:
   282             HIDAPI_DriverXboxOne_HandleModePacket(joystick, dev, ctx, data, size);
   323             HIDAPI_DriverXboxOne_HandleModePacket(joystick, context->device, ctx, data, size);
   283             break;
   324             break;
   284         default:
   325         default:
   285 #ifdef DEBUG_JOYSTICK
   326 #ifdef DEBUG_JOYSTICK
   286             SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]);
   327             SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]);
   287 #endif
   328 #endif
   290     }
   331     }
   291 
   332 
   292     if (ctx->rumble_expiration) {
   333     if (ctx->rumble_expiration) {
   293         Uint32 now = SDL_GetTicks();
   334         Uint32 now = SDL_GetTicks();
   294         if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   335         if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   295             HIDAPI_DriverXboxOne_Rumble(joystick, dev, context, 0, 0, 0);
   336             HIDAPI_DriverXboxOne_Rumble(context, joystick, 0, 0, 0);
   296         }
   337         }
   297     }
   338     }
   298 
   339 
   299     return (size >= 0);
   340     return (size >= 0);
   300 }
       
   301 
       
   302 static void
       
   303 HIDAPI_DriverXboxOne_Quit(SDL_Joystick *joystick, hid_device *dev, void *context)
       
   304 {
       
   305     SDL_free(context);
       
   306 }
   341 }
   307 
   342 
   308 SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
   343 SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
   309 {
   344 {
   310     SDL_HINT_JOYSTICK_HIDAPI_XBOX,
   345     SDL_HINT_JOYSTICK_HIDAPI_XBOX,
   311     SDL_TRUE,
   346     SDL_TRUE,
   312     HIDAPI_DriverXboxOne_IsSupportedDevice,
   347     HIDAPI_DriverXboxOne_IsSupportedDevice,
   313     HIDAPI_DriverXboxOne_GetDeviceName,
   348     HIDAPI_DriverXboxOne_GetDeviceName,
   314     HIDAPI_DriverXboxOne_Init,
   349     HIDAPI_DriverXboxOne_InitDriver,
   315     HIDAPI_DriverXboxOne_Rumble,
   350     HIDAPI_DriverXboxOne_QuitDriver,
   316     HIDAPI_DriverXboxOne_Update,
   351     HIDAPI_DriverXboxOne_UpdateDriver,
   317     HIDAPI_DriverXboxOne_Quit
   352     HIDAPI_DriverXboxOne_NumJoysticks,
       
   353     HIDAPI_DriverXboxOne_InstanceIDForIndex,
       
   354     HIDAPI_DriverXboxOne_OpenJoystick,
       
   355     HIDAPI_DriverXboxOne_Rumble
   318 };
   356 };
   319 
   357 
   320 #endif /* SDL_JOYSTICK_HIDAPI_XBOXONE */
   358 #endif /* SDL_JOYSTICK_HIDAPI_XBOXONE */
   321 
   359 
   322 #endif /* SDL_JOYSTICK_HIDAPI */
   360 #endif /* SDL_JOYSTICK_HIDAPI */