PaulStoffregen / USBHost_t36

USB Host Library for Teensy 3.6 and 4.0
165 stars 85 forks source link

Joystick Example Correction #69

Open welshcoder opened 3 years ago

welshcoder commented 3 years ago

Hi,

First of all, thank you for the team's work on the Teensy and supporting software. The product is just great! :-)

I've been playing with the joystick part of this library, and there were some unexpected results when I was using an XBox 360 wireless receiver for windows. I was finding that when I was using the joystick examples included with the library, the Teensy would say that all four joysticks were connected when nothing was connected to the receiver. I could see in the source that it is meant to detect when a controller connects to the receiver, but this didn't happen.

It took me some time to realise what was going on, and I initially thought there was a bug in the library. However, it turns out that it's the example that's erroneous, and I'd like to propose a change, just in case others find this issue. In the function PrintDeviceListChanges, the check to determine if a joystick active has changed needs to be changed from

if (*drivers[i] != driver_active[i]) (line 173) and if (*hiddrivers[i] != hid_driver_active[i]) (line 192) to if (*(static_cast<JoystickController*>(drivers[i])) != driver_active[i] && (*(drivers[i]) || *(drivers[i]) != driver_active[i])) and if (*(static_cast<JoystickController*>(hiddrivers[i])) != hid_driver_active[i] && (*(hiddrivers[i]) || *(hiddrivers[i]) != hid_driver_active[i]) ) respectively.

The problem was that in the original code, it was the base classes (USBDriver and USBHIDInput) that were being checked for a connection, not the derived JoystickController class which has additional connection checks. It is also necessary to check which base class is actively being used by the JoystickController driver (since the derived class does not differentiate between them), hence the additional check to see which base class returns true.

After changing the code, the driver works as expected with the wireless controller receiver.

I hope you find this helpful and thanks for looking.

EDIT: the check for which base class is being used needed an additional check since the base class would respond with false when some devices are disconnected (this is not true for the XBox wireless receiver, unless it's physically disconnected). Also changed the casting to use static_cast.

welshcoder commented 3 years ago

Just a correction to the above:

Due to the casting taking place and that the pointer could be for other device types, a check is needed to determine if it really is a JoystickController. This could be achieved with a if(strstr(driver_names[i],"joystick")!=NULL) or similar before the if statements above.