diff --git a/CMakeLists.txt b/CMakeLists.txt index fedfb6e..3a48b15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ set(SRC_IDF source/idf/ThrustMaster2.cpp source/idf/ThrustMasterBase.cpp source/idf/ThrustMaster.cpp + source/idf/ThrustMasterAvaBase.cpp source/idf/VirpilMT50CM3.cpp source/idf/VirpilConstellationAlpha.cpp source/idf/UsbChProPedals.cpp @@ -104,6 +105,7 @@ set(SRC_IDF source/idf/UsbSpaceMouse.cpp source/idf/UsbSpaceNavigator.cpp source/idf/UsbTeensyduino.cpp + source/idf/UsbThrustMasterAvaBase.cpp source/idf/UsbVirpilConstellationAlpha.cpp source/idf/UsbWingMan.cpp source/idf/UsbXBox.cpp diff --git a/apps/configurator/configurator.cpp b/apps/configurator/configurator.cpp index fab1c4b..32564df 100644 --- a/apps/configurator/configurator.cpp +++ b/apps/configurator/configurator.cpp @@ -28,6 +28,7 @@ #include "idf/UsbSpaceMouse.hh" #include "idf/UsbSpaceNavigator.hh" #include "idf/UsbTeensyduino.hh" +#include "idf/UsbThrustMasterAvaBase.hh" #include "idf/UsbVirpilConstellationAlpha.hh" #include "idf/UsbWingMan.hh" #include "idf/UsbXBox.hh" @@ -83,6 +84,7 @@ void run() { idf::UsbSpaceMouse spaceMouse; idf::UsbSpaceNavigator spaceNavigator; idf::UsbTeensyduino teensyduino; + idf::UsbThrustMasterAvaBase tmAvaBase; idf::UsbVirpilConstellationAlpha constellation; idf::UsbWingMan wingMan; idf::UsbXBox xBox; @@ -109,6 +111,7 @@ void run() { devices.push_back(&spaceMouse); devices.push_back(&spaceNavigator); devices.push_back(&teensyduino); + devices.push_back(&tmAvaBase); devices.push_back(&constellation); devices.push_back(&wingMan); devices.push_back(&xBox); diff --git a/include/idf/SingleCameraController.hh b/include/idf/SingleCameraController.hh index 092660e..3dc5529 100644 --- a/include/idf/SingleCameraController.hh +++ b/include/idf/SingleCameraController.hh @@ -32,6 +32,7 @@ LIBRARY DEPENDENCIES: ( #include "idf/SaitekX56Stick.hh" #include "idf/SaitekX56Throttle.hh" #include "idf/SpaceBase.hh" +#include "idf/ThrustMasterAvaBase.hh" #include "idf/ThrustMasterBase.hh" #include "idf/XBoxOne.hh" #include "idf/VirpilConstellationAlpha.hh" @@ -279,6 +280,26 @@ class SingleCameraController : public CameraController { */ static SingleCameraController* createInstance(const VirpilConstellationAlpha& virpil); + /** + * creates a new SingleCameraController mapped to @a ThrustMasterAvaBase base using appropriate + * defaults. The AVA Base has 32 discrete generic buttons, X, Y, Z, Rx, Ry, Rz, Slider, Dial + * single directional Hat inputs. But, due to the interchangable grips, generally only a subset + * of these inputs will be functional, and many functions will be mapped to the generic buttons. + * eg for the F-16C Viper grip there are three 4-way hats which are just mapped to 4 buttons + * each and it lacks a twist axis (Z). + * + * HID inherited some legacy norms, such as Joysticks using X and Y for the normal pivot axes, and + * Z to the twist axis, instead of using Rx, Ry and Rz. As such, the Rotational Axes are used for + * other analog inputs. Often a secondary thumbstick or throttle or slider or dial of some kind. + * + * Thus, this mapping will only use the most common and universally typical inputs. + * + * @param ava the inputs to use in the default mapping + * + * @return a new Thrust Master AVA based flight controller + */ + static SingleCameraController* createInstance(const ThrustMasterAvaBase& ava); + /** * creates a new SingleCameraController mapped to @a HidGenericJoystick using appropriate * defaults. Since this is a generic mapping without specific knowledge of the diff --git a/include/idf/SingleFlightController.hh b/include/idf/SingleFlightController.hh index 89e1ab4..ff701d8 100644 --- a/include/idf/SingleFlightController.hh +++ b/include/idf/SingleFlightController.hh @@ -31,6 +31,7 @@ LIBRARY DEPENDENCIES: ( #include "idf/SaitekX52.hh" #include "idf/SaitekX56Stick.hh" #include "idf/SpaceBase.hh" +#include "idf/ThrustMasterAvaBase.hh" #include "idf/ThrustMasterBase.hh" #include "idf/XBoxOne.hh" #include "idf/VirpilConstellationAlpha.hh" @@ -293,6 +294,27 @@ class SingleFlightController : public FlightController { */ static SingleFlightController* createInstance(const VirpilConstellationAlpha& virpil); + /** + * creates a new SingleFlightController mapped to @a ThrustMasterAvaBase base using appropriate + * defaults. The AVA Base has 32 discrete generic buttons, X, Y, Z, Rx, Ry, Rz, Slider, Dial + * single directional Hat inputs. But, due to the interchangable grips, generally only a subset + * of these inputs will be functional, and many functions will be mapped to the generic buttons. + * eg for the F-16C Viper grip there are three 4-way hats which are just mapped to 4 buttons + * each and it lacks a twist axis (Z). + * + * HID inherited some legacy norms, such as Joysticks using X and Y for the normal pivot axes, and + * Z to the twist axis, instead of using Rx, Ry and Rz. As such, the Rotational Axes are used for + * other analog inputs. Often a secondary thumbstick or throttle or slider or dial of some kind. + * + * Thus, this mapping will only use the most common and universally typical inputs. + * + * @param ava the inputs to use in the default mapping + * + * @return a new Thrust Master AVA based flight controller + */ + static SingleFlightController* createInstance(const ThrustMasterAvaBase& ava); + + /** * creates a new SingleFlightController mapped to @a HidGenericJoystick using appropriate * defaults. Since this is a generic mapping without specific knowledge of the diff --git a/include/idf/SingleRoboticsController.hh b/include/idf/SingleRoboticsController.hh index 23c0578..3a18589 100644 --- a/include/idf/SingleRoboticsController.hh +++ b/include/idf/SingleRoboticsController.hh @@ -36,6 +36,7 @@ LIBRARY DEPENDENCIES: ( #include "idf/SpaceMouse.hh" #include "idf/ThrustMaster.hh" #include "idf/ThrustMaster2.hh" +#include "idf/ThrustMasterAvaBase.hh" #include "idf/XBoxOne.hh" #include "idf/VirpilConstellationAlpha.hh" #include "idf/VirtualLayout.hh" @@ -343,7 +344,7 @@ class SingleRoboticsController : public RoboticsController { * * @param dacoThc the inputs to use in the default mapping * - * @return a new DacoThc-based camera controller + * @return a new DacoThc-based robotics controller */ static SingleRoboticsController* createInstance(const DacoThc& dacoThc); @@ -357,6 +358,26 @@ class SingleRoboticsController : public RoboticsController { */ static SingleRoboticsController* createInstance(const VirpilConstellationAlpha& virpil); + /** + * creates a new SingleRoboticsController mapped to @a ThrustMasterAvaBase base using appropriate + * defaults. The AVA Base has 32 discrete generic buttons, X, Y, Z, Rx, Ry, Rz, Slider, Dial + * single directional Hat inputs. But, due to the interchangable grips, generally only a subset + * of these inputs will be functional, and many functions will be mapped to the generic buttons. + * eg for the F-16C Viper grip there are three 4-way hats which are just mapped to 4 buttons + * each and it lacks a twist axis (Z). + * + * HID inherited some legacy norms, such as Joysticks using X and Y for the normal pivot axes, and + * Z to the twist axis, instead of using Rx, Ry and Rz. As such, the Rotational Axes are used for + * other analog inputs. Often a secondary thumbstick or throttle or slider or dial of some kind. + * + * Thus, this mapping will only use the most common and universally typical inputs. + * + * @param ava the inputs to use in the default mapping + * + * @return a new Thrust Master AVA based flight controller + */ + static SingleRoboticsController* createInstance(const ThrustMasterAvaBase& ava); + /** * creates a new SingleRoboticsController mapped to @a HidGenericJoystick using appropriate * defaults. Since this is a generic mapping without specific knowledge of the diff --git a/include/idf/ThrustMasterAvaBase.hh b/include/idf/ThrustMasterAvaBase.hh new file mode 100644 index 0000000..45ed8ce --- /dev/null +++ b/include/idf/ThrustMasterAvaBase.hh @@ -0,0 +1,198 @@ +/* +PURPOSE: +LIBRARY DEPENDENCIES: ( +(idf/ThrustMasterAvaBase.cpp) +) +*/ + +/** + * @trick_parse{everything} + * @trick_link_dependency{idf/ThrustMasterAvaBase.cpp} + */ + +#ifndef THRUSTMASTER_AVA_BASE_HH +#define THRUSTMASTER_AVA_BASE_HH + +#include "idf/InputLayout.hh" +#include "idf/SingleInput.hh" + +namespace idf { + +/** + * %ThrustMaster AVA Base hand controller's input layout. This device has + * interchangeable grips, and not all grips have all inputs. e.g. While this + * class lists Twist, F/B Thumbstick Pivot, L/R Thumbstick Pivot, and 32 buttons, + * the compatible F-16 stick lacks Twist and the thumbstick Pivots, and has only + * 18 buttons. Of those buttons, 12 are physically implemented as three + * different 4-way hat switches. Thus, the standard IDF provided Controllers + * (ie FlightController) will only have the most basic and essential inputs. + * + * @author Philip Kunz + */ +class ThrustMasterAvaBase : public virtual InputLayout { + + public: + + /** constructor */ + ThrustMasterAvaBase(); + + /** destructor */ + virtual ~ThrustMasterAvaBase() {}; + + /** forward-backward pivoting, uses HID X-axis (legacy HID consideration) */ + SingleInput forwardBackwardPivot; + + /** forward-backward pivoting, uses HID Y-axis (legacy HID consideration) */ + SingleInput leftRightPivot; + + /** twisting, uses HID Z-axis (legacy HID consideration) */ + SingleInput twist; + + /** input from Ry axis, likely a thumbstick */ + SingleInput forwardBackwardThumbstickPivot; + + /** input from Rx axis, likely a thumbstick */ + SingleInput leftRightThumbstickPivot; + + /** input from Rz axis. Sometimes throttle slider, analog brakes or a dial */ + SingleInput rotationZ; + + /** the hat's northern trigger */ + SingleInput hatNorth; + + /** the hat's north-eastern trigger */ + SingleInput hatNorthEast; + + /** the hat's eastern trigger */ + SingleInput hatEast; + + /** the hat's south-eastern trigger */ + SingleInput hatSouthEast; + + /** the hat's southern trigger */ + SingleInput hatSouth; + + /** the hat's south-western trigger */ + SingleInput hatSouthWest; + + /** the hat's western trigger */ + SingleInput hatWest; + + /** the hat's north-western trigger */ + SingleInput hatNorthWest; + + /** slider */ + SingleInput slider; + + /** dial */ + SingleInput dial; + + /** the trigger, or button1 */ + SingleInput trigger; + + /** button 2 */ + SingleInput button2; + + /** button 3 */ + SingleInput button3; + + /** button 4 */ + SingleInput button4; + + /** button 5 */ + SingleInput button5; + + /** button 6 */ + SingleInput button6; + + /** button 7 */ + SingleInput button7; + + /** button 8 */ + SingleInput button8; + + /** button 9 */ + SingleInput button9; + + /** button 10 */ + SingleInput button10; + + /** button 11 */ + SingleInput button11; + + /** button 12 */ + SingleInput button12; + + /** button 13 */ + SingleInput button13; + + /** button 14 */ + SingleInput button14; + + /** button 15 */ + SingleInput button15; + + /** button 16 */ + SingleInput button16; + + /** button 17 */ + SingleInput button17; + + /** button 18 */ + SingleInput button18; + + /** button 19 */ + SingleInput button19; + + /** button 20 */ + SingleInput button20; + + /** button 21 */ + SingleInput button21; + + /** button 22 */ + SingleInput button22; + + /** button 23 */ + SingleInput button23; + + /** button 24 */ + SingleInput button24; + + /** button 25 */ + SingleInput button25; + + /** button 26 */ + SingleInput button26; + + /** button 27 */ + SingleInput button27; + + /** button 28 */ + SingleInput button28; + + /** button 29 */ + SingleInput button29; + + /** button 30 */ + SingleInput button30; + + /** button 31 */ + SingleInput button31; + + /** button 32 */ + SingleInput button32; + + protected: + + virtual const std::vector& getConfigurables(); + + private: + + ThrustMasterAvaBase& operator=(const ThrustMasterAvaBase&); + +}; + +} // namespace idf + +#endif \ No newline at end of file diff --git a/include/idf/UsbThrustMasterAvaBase.hh b/include/idf/UsbThrustMasterAvaBase.hh new file mode 100644 index 0000000..dfe170d --- /dev/null +++ b/include/idf/UsbThrustMasterAvaBase.hh @@ -0,0 +1,35 @@ +/* +PURPOSE: +LIBRARY DEPENDENCIES: ( +(idf/UsbThrustMasterAvaBase.cpp) +) +*/ + +/** + * @trick_parse{everything} + * @trick_link_dependency{idf/UsbThrustMasterAvaBase.cpp} + */ + +#ifndef USB_THRUSTMASTER_AVA_BASE_HH +#define USB_THRUSTMASTER_AVA_BASE_HH + +#include "idf/UsbDevice.hh" +#include "idf/ThrustMasterAvaBase.hh" + +namespace idf { + +/** USB ThrustMasterAvaBase joystick */ +class UsbThrustMasterAvaBase : public UsbDevice, public virtual ThrustMasterAvaBase { + + public: + + /** constructor */ + UsbThrustMasterAvaBase(); + + virtual void decode(const std::vector& data); + +}; + +} // name space idf + +#endif diff --git a/source/idf/BtXBoxOneWireless.cpp b/source/idf/BtXBoxOneWireless.cpp index 6b93988..6f902f5 100644 --- a/source/idf/BtXBoxOneWireless.cpp +++ b/source/idf/BtXBoxOneWireless.cpp @@ -9,6 +9,8 @@ BtXBoxOneWireless::BtXBoxOneWireless() : void BtXBoxOneWireless::decode(const std::vector& data) { if (data[0] == 1) { + if (data.size() < 16) return; + directionalPadUp.setValue(false); directionalPadDown.setValue(false); directionalPadLeft.setValue(false); @@ -67,6 +69,7 @@ void BtXBoxOneWireless::decode(const std::vector& data) { rightAnalogTrigger.setValue((int)(unsigned char)(data[12] & 0x3) << 8 | data[11]); } else if (data[0] == 2) { + if (data.size() < 2) return; xBoxButton.setValue(data[1] & 0x1); } } diff --git a/source/idf/SingleCameraController.cpp b/source/idf/SingleCameraController.cpp index ec3c9a6..7259301 100644 --- a/source/idf/SingleCameraController.cpp +++ b/source/idf/SingleCameraController.cpp @@ -305,6 +305,22 @@ SingleCameraController* SingleCameraController::createInstance( return controller; } +SingleCameraController* SingleCameraController::createInstance(const ThrustMasterAvaBase& ava) { + CompositeInput* zoom = new CompositeInput(); + zoom->addInput(ava.hatNorth); + zoom->addInput(ava.hatSouth, -1); + + SingleCameraController *controller = + new SingleCameraController( + ava.twist, + ava.forwardBackwardPivot, + ava.leftRightPivot, + *zoom + ); + + return controller; +} + SingleCameraController* SingleCameraController::createInstance(const GenericJoystick& js) { CompositeInput* zoom = new CompositeInput(); diff --git a/source/idf/SingleFlightController.cpp b/source/idf/SingleFlightController.cpp index 94eb321..bb563e4 100644 --- a/source/idf/SingleFlightController.cpp +++ b/source/idf/SingleFlightController.cpp @@ -389,6 +389,33 @@ SingleFlightController* SingleFlightController::createInstance(const VirpilConst return controller; } +SingleFlightController* SingleFlightController::createInstance(const ThrustMasterAvaBase& ava) { + SingleInput* dummyInput = new SingleInput(-1, 1); + + CompositeInput* x = new CompositeInput(); + x->addInput(ava.hatEast); + x->addInput(ava.hatWest, -1); + + CompositeInput* y = new CompositeInput(); + y->addInput(ava.hatNorth); + y->addInput(ava.hatSouth, -1); + + SingleFlightController *controller = + new SingleFlightController( + ava.leftRightPivot, + ava.forwardBackwardPivot, + ava.twist, + *x, + *y, + *dummyInput + ); + + controller->pitch.setInverted(true); + controller->yaw.setInverted(true); + + return controller; +} + SingleFlightController* SingleFlightController::createInstance(const GenericJoystick& js) { SingleInput* dummyInput = new SingleInput(-1, 1); @@ -406,9 +433,9 @@ SingleFlightController* SingleFlightController::createInstance(const GenericJoys SingleFlightController *controller = new SingleFlightController( - js.twist, - js.forwardBackwardPivot, js.leftRightPivot, + js.forwardBackwardPivot, + js.twist, *dummyInput, *dummyInput, *dummyInput diff --git a/source/idf/SingleRoboticsController.cpp b/source/idf/SingleRoboticsController.cpp index c148d23..5688a6e 100644 --- a/source/idf/SingleRoboticsController.cpp +++ b/source/idf/SingleRoboticsController.cpp @@ -537,6 +537,35 @@ SingleRoboticsController* SingleRoboticsController::createInstance(const VirpilC return controller; } +SingleRoboticsController* SingleRoboticsController::createInstance(const ThrustMasterAvaBase& ava) { + SingleInput* dummyInput = new SingleInput(-1, 1); + + CompositeInput* x = new CompositeInput(); + x->addInput(ava.hatEast); + x->addInput(ava.hatWest, -1); + + CompositeInput* y = new CompositeInput(); + y->addInput(ava.hatNorth); + y->addInput(ava.hatSouth, -1); + + SingleRoboticsController *controller = + new SingleRoboticsController( + ava.leftRightPivot, + ava.forwardBackwardPivot, + ava.twist, + *x, + *y, + *dummyInput, + ava.trigger, + ava.slider + ); + + controller->pitch.setInverted(true); + controller->yaw.setInverted(true); + + return controller; +} + SingleRoboticsController* SingleRoboticsController::createInstance(const GenericJoystick& js) { CompositeInput* x = new CompositeInput(); diff --git a/source/idf/ThrustMasterAvaBase.cpp b/source/idf/ThrustMasterAvaBase.cpp new file mode 100644 index 0000000..68e1b7a --- /dev/null +++ b/source/idf/ThrustMasterAvaBase.cpp @@ -0,0 +1,71 @@ +#include "idf/ThrustMasterAvaBase.hh" + +namespace idf { + +ThrustMasterAvaBase::ThrustMasterAvaBase() : + forwardBackwardPivot(0, 65535, 32768), + leftRightPivot(0, 65535, 32768), + twist(0, 65535, 32768), + forwardBackwardThumbstickPivot(0, 65535, 32768), + leftRightThumbstickPivot(0, 65535, 32768), + rotationZ(0, 65535, 32768), + hatNorth(0, 1), + hatNorthEast(0, 1), + hatEast(0, 1), + hatSouthEast(0, 1), + hatSouth(0, 1), + hatSouthWest(0, 1), + hatWest(0, 1), + hatNorthWest(0, 1), + slider(0, 255), + dial(0,255), + trigger(0, 1), + button2(0, 1), + button3(0, 1), + button4(0, 1), + button5(0, 1), + button6(0, 1), + button7(0, 1), + button8(0, 1), + button9(0, 1), + button10(0, 1), + button11(0, 1), + button12(0, 1), + button13(0, 1), + button14(0, 1), + button15(0, 1), + button16(0, 1), + button17(0, 1), + button18(0, 1), + button19(0, 1), + button20(0, 1), + button21(0, 1), + button22(0, 1), + button23(0, 1), + button24(0, 1), + button25(0, 1), + button26(0, 1), + button27(0, 1), + button28(0, 1), + button29(0, 1), + button30(0, 1), + button31(0, 1), + button32(0, 1) {} + +const std::vector& ThrustMasterAvaBase::getConfigurables() { + static std::vector inputs; + if (inputs.empty()) { + append(InputLayout::getConfigurables(), inputs); + inputs.push_back(Configurable(forwardBackwardPivot, "forwardBackwardPivot", "forwardBackwardPivot")); + inputs.push_back(Configurable(leftRightPivot, "leftRightPivot", "leftRightPivot")); + inputs.push_back(Configurable(twist, "twist", "twist")); + inputs.push_back(Configurable(forwardBackwardThumbstickPivot, "forwardBackwardThumbstickPivot", "forwardBackwardThumbstickPivot")); + inputs.push_back(Configurable(leftRightThumbstickPivot, "leftRightThumbstickPivot", "leftRightThumbstickPivot")); + inputs.push_back(Configurable(rotationZ, "rotationZ", "rotationZ")); + inputs.push_back(Configurable(slider, "slider", "slider")); + inputs.push_back(Configurable(dial, "dial", "dial")); + } + return inputs; +} + +} // namespace idf diff --git a/source/idf/UsbDevice.cpp b/source/idf/UsbDevice.cpp index ce00fe2..0aadfdb 100644 --- a/source/idf/UsbDevice.cpp +++ b/source/idf/UsbDevice.cpp @@ -51,6 +51,7 @@ UsbDevice::UsbDevice(const std::string& id, unsigned length) : identifications["Space Navigator"].push_back(Identification(0x046D, 0xC628, 0)); identifications["Space Navigator"].push_back(Identification(0x256F, 0xC635, 0)); identifications["Teensyduino Joystick"].push_back(Identification(0x16C0, 0x0482, 3)); + identifications["ThrustMaster AVA Base"].push_back(Identification(0x044F, 0x0415, 0)); identifications["Virpil Constellation Alpha"].push_back(Identification(0x3344, 0x4391, 0)); identifications["Wing Man"].push_back(Identification(0x046D, 0xC212, 0)); identifications["Xbox Controller"].push_back(Identification(0x045E, 0x028E, 0)); diff --git a/source/idf/UsbThrustMasterAvaBase.cpp b/source/idf/UsbThrustMasterAvaBase.cpp new file mode 100644 index 0000000..6845c91 --- /dev/null +++ b/source/idf/UsbThrustMasterAvaBase.cpp @@ -0,0 +1,71 @@ +#include "idf/UsbThrustMasterAvaBase.hh" + +namespace idf { + +UsbThrustMasterAvaBase::UsbThrustMasterAvaBase() : + UsbDevice("ThrustMaster AVA Base", 64) {} + +void UsbThrustMasterAvaBase::decode(const std::vector& data) { + if (data[0] != 1) return; + if (data.size() < 64) return; + + trigger.setValue(data[1] & 0x1); + button2.setValue(data[1] >> 1 & 0x1); + button3.setValue(data[1] >> 2 & 0x1); + button4.setValue(data[1] >> 3 & 0x1); + button5.setValue(data[1] >> 4 & 0x1); + button6.setValue(data[1] >> 5 & 0x1); + button7.setValue(data[1] >> 6 & 0x1); + button8.setValue(data[1] >> 7 & 0x1); + + button9.setValue(data[2] & 0x1); + button10.setValue(data[2] >> 1 & 0x1); + button11.setValue(data[2] >> 2 & 0x1); + button12.setValue(data[2] >> 3 & 0x1); + button13.setValue(data[2] >> 4 & 0x1); + button14.setValue(data[2] >> 5 & 0x1); + button15.setValue(data[2] >> 6 & 0x1); + button16.setValue(data[2] >> 7 & 0x1); + + button17.setValue(data[3] & 0x1); + button18.setValue(data[3] >> 1 & 0x1); + button19.setValue(data[3] >> 2 & 0x1); + button20.setValue(data[3] >> 3 & 0x1); + button21.setValue(data[3] >> 4 & 0x1); + button22.setValue(data[3] >> 5 & 0x1); + button23.setValue(data[3] >> 6 & 0x1); + button24.setValue(data[3] >> 7 & 0x1); + + button25.setValue(data[4] & 0x1); + button26.setValue(data[4] >> 1 & 0x1); + button27.setValue(data[4] >> 2 & 0x1); + button28.setValue(data[4] >> 3 & 0x1); + button29.setValue(data[4] >> 4 & 0x1); + button30.setValue(data[4] >> 5 & 0x1); + button31.setValue(data[4] >> 6 & 0x1); + button32.setValue(data[4] >> 7 & 0x1); + + unsigned int hat = data[5] & 0xF; + + hatNorth.setValue(hat == 0); + hatNorthEast.setValue(hat == 1); + hatEast.setValue(hat == 2); + hatSouthEast.setValue(hat == 3); + hatSouth.setValue(hat == 4); + hatSouthWest.setValue(hat == 5); + hatWest.setValue(hat == 6); + hatNorthWest.setValue(hat == 7); + + leftRightPivot.setValue(data[7] << 8 | data[6]); + forwardBackwardPivot.setValue(data[9] << 8 | data[8]); + twist.setValue(data[11] << 8 | data[10]); + + leftRightThumbstickPivot.setValue(data[13] << 8 | data[12]); + forwardBackwardThumbstickPivot.setValue(data[15] << 8 | data[14]); + rotationZ.setValue(data[17] << 8 | data[16]); + + slider.setValue(data[19] << 8 | data[18]); + dial.setValue(data[21] << 8 | data[20]); +} + +} // namespace idf