5757/* Rate of IMU Sensor Packets over wireless dongle observed in testcontroller at 295hz */
5858#define SENSOR_INTERVAL_APEX5_DONGLE_RATE_HZ 295
5959#define SENSOR_INTERVAL_APEX5_DONGLE_NS (SDL_NS_PER_SECOND / SENSOR_INTERVAL_APEX5_DONGLE_RATE_HZ)
60- /* Rate of IMU Sensor Packets over wired connection observed in testcontroller at 570hz */
61- #define SENSOR_INTERVAL_APEX5_WIRED_RATE_HZ 570
60+ /* Rate of IMU Sensor Packets over wired connection observed in testcontroller at 970hz */
61+ #define SENSOR_INTERVAL_APEX5_WIRED_RATE_HZ 970
6262#define SENSOR_INTERVAL_APEX5_WIRED_NS (SDL_NS_PER_SECOND / SENSOR_INTERVAL_APEX5_WIRED_RATE_HZ)
6363
6464#define FLYDIGI_V1_CMD_REPORT_ID 0x05
6969#define FLYDIGI_V2_MAGIC1 0x5A
7070#define FLYDIGI_V2_MAGIC2 0xA5
7171#define FLYDIGI_V2_GET_INFO_COMMAND 0x01
72- #define FLYDIGI_V2_SET_MODE_COMMAND 0x11
7372#define FLYDIGI_V2_HAPTIC_COMMAND 0x12
74-
73+ #define FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND 0x1c
74+ #define FLYDIGI_ACQUIRE_CONTROLLER_HEARTBEAT_TIME 1000 * 60
7575#define LOAD16 (A , B ) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8))
7676
7777typedef struct
7878{
79+ bool enabled ;
7980 Uint8 deviceID ;
8081 bool has_cz ;
8182 bool has_lmrm ;
@@ -88,6 +89,10 @@ typedef struct
8889 float accelScale ;
8990 float gyroScale ;
9091 Uint8 last_state [USB_PACKET_LENGTH ];
92+
93+ bool stop_thread ;
94+ SDL_Thread * thread ;
95+ char thread_name_buf [256 ];
9196} SDL_DriverFlydigi_Context ;
9297
9398
@@ -193,6 +198,26 @@ static bool GetReply(SDL_HIDAPI_Device* device, Uint8 command, Uint8* data, size
193198 return false;
194199}
195200
201+ static int SDLCALL SDL_HIDAPI_Flydigi_ThreadFunction (SDL_HIDAPI_Device * device )
202+ {
203+ SDL_DriverFlydigi_Context * ctx = (SDL_DriverFlydigi_Context * )device -> context ;
204+ while (true) {
205+ if (ctx -> stop_thread ) {
206+ return 0 ;
207+ }
208+
209+ const Uint8 acquireControllerCmd [] = { FLYDIGI_V2_CMD_REPORT_ID , FLYDIGI_V2_MAGIC1 , FLYDIGI_V2_MAGIC2 , FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND , 23 , 1 , 83 , 68 , 76 , 0 };
210+ if (SDL_hid_write (device -> dev , acquireControllerCmd , sizeof (acquireControllerCmd )) < 0 ) {
211+ return SDL_SetError ("Couldn't enable input reports" );
212+ }
213+ Uint8 acquireControllerData [USB_PACKET_LENGTH ];
214+
215+ if (GetReply (device , FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND , acquireControllerData , sizeof (acquireControllerData ))) {
216+ ctx -> enabled = acquireControllerData [6 ] == 1 ;
217+ }
218+ SDL_Delay (FLYDIGI_ACQUIRE_CONTROLLER_HEARTBEAT_TIME );
219+ }
220+ }
196221static bool HIDAPI_DriverFlydigi_InitControllerV2 (SDL_HIDAPI_Device * device )
197222{
198223 SDL_DriverFlydigi_Context * ctx = (SDL_DriverFlydigi_Context * )device -> context ;
@@ -208,6 +233,7 @@ static bool HIDAPI_DriverFlydigi_InitControllerV2(SDL_HIDAPI_Device *device)
208233 ctx -> firmware_version = LOAD16 (data [17 ], data [16 ]);
209234
210235 switch (data [7 ]) {
236+
211237 case 1 :
212238 // Wired connection
213239 ctx -> wireless = false;
@@ -221,14 +247,26 @@ static bool HIDAPI_DriverFlydigi_InitControllerV2(SDL_HIDAPI_Device *device)
221247 }
222248 }
223249
224- const Uint8 enable_xinput = 255 ; // 1 to enable, 0 to disable (which increases report rate to 1Khz)
225- const Uint8 enable_reports [] = { FLYDIGI_V2_CMD_REPORT_ID , FLYDIGI_V2_MAGIC1 , FLYDIGI_V2_MAGIC2 , FLYDIGI_V2_SET_MODE_COMMAND , 6 , enable_xinput , 1 , 255 , 255 , 0 };
226- if (SDL_hid_write (device -> dev , enable_reports , sizeof (enable_reports )) < 0 ) {
250+ const Uint8 acquireControllerCmd [] = { FLYDIGI_V2_CMD_REPORT_ID , FLYDIGI_V2_MAGIC1 , FLYDIGI_V2_MAGIC2 , FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND , 23 , 1 , 83 , 68 , 76 , 0 };
251+ if (SDL_hid_write (device -> dev , acquireControllerCmd , sizeof (acquireControllerCmd )) < 0 ) {
227252 return SDL_SetError ("Couldn't enable input reports" );
228253 }
229- return true;
230- }
231254
255+ Uint8 acquireControllerData [USB_PACKET_LENGTH ];
256+ if (GetReply (device , FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND , acquireControllerData , sizeof (acquireControllerData ))) {
257+ if (acquireControllerData [6 ] == 1 ) {
258+ ctx -> enabled = true;
259+ } else {
260+ // the controller can not be acquired by third party app
261+ ctx -> enabled = false;
262+ }
263+ }else {
264+ // the controller does not support acquired by third party app
265+ ctx -> enabled = false;
266+ }
267+
268+ return ctx -> enabled ;
269+ }
232270
233271static void HIDAPI_DriverFlydigi_UpdateDeviceIdentity (SDL_HIDAPI_Device * device )
234272{
@@ -268,6 +306,9 @@ static void HIDAPI_DriverFlydigi_UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
268306 controller_type = SDL_FLYDIGI_VADER4_PRO ;
269307 break ;
270308 case 128 :
309+ case 129 :
310+ case 133 :
311+ case 134 :
271312 controller_type = SDL_FLYDIGI_APEX5 ;
272313 break ;
273314 default :
@@ -314,8 +355,8 @@ static void HIDAPI_DriverFlydigi_UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
314355 HIDAPI_SetDeviceName (device , "Flydigi Apex 5" );
315356 ctx -> has_lmrm = true;
316357
317- // The Apex 5 gyro values are only usable on firmware 7.0.2.8 and newer
318- if (ctx -> firmware_version >= 0x7028 ) {
358+ // The Apex 5 gyro values are only usable on firmware 7.0.3.0 and newer
359+ if (ctx -> firmware_version >= 0x7030 ) {
319360 ctx -> sensors_supported = true;
320361 ctx -> accelScale = SDL_STANDARD_GRAVITY / 4096.0f ;
321362 ctx -> gyroScale = DEG2RAD (2000.0f );
@@ -416,7 +457,13 @@ static bool HIDAPI_DriverFlydigi_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
416457 SDL_PrivateJoystickAddSensor (joystick , SDL_SENSOR_GYRO , flSensorRate );
417458 SDL_PrivateJoystickAddSensor (joystick , SDL_SENSOR_ACCEL , flSensorRate );
418459 }
460+ if (ctx -> enabled && device -> vendor_id == USB_VENDOR_FLYDIGI_V2 ) {
461+
462+ SDL_snprintf (ctx -> thread_name_buf , sizeof (ctx -> thread_name_buf ), "SDL_hidapi_flydigi %d %04x:%04x" , SDL_GetJoystickID (device -> joysticks ), USB_VENDOR_FLYDIGI_V2 , ctx -> deviceID );
419463
464+ ctx -> stop_thread = false;
465+ ctx -> thread = SDL_CreateThread (SDL_HIDAPI_Flydigi_ThreadFunction , ctx -> thread_name_buf , device );
466+ }
420467 return true;
421468}
422469
@@ -612,6 +659,9 @@ static void HIDAPI_DriverFlydigi_HandleStatePacketV2(SDL_Joystick *joystick, SDL
612659 Sint16 axis ;
613660 Uint64 timestamp = SDL_GetTicksNS ();
614661
662+ if (!ctx -> enabled ) {
663+ return ;
664+ }
615665 if (size > 0 && data [0 ] != 0x5A ) {
616666 // If first byte is not 0x5A, it must be REPORT_ID, we need to remove it.
617667 ++ data ;
@@ -728,13 +778,13 @@ static void HIDAPI_DriverFlydigi_HandleStatePacketV2(SDL_Joystick *joystick, SDL
728778 const float flGyroScale = ctx -> gyroScale ;
729779 values [0 ] = HIDAPI_RemapVal ((float )LOAD16 (data [17 ], data [18 ]), INT16_MIN , INT16_MAX , - flGyroScale , flGyroScale );
730780 values [1 ] = HIDAPI_RemapVal ((float )LOAD16 (data [19 ], data [20 ]), INT16_MIN , INT16_MAX , - flGyroScale , flGyroScale );
731- values [2 ] = HIDAPI_RemapVal ((float )- LOAD16 (data [21 ], data [22 ]), INT16_MIN , INT16_MAX , - flGyroScale , flGyroScale );
781+ values [2 ] = HIDAPI_RemapVal ((float )LOAD16 (data [21 ], data [22 ]), INT16_MIN , INT16_MAX , - flGyroScale , flGyroScale );
732782 SDL_SendJoystickSensor (timestamp , joystick , SDL_SENSOR_GYRO , sensor_timestamp , values , 3 );
733783
734784 const float flAccelScale = ctx -> accelScale ;
735- values [0 ] = LOAD16 (data [25 ], data [26 ]) * flAccelScale ; // Acceleration along pitch axis
736- values [1 ] = LOAD16 (data [27 ], data [28 ]) * flAccelScale ; // Acceleration along yaw axis
737- values [2 ] = - LOAD16 (data [23 ], data [24 ]) * flAccelScale ; // Acceleration along roll axis
785+ values [0 ] = LOAD16 (data [23 ], data [24 ]) * flAccelScale ; // Acceleration along pitch axis
786+ values [1 ] = LOAD16 (data [25 ], data [26 ]) * flAccelScale ; // Acceleration along yaw axis
787+ values [2 ] = - LOAD16 (data [27 ], data [28 ]) * flAccelScale ; // Acceleration along roll axis
738788 SDL_SendJoystickSensor (timestamp , joystick , SDL_SENSOR_ACCEL , sensor_timestamp , values , 3 );
739789 }
740790
@@ -777,6 +827,12 @@ static bool HIDAPI_DriverFlydigi_UpdateDevice(SDL_HIDAPI_Device *device)
777827
778828static void HIDAPI_DriverFlydigi_CloseJoystick (SDL_HIDAPI_Device * device , SDL_Joystick * joystick )
779829{
830+ SDL_DriverFlydigi_Context * ctx = (SDL_DriverFlydigi_Context * )device -> context ;
831+ ctx -> stop_thread = true;
832+ const Uint8 acquireControllerCmd [] = { FLYDIGI_V2_CMD_REPORT_ID , FLYDIGI_V2_MAGIC1 , FLYDIGI_V2_MAGIC2 , FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND , 23 , 0 , 83 , 68 , 76 , 0 };
833+ if (SDL_hid_write (device -> dev , acquireControllerCmd , sizeof (acquireControllerCmd )) < 0 ) {
834+ return SDL_SetError ("Couldn't enable input reports" );
835+ }
780836}
781837
782838static void HIDAPI_DriverFlydigi_FreeDevice (SDL_HIDAPI_Device * device )
0 commit comments