6161#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
64+ #define FLYDIGI_ACQUIRE_CONTROLLER_HEARTBEAT_TIME 1000 * 60
65+
6466#define FLYDIGI_V1_CMD_REPORT_ID 0x05
6567#define FLYDIGI_V1_HAPTIC_COMMAND 0x0F
6668#define FLYDIGI_V1_GET_INFO_COMMAND 0xEC
7173#define FLYDIGI_V2_GET_INFO_COMMAND 0x01
7274#define FLYDIGI_V2_HAPTIC_COMMAND 0x12
7375#define FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND 0x1c
74- #define FLYDIGI_ACQUIRE_CONTROLLER_HEARTBEAT_TIME 1000 * 60
76+
7577#define LOAD16 (A , B ) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8))
7678
7779typedef struct
7880{
79- bool enabled ;
8081 Uint8 deviceID ;
8182 bool has_cz ;
8283 bool has_lmrm ;
@@ -88,11 +89,8 @@ typedef struct
8889 Uint64 sensor_timestamp_step_ns ; // Based on observed rate of receipt of IMU sensor packets.
8990 float accelScale ;
9091 float gyroScale ;
92+ Uint64 last_heartbeat ;
9193 Uint8 last_state [USB_PACKET_LENGTH ];
92-
93- bool stop_thread ;
94- SDL_Thread * thread ;
95- char thread_name_buf [256 ];
9694} SDL_DriverFlydigi_Context ;
9795
9896
@@ -198,26 +196,25 @@ static bool GetReply(SDL_HIDAPI_Device* device, Uint8 command, Uint8* data, size
198196 return false;
199197}
200198
201- static int SDLCALL SDL_HIDAPI_Flydigi_ThreadFunction (SDL_HIDAPI_Device * device )
199+ static bool SDL_HIDAPI_Flydigi_SendHeartbeat (SDL_HIDAPI_Device * device )
202200{
203201 SDL_DriverFlydigi_Context * ctx = (SDL_DriverFlydigi_Context * )device -> context ;
204- while (true) {
205- if (ctx -> stop_thread ) {
206- return 0 ;
207- }
208202
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 ];
203+ 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 };
204+ if (SDL_hid_write (device -> dev , acquireControllerCmd , sizeof (acquireControllerCmd )) < 0 ) {
205+ return SDL_SetError ("Couldn't enable input reports" );
206+ }
214207
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 );
208+ Uint8 acquireControllerData [USB_PACKET_LENGTH ];
209+ if (!GetReply (device , FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND , acquireControllerData , sizeof (acquireControllerData ))) {
210+ return SDL_SetError ("Controller acquiring is not supported" );
219211 }
212+ if (acquireControllerData [6 ] != 1 ) {
213+ return SDL_SetError ("Controller acquiring is disabled" );
214+ }
215+ return true;
220216}
217+
221218static bool HIDAPI_DriverFlydigi_InitControllerV2 (SDL_HIDAPI_Device * device )
222219{
223220 SDL_DriverFlydigi_Context * ctx = (SDL_DriverFlydigi_Context * )device -> context ;
@@ -233,7 +230,6 @@ static bool HIDAPI_DriverFlydigi_InitControllerV2(SDL_HIDAPI_Device *device)
233230 ctx -> firmware_version = LOAD16 (data [17 ], data [16 ]);
234231
235232 switch (data [7 ]) {
236-
237233 case 1 :
238234 // Wired connection
239235 ctx -> wireless = false;
@@ -247,25 +243,9 @@ static bool HIDAPI_DriverFlydigi_InitControllerV2(SDL_HIDAPI_Device *device)
247243 }
248244 }
249245
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 ) {
252- return SDL_SetError ("Couldn't enable input reports" );
253- }
254-
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- }
246+ ctx -> last_heartbeat = SDL_GetTicks ();
267247
268- return ctx -> enabled ;
248+ return SDL_HIDAPI_Flydigi_SendHeartbeat ( device ) ;
269249}
270250
271251static void HIDAPI_DriverFlydigi_UpdateDeviceIdentity (SDL_HIDAPI_Device * device )
@@ -457,13 +437,6 @@ static bool HIDAPI_DriverFlydigi_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
457437 SDL_PrivateJoystickAddSensor (joystick , SDL_SENSOR_GYRO , flSensorRate );
458438 SDL_PrivateJoystickAddSensor (joystick , SDL_SENSOR_ACCEL , flSensorRate );
459439 }
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 );
463-
464- ctx -> stop_thread = false;
465- ctx -> thread = SDL_CreateThread (SDL_HIDAPI_Flydigi_ThreadFunction , ctx -> thread_name_buf , device );
466- }
467440 return true;
468441}
469442
@@ -659,9 +632,6 @@ static void HIDAPI_DriverFlydigi_HandleStatePacketV2(SDL_Joystick *joystick, SDL
659632 Sint16 axis ;
660633 Uint64 timestamp = SDL_GetTicksNS ();
661634
662- if (!ctx -> enabled ) {
663- return ;
664- }
665635 if (size > 0 && data [0 ] != 0x5A ) {
666636 // If first byte is not 0x5A, it must be REPORT_ID, we need to remove it.
667637 ++ data ;
@@ -818,6 +788,16 @@ static bool HIDAPI_DriverFlydigi_UpdateDevice(SDL_HIDAPI_Device *device)
818788 }
819789 }
820790
791+ Uint64 now = SDL_GetTicks ();
792+ if (now >= (ctx -> last_heartbeat + FLYDIGI_ACQUIRE_CONTROLLER_HEARTBEAT_TIME )) {
793+ if (!SDL_HIDAPI_Flydigi_SendHeartbeat (device )) {
794+ // We can no longer acquire the device, mark it as disconnected
795+ HIDAPI_JoystickDisconnected (device , device -> joysticks [0 ]);
796+ return false;
797+ }
798+ ctx -> last_heartbeat = now ;
799+ }
800+
821801 if (size < 0 ) {
822802 // Read error, device is disconnected
823803 HIDAPI_JoystickDisconnected (device , device -> joysticks [0 ]);
@@ -827,12 +807,8 @@ static bool HIDAPI_DriverFlydigi_UpdateDevice(SDL_HIDAPI_Device *device)
827807
828808static void HIDAPI_DriverFlydigi_CloseJoystick (SDL_HIDAPI_Device * device , SDL_Joystick * joystick )
829809{
830- SDL_DriverFlydigi_Context * ctx = (SDL_DriverFlydigi_Context * )device -> context ;
831- ctx -> stop_thread = true;
832810 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- }
811+ SDL_hid_write (device -> dev , acquireControllerCmd , sizeof (acquireControllerCmd ));
836812}
837813
838814static void HIDAPI_DriverFlydigi_FreeDevice (SDL_HIDAPI_Device * device )
0 commit comments