From 2234d7f14338b0247d23e0a1681b7b5b48fc4f78 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Thu, 14 May 2015 18:16:36 -0700 Subject: [PATCH 1/4] Initial DS3 support --- InputDeviceClasses.cpp | 2 + include/boo.hpp | 1 + include/inputdev/CDeviceBase.hpp | 5 +- include/inputdev/CDolphinSmashAdapter.hpp | 1 - include/inputdev/CDualshockPad.hpp | 174 ++++++++++++++++++++++ libBoo.pro | 6 +- src/inputdev/CDeviceBase.cpp | 11 +- src/inputdev/CDolphinSmashAdapter.cpp | 8 +- src/inputdev/CDualshockPad.cpp | 136 +++++++++++++++++ src/inputdev/CHIDDeviceIOKit.cpp | 2 +- src/inputdev/CHIDDeviceUdev.cpp | 48 +++++- src/inputdev/CHIDDeviceWinUSB.cpp | 2 +- src/inputdev/CHIDListenerUdev.cpp | 3 +- src/inputdev/IHIDDevice.hpp | 3 +- test/main.cpp | 107 ++++++++++--- 15 files changed, 464 insertions(+), 45 deletions(-) diff --git a/InputDeviceClasses.cpp b/InputDeviceClasses.cpp index 3557116..fb9a10c 100644 --- a/InputDeviceClasses.cpp +++ b/InputDeviceClasses.cpp @@ -1,5 +1,6 @@ #include "inputdev/SDeviceSignature.hpp" #include "inputdev/CDolphinSmashAdapter.hpp" +#include "inputdev/CDualshockPad.hpp" namespace boo { @@ -7,6 +8,7 @@ namespace boo const SDeviceSignature BOO_DEVICE_SIGS[] = { DEVICE_SIG(CDolphinSmashAdapter, 0x57e, 0x337), + DEVICE_SIG(CDualshockController, 0x54c, 0x268), DEVICE_SIG_SENTINEL() }; diff --git a/include/boo.hpp b/include/boo.hpp index c407f9e..626f5d7 100644 --- a/include/boo.hpp +++ b/include/boo.hpp @@ -18,5 +18,6 @@ namespace boo {typedef CGLXContext CGraphicsContext;} #include "IGraphicsContext.hpp" #include "inputdev/CDeviceFinder.hpp" #include "inputdev/CDolphinSmashAdapter.hpp" +#include "inputdev/CDualshockPad.hpp" #endif // BOO_HPP diff --git a/include/inputdev/CDeviceBase.hpp b/include/inputdev/CDeviceBase.hpp index 392802f..c468e22 100644 --- a/include/inputdev/CDeviceBase.hpp +++ b/include/inputdev/CDeviceBase.hpp @@ -34,9 +34,8 @@ public: virtual void finalCycle() {} /* High-Level API */ - bool sendHIDReport(const uint8_t* data, size_t length); - virtual size_t receiveReport(uint8_t* data, size_t length) {return 0;} - + bool sendHIDReport(const uint8_t* data, size_t length, uint16_t message=0); + virtual size_t receiveReport(uint8_t* data, size_t length, uint16_t message=0); }; } diff --git a/include/inputdev/CDolphinSmashAdapter.hpp b/include/inputdev/CDolphinSmashAdapter.hpp index ceb0795..adba95e 100644 --- a/include/inputdev/CDolphinSmashAdapter.hpp +++ b/include/inputdev/CDolphinSmashAdapter.hpp @@ -29,7 +29,6 @@ enum EDolphinControllerButtons DOL_DOWN = 1<<14, DOL_UP = 1<<15 }; - struct SDolphinControllerState { uint8_t m_leftStick[2]; diff --git a/include/inputdev/CDualshockPad.hpp b/include/inputdev/CDualshockPad.hpp index ab29c1e..5a4b629 100644 --- a/include/inputdev/CDualshockPad.hpp +++ b/include/inputdev/CDualshockPad.hpp @@ -1,9 +1,183 @@ #ifndef CDUALSHOCKPAD_HPP #define CDUALSHOCKPAD_HPP +#include +#include "CDeviceBase.hpp" namespace boo { + +struct SDualshockLED +{ + uint8_t timeEnabled; + uint8_t dutyLength; + uint8_t enabled; + uint8_t dutyOff; + uint8_t dutyOn; +}; + +struct SDualshockRumble +{ + uint8_t rightDuration; + bool rightOn; + uint8_t leftDuration; + uint8_t leftForce; +}; + +union SDualshockOutReport +{ + struct + { + uint8_t reportId; + SDualshockRumble rumble; + uint8_t padding[4]; + uint8_t leds; + SDualshockLED led[4]; + SDualshockLED reserved; + }; + uint8_t buf[36]; +}; + +enum EDualshockControllerButtons +{ + DS3_SELECT = 1<<0, + DS3_L3 = 1<<1, + DS3_R3 = 1<<2, + DS3_START = 1<<3, + DS3_UP = 1<<4, + DS3_RIGHT = 1<<5, + DS3_DOWN = 1<<6, + DS3_LEFT = 1<<7, + DS3_L2 = 1<<8, + DS3_R2 = 1<<9, + DS3_L1 = 1<<10, + DS3_R1 = 1<<11, + DS3_TRIANGLE = 1<<12, + DS3_CIRCLE = 1<<13, + DS3_CROSS = 1<<14, + DS3_SQUARE = 1<<15 +}; + +enum EDualshockMotor : int +{ + DS3_MOTOR_RIGHT = 1<<0, + DS3_MOTOR_LEFT = 1<<1, +}; + +enum EDualshockLED +{ + DS3_LED_OFF = 0, + DS3_LED_1 = 1<<1, + DS3_LED_2 = 1<<2, + DS3_LED_3 = 1<<3, + DS3_LED_4 = 1<<4 +}; + +struct SDualshockControllerState +{ + uint8_t m_reportType; + uint8_t m_reserved1; + uint16_t m_buttonState; + uint8_t m_psButtonState; + uint8_t m_reserved2; + uint8_t m_leftStick[2]; + uint8_t m_rightStick[2]; + uint8_t m_reserved3[4]; + uint8_t m_pressureUp; + uint8_t m_pressureRight; + uint8_t m_pressureDown; + uint8_t m_pressureLeft; + uint8_t m_pressureL2; + uint8_t m_pressureR2; + uint8_t m_pressureL1; + uint8_t m_pressureR1; + uint8_t m_pressureTriangle; + uint8_t m_pressureCircle; + uint8_t m_pressureCross; + uint8_t m_pressureSquare; + uint8_t m_reserved4[3]; + uint8_t m_charge; + uint8_t m_power; + uint8_t m_connection; + uint8_t m_reserved5[9]; + uint16_t m_accelerometer[3]; + uint16_t m_gyrometerZ; + float accPitch; + float accYaw; + float gyroZ; +}; + +class CDualshockController; +struct IDualshockControllerCallback +{ + CDualshockController* ctrl = nullptr; + virtual void controllerDisconnected() {} + virtual void controllerUpdate(const SDualshockControllerState& state) {} +}; + +class CDualshockController final : public CDeviceBase +{ + IDualshockControllerCallback* m_callback; + uint8_t m_rumbleRequest; + uint8_t m_rumbleState; + uint8_t m_rumbleDuration[2]; + uint8_t m_rumbleIntensity[2]; + uint8_t m_led; + SDualshockOutReport m_report; + uint8_t m_btAddress[6]; + void deviceDisconnected(); + void initialCycle(); + void transferCycle(); + void finalCycle(); +public: + CDualshockController(CDeviceToken* token); + ~CDualshockController(); + + inline void setCallback(IDualshockControllerCallback* cb) + { m_callback = cb; if (m_callback) m_callback->ctrl = this; } + + inline void startRumble(int motor, uint8_t duration = 254, uint8_t intensity=255) + { + m_rumbleRequest |= motor; + if (motor & DS3_MOTOR_LEFT) + { + m_rumbleDuration[0] = duration; + m_rumbleIntensity[0] = intensity; + } + if (motor & DS3_MOTOR_RIGHT) + { + m_rumbleDuration[1] = duration; + m_rumbleIntensity[1] = intensity; + } + } + + inline void stopRumble(int motor) + { + m_rumbleRequest &= ~motor; + } + + inline int getLED() + { + return m_led; + } + + inline void setLED(int led, bool on = true) + { + if (on) + m_led |= led; + else + m_led &= ~led; + + setRawLED(led); + } + + inline void setRawLED(int led) + { + m_report.leds = led; + sendHIDReport(m_report.buf, sizeof(m_report), 0x0201); + } +}; + } #endif // CDUALSHOCKPAD_HPP diff --git a/libBoo.pro b/libBoo.pro index f26f9eb..db56c4a 100644 --- a/libBoo.pro +++ b/libBoo.pro @@ -2,8 +2,10 @@ CONFIG -= Qt CONFIG += console #QMAKE_CXXFLAGS -= -std=c++0x #CONFIG += c++11 -unix:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++ -unix:LIBS += -std=c++11 -stdlib=libc++ -lc++abi +mac:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++ +mac:LIBS += -std=c++11 -lc++abi +unix:!mac:QMAKE_CXXFLAGS += -std=c++11 +unix:!mac:LIBS += -std=c++11 -lc++abi win32:LIBS += Setupapi.lib winusb.lib User32.lib /SUBSYSTEM:Windows diff --git a/src/inputdev/CDeviceBase.cpp b/src/inputdev/CDeviceBase.cpp index c48c719..41c5394 100644 --- a/src/inputdev/CDeviceBase.cpp +++ b/src/inputdev/CDeviceBase.cpp @@ -47,10 +47,17 @@ size_t CDeviceBase::receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, siz return false; } -bool CDeviceBase::sendHIDReport(const uint8_t* data, size_t length) +bool CDeviceBase::sendHIDReport(const uint8_t* data, size_t length, uint16_t message) { if (m_hidDev) - return m_hidDev->_sendHIDReport(data, length); + return m_hidDev->_sendHIDReport(data, length, message); + return false; +} + +size_t CDeviceBase::receiveReport(uint8_t* data, size_t length, uint16_t message) +{ + if (m_hidDev) + return m_hidDev->_recieveReport(data, length, message); return false; } diff --git a/src/inputdev/CDolphinSmashAdapter.cpp b/src/inputdev/CDolphinSmashAdapter.cpp index ab5106e..f93e173 100644 --- a/src/inputdev/CDolphinSmashAdapter.cpp +++ b/src/inputdev/CDolphinSmashAdapter.cpp @@ -102,12 +102,8 @@ void CDolphinSmashAdapter::transferCycle() { uint8_t rumbleMessage[5] = {0x11}; for (int i=0 ; i<4 ; ++i) - { - if (rumbleReq & 1< +#include +#include +#include +#include + +#define RAD_TO_DEG (180.0/M_PI) + +void hexdump(void *ptr, int buflen) { + unsigned char *buf = (unsigned char*)ptr; + int i, j; + for (i=0; icontrollerDisconnected(); +} + +void CDualshockController::initialCycle() +{ + uint8_t setupCommand[4] = {0x42, 0x0c, 0x00, 0x00}; //Tells controller to start sending changes on in pipe + sendHIDReport(setupCommand, sizeof(setupCommand), 0x03F4); + uint8_t btAddr[8]; + receiveReport(btAddr, sizeof(btAddr), 0x03F5); + for (int i = 0; i < 6; i++) + m_btAddress[5 - i] = btAddr[i + 2]; // Copy into buffer reversed, so it is LSB first +} + +void CDualshockController::transferCycle() +{ + SDualshockControllerState state; + size_t recvSz = receiveUSBInterruptTransfer(0, (uint8_t*)&state, 49); + if (recvSz != 49) + return; + printf("\x1B[2J\x1B[H"); + hexdump(&state, 49); + + for (int i = 0; i < 3; i++) + state.m_accelerometer[i] = be16toh(state.m_accelerometer[i]); + + state.m_gyrometerZ = be16toh(state.m_gyrometerZ); + if (m_callback) + m_callback->controllerUpdate(state); + + if (m_rumbleRequest != m_rumbleState) + { + if (m_rumbleRequest & DS3_MOTOR_LEFT) + { + m_report.rumble.leftDuration = m_rumbleDuration[0]; + m_report.rumble.leftForce = m_rumbleIntensity[0]; + } + else + { + m_report.rumble.leftDuration = 0; + m_report.rumble.leftForce = 0; + } + + if (m_rumbleRequest & DS3_MOTOR_RIGHT) + { + m_report.rumble.rightDuration = m_rumbleDuration[0]; + m_report.rumble.rightOn = true; + } + else + { + m_report.rumble.rightDuration = 0; + m_report.rumble.rightOn = false; + } + sendHIDReport(m_report.buf, sizeof(m_report), 0x0201); + m_rumbleState = m_rumbleRequest; + } + else + { + if (state.m_reserved5[8] == 0xC0) + m_rumbleRequest &= ~DS3_MOTOR_RIGHT; + if (state.m_reserved5[7] == 0x01) + m_rumbleRequest &= ~DS3_MOTOR_LEFT; + m_rumbleState = m_rumbleRequest; + const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V); + float accXval = -((double)state.m_accelerometer[0] - zeroG); + float accYval = -((double)state.m_accelerometer[1] - zeroG); + float accZval = -((double)state.m_accelerometer[2] - zeroG); + state.accPitch = (atan2(accYval, accZval) + M_PI) * RAD_TO_DEG; + state.accYaw = (atan2(accXval, accZval) + M_PI) * RAD_TO_DEG; + state.gyroZ = (state.m_gyrometerZ / 1023.f); + } + +} + +void CDualshockController::finalCycle() +{ + +} + +} // boo diff --git a/src/inputdev/CHIDDeviceIOKit.cpp b/src/inputdev/CHIDDeviceIOKit.cpp index 95b115a..cf2b314 100644 --- a/src/inputdev/CHIDDeviceIOKit.cpp +++ b/src/inputdev/CHIDDeviceIOKit.cpp @@ -212,7 +212,7 @@ class CHIDDeviceIOKit final : public IHIDDevice m_runningTransferLoop = false; } - bool _sendHIDReport(const uint8_t* data, size_t length) + bool _sendHIDReport(const uint8_t* data, size_t length, uint16_t message) { return false; } diff --git a/src/inputdev/CHIDDeviceUdev.cpp b/src/inputdev/CHIDDeviceUdev.cpp index 48aaa11..4ba3e20 100644 --- a/src/inputdev/CHIDDeviceUdev.cpp +++ b/src/inputdev/CHIDDeviceUdev.cpp @@ -44,7 +44,7 @@ class CHIDDeviceUdev final : public IHIDDevice { usbdevfs_bulktransfer xfer = { - m_usbIntfOutPipe | USB_DIR_OUT, + m_usbIntfOutPipe | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, (unsigned)length, 0, (void*)data @@ -56,7 +56,7 @@ class CHIDDeviceUdev final : public IHIDDevice } return false; } - + size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length) { if (m_devFd) @@ -191,17 +191,53 @@ class CHIDDeviceUdev final : public IHIDDevice m_runningTransferLoop = false; } - bool _sendHIDReport(const uint8_t* data, size_t length) + bool _sendHIDReport(const uint8_t* data, size_t length, uint16_t message) { + if (m_devFd) + { + usbdevfs_ctrltransfer xfer = + { + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0x09, // HID_SET_REPORT + message, + 0, + (uint16_t)length, + 0, + (void*)data + }; + int ret = ioctl(m_devFd, USBDEVFS_CONTROL, &xfer); + if (ret != (int)length) + return false; + return true; + } return false; } + + size_t _recieveReport(const uint8_t *data, size_t length, uint16_t message) + { + if (m_devFd) + { + usbdevfs_ctrltransfer xfer = + { + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0x01, // HID_GET_REPORT + message, + 0, + (uint16_t)length, + 0, + (void*)data + }; + return ioctl(m_devFd, USBDEVFS_CONTROL, &xfer); + } + return 0; + } public: CHIDDeviceUdev(CDeviceToken& token, CDeviceBase& devImp) - : m_token(token), - m_devImp(devImp), - m_devPath(token.getDevicePath()) + : m_token(token), + m_devImp(devImp), + m_devPath(token.getDevicePath()) { devImp.m_hidDev = this; std::unique_lock lk(m_initMutex); diff --git a/src/inputdev/CHIDDeviceWinUSB.cpp b/src/inputdev/CHIDDeviceWinUSB.cpp index d419140..8149103 100644 --- a/src/inputdev/CHIDDeviceWinUSB.cpp +++ b/src/inputdev/CHIDDeviceWinUSB.cpp @@ -180,7 +180,7 @@ class CHIDDeviceWinUSB final : public IHIDDevice m_runningTransferLoop = false; } - bool _sendHIDReport(const uint8_t* data, size_t length) + bool _sendHIDReport(const uint8_t* data, size_t length, uint16_t message) { return false; } diff --git a/src/inputdev/CHIDListenerUdev.cpp b/src/inputdev/CHIDListenerUdev.cpp index eba7e61..5a01ef1 100644 --- a/src/inputdev/CHIDListenerUdev.cpp +++ b/src/inputdev/CHIDListenerUdev.cpp @@ -88,7 +88,8 @@ class CHIDListenerUdev final : public IHIDListener { const char* interfacesStr = udev_list_entry_get_value(devInterfaces); if (strstr(interfacesStr, ":030104") || /* HID / GenericDesktop / Joystick */ - strstr(interfacesStr, ":030105")) /* HID / GenericDesktop / Gamepad */ + strstr(interfacesStr, ":030105") || /* HID / GenericDesktop / Gamepad */ + strstr(interfacesStr, ":090000")) /* HID / Sony / Dualshock */ { udev_enumerate* hidEnum = udev_enumerate_new(UDEV_INST); udev_enumerate_add_match_parent(hidEnum, device); diff --git a/src/inputdev/IHIDDevice.hpp b/src/inputdev/IHIDDevice.hpp index 99ca399..54beef2 100644 --- a/src/inputdev/IHIDDevice.hpp +++ b/src/inputdev/IHIDDevice.hpp @@ -12,7 +12,8 @@ class IHIDDevice virtual void _deviceDisconnected()=0; virtual bool _sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)=0; virtual size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)=0; - virtual bool _sendHIDReport(const uint8_t* data, size_t length)=0; + virtual bool _sendHIDReport(const uint8_t* data, size_t length, uint16_t message)=0; + virtual size_t _recieveReport(const uint8_t* data, size_t length, uint16_t message){} public: inline virtual ~IHIDDevice() {} }; diff --git a/test/main.cpp b/test/main.cpp index 79e4b27..ce3f7e3 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -5,6 +5,7 @@ #else #endif #include +#include #include #if _WIN32 #define _WIN32_LEAN_AND_MEAN 1 @@ -32,22 +33,78 @@ class CDolphinSmashAdapterCallback : public IDolphinSmashAdapterCallback const SDolphinControllerState& state) { printf("CONTROLLER %u UPDATE %d %d\n", idx, state.m_leftStick[0], state.m_leftStick[1]); + printf(" %d %d\n", state.m_rightStick[0], state.m_rightStick[1]); + } +}; + +class CDualshockControllerCallback : public IDualshockControllerCallback +{ + void controllerDisconnected() + { + printf("CONTROLLER DISCONNECTED\n"); + } + void controllerUpdate(const SDualshockControllerState& state) + { + static time_t timeTotal; + static time_t lastTime = 0; + timeTotal = time(NULL); + time_t timeDif = timeTotal - lastTime; + /* + if (timeDif >= .15) + { + uint8_t led = ctrl->getLED(); + led *= 2; + if (led > 0x10) + led = 2; + ctrl->setRawLED(led); + lastTime = timeTotal; + } + */ + if (state.m_psButtonState) + { + if (timeDif >= 1) // wait 30 seconds before issuing another rumble event + { + std::cout << "RUMBLE" << std::endl; + ctrl->startRumble(DS3_MOTOR_LEFT); + ctrl->startRumble(DS3_MOTOR_RIGHT, 100); + lastTime = timeTotal; + } + } + /* + else + ctrl->stopRumble(DS3_MOTOR_RIGHT | DS3_MOTOR_LEFT);*/ + printf("CONTROLLER UPDATE %d %d\n", state.m_leftStick[0], state.m_leftStick[1]); + printf(" %d %d\n", state.m_rightStick[0], state.m_rightStick[1]); + printf(" %f %f %f\n", state.accPitch, state.accYaw, state.gyroZ); } }; class CTestDeviceFinder : public CDeviceFinder { CDolphinSmashAdapter* smashAdapter = NULL; + CDualshockController* ds3 = nullptr; CDolphinSmashAdapterCallback m_cb; + CDualshockControllerCallback m_ds3CB; public: CTestDeviceFinder() - : CDeviceFinder({"CDolphinSmashAdapter"}) + : CDeviceFinder({"CDolphinSmashAdapter", + "CDualshockController"}) {} void deviceConnected(CDeviceToken& tok) { smashAdapter = dynamic_cast(tok.openAndGetDevice()); - smashAdapter->setCallback(&m_cb); - smashAdapter->startRumble(0); + if (smashAdapter) + { + smashAdapter->setCallback(&m_cb); + smashAdapter->startRumble(0); + return; + } + ds3 = dynamic_cast(tok.openAndGetDevice()); + if (ds3) + { + ds3->setCallback(&m_ds3CB); + ds3->setLED(DS3_LED_1); + } } void deviceDisconnected(CDeviceToken&, CDeviceBase* device) { @@ -56,6 +113,11 @@ public: delete smashAdapter; smashAdapter = NULL; } + if (ds3 == device) + { + delete ds3; + ds3 = nullptr; + } } }; @@ -75,33 +137,33 @@ static const DEV_BROADCAST_DEVICEINTERFACE_A HOTPLUG_CONF = }; LRESULT CALLBACK WindowProc( - _In_ HWND hwnd, - _In_ UINT uMsg, - _In_ WPARAM wParam, - _In_ LPARAM lParam -) + _In_ HWND hwnd, + _In_ UINT uMsg, + _In_ WPARAM wParam, + _In_ LPARAM lParam + ) { switch (uMsg) { - case WM_CREATE: - /* Register hotplug notification with windows */ - RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE); - return 0; + case WM_CREATE: + /* Register hotplug notification with windows */ + RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE); + return 0; - case WM_DEVICECHANGE: - return boo::CDeviceFinder::winDevChangedHandler(wParam, lParam); + case WM_DEVICECHANGE: + return boo::CDeviceFinder::winDevChangedHandler(wParam, lParam); - default: - return DefWindowProc(hwnd, uMsg, wParam, lParam); + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); } } int APIENTRY wWinMain( - _In_ HINSTANCE hInstance, - _In_ HINSTANCE, - _In_ LPTSTR, - _In_ int -) + _In_ HINSTANCE hInstance, + _In_ HINSTANCE, + _In_ LPTSTR, + _In_ int + ) { AllocConsole(); freopen("CONOUT$", "w", stdout); @@ -159,6 +221,9 @@ int main(int argc, char** argv) CFRunLoopRun(); #endif + while(1) + { + } //delete ctx; return 0; } From 4d644327cdd82cee76ed59f970588f2ef49feb17 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Thu, 21 May 2015 17:35:46 -0700 Subject: [PATCH 2/4] * More DS3 work --- include/inputdev/CDeviceBase.hpp | 2 +- include/inputdev/CDualshockPad.hpp | 27 +++++++++++++++------------ src/inputdev/CDeviceBase.cpp | 9 +++++++++ src/inputdev/CDualshockPad.cpp | 13 ++++++++----- src/inputdev/CHIDListenerUdev.cpp | 2 +- test/main.cpp | 1 + 6 files changed, 35 insertions(+), 19 deletions(-) diff --git a/include/inputdev/CDeviceBase.hpp b/include/inputdev/CDeviceBase.hpp index c468e22..fe81c69 100644 --- a/include/inputdev/CDeviceBase.hpp +++ b/include/inputdev/CDeviceBase.hpp @@ -24,7 +24,7 @@ public: virtual ~CDeviceBase(); void closeDevice(); virtual void deviceDisconnected()=0; - virtual void deviceError(const char* error) {fprintf(stderr, "%s\n", error);} + virtual void deviceError(const char* error, ...); /* Low-Level API */ bool sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length); diff --git a/include/inputdev/CDualshockPad.hpp b/include/inputdev/CDualshockPad.hpp index 5a4b629..e4d4107 100644 --- a/include/inputdev/CDualshockPad.hpp +++ b/include/inputdev/CDualshockPad.hpp @@ -30,7 +30,9 @@ union SDualshockOutReport { uint8_t reportId; SDualshockRumble rumble; - uint8_t padding[4]; + uint8_t gyro1; + uint8_t gyro2; + uint8_t padding[2]; uint8_t leds; SDualshockLED led[4]; SDualshockLED reserved; @@ -40,16 +42,16 @@ union SDualshockOutReport enum EDualshockControllerButtons { - DS3_SELECT = 1<<0, - DS3_L3 = 1<<1, - DS3_R3 = 1<<2, - DS3_START = 1<<3, - DS3_UP = 1<<4, - DS3_RIGHT = 1<<5, - DS3_DOWN = 1<<6, - DS3_LEFT = 1<<7, - DS3_L2 = 1<<8, - DS3_R2 = 1<<9, + DS3_SELECT = 1<< 0, + DS3_L3 = 1<< 1, + DS3_R3 = 1<< 2, + DS3_START = 1<< 3, + DS3_UP = 1<< 4, + DS3_RIGHT = 1<< 5, + DS3_DOWN = 1<< 6, + DS3_LEFT = 1<< 7, + DS3_L2 = 1<< 8, + DS3_R2 = 1<< 9, DS3_L1 = 1<<10, DS3_R1 = 1<<11, DS3_TRIANGLE = 1<<12, @@ -102,6 +104,7 @@ struct SDualshockControllerState uint8_t m_reserved5[9]; uint16_t m_accelerometer[3]; uint16_t m_gyrometerZ; + // INTERNAL, set by libBoo, do not modify directly! float accPitch; float accYaw; float gyroZ; @@ -112,7 +115,7 @@ struct IDualshockControllerCallback { CDualshockController* ctrl = nullptr; virtual void controllerDisconnected() {} - virtual void controllerUpdate(const SDualshockControllerState& state) {} + virtual void controllerUpdate(const SDualshockControllerState&) {} }; class CDualshockController final : public CDeviceBase diff --git a/src/inputdev/CDeviceBase.cpp b/src/inputdev/CDeviceBase.cpp index 41c5394..c182bb3 100644 --- a/src/inputdev/CDeviceBase.cpp +++ b/src/inputdev/CDeviceBase.cpp @@ -1,6 +1,7 @@ #include "inputdev/CDeviceBase.hpp" #include "inputdev/CDeviceToken.hpp" #include "IHIDDevice.hpp" +#include namespace boo { @@ -33,6 +34,14 @@ void CDeviceBase::closeDevice() m_token->_deviceClose(); } +void CDeviceBase::deviceError(const char* error, ...) +{ + va_list vl; + va_start(vl, error); + vfprintf(stderr, error, vl); + va_end(vl); +} + bool CDeviceBase::sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length) { if (m_hidDev) diff --git a/src/inputdev/CDualshockPad.cpp b/src/inputdev/CDualshockPad.cpp index 1ccbebf..8664c8f 100644 --- a/src/inputdev/CDualshockPad.cpp +++ b/src/inputdev/CDualshockPad.cpp @@ -29,8 +29,7 @@ void hexdump(void *ptr, int buflen) { namespace boo { static const uint8_t defaultReport[35] = { - 0x01, - 0xff, 0x00, 0xff, 0x00, + 0x01, 0xff, 0x00, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, @@ -62,7 +61,11 @@ void CDualshockController::deviceDisconnected() void CDualshockController::initialCycle() { uint8_t setupCommand[4] = {0x42, 0x0c, 0x00, 0x00}; //Tells controller to start sending changes on in pipe - sendHIDReport(setupCommand, sizeof(setupCommand), 0x03F4); + if (!sendHIDReport(setupCommand, sizeof(setupCommand), 0x03F4)) + { + deviceError("Unable to send complete packet! Request size %x\n", sizeof(setupCommand)); + return; + } uint8_t btAddr[8]; receiveReport(btAddr, sizeof(btAddr), 0x03F5); for (int i = 0; i < 6; i++) @@ -113,9 +116,9 @@ void CDualshockController::transferCycle() } else { - if (state.m_reserved5[8] == 0xC0) + if (state.m_reserved5[8] & 0x80) m_rumbleRequest &= ~DS3_MOTOR_RIGHT; - if (state.m_reserved5[7] == 0x01) + if (state.m_reserved5[7] & 0x01) m_rumbleRequest &= ~DS3_MOTOR_LEFT; m_rumbleState = m_rumbleRequest; const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V); diff --git a/src/inputdev/CHIDListenerUdev.cpp b/src/inputdev/CHIDListenerUdev.cpp index 5a01ef1..5db05f5 100644 --- a/src/inputdev/CHIDListenerUdev.cpp +++ b/src/inputdev/CHIDListenerUdev.cpp @@ -47,7 +47,7 @@ class CHIDListenerUdev final : public IHIDListener int vid = 0, pid = 0; udev_list_entry* attrs = udev_device_get_properties_list_entry(device); -#if 0 +#if 1 udev_list_entry* att = NULL; udev_list_entry_foreach(att, attrs) { diff --git a/test/main.cpp b/test/main.cpp index ce3f7e3..b172a16 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -73,6 +73,7 @@ class CDualshockControllerCallback : public IDualshockControllerCallback /* else ctrl->stopRumble(DS3_MOTOR_RIGHT | DS3_MOTOR_LEFT);*/ + printf("CONTROLLER UPDATE %d %d\n", state.m_leftStick[0], state.m_leftStick[1]); printf(" %d %d\n", state.m_rightStick[0], state.m_rightStick[1]); printf(" %f %f %f\n", state.accPitch, state.accYaw, state.gyroZ); From bfae7bb54a28fa7df4c2ffdc553cca077ebbe2df Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 18 Aug 2015 16:38:53 -0700 Subject: [PATCH 3/4] Fix last commit (how????) --- lib/inputdev/DualshockPad.cpp | 2 +- test/main.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/inputdev/DualshockPad.cpp b/lib/inputdev/DualshockPad.cpp index 747fcf7..6dd6f14 100644 --- a/lib/inputdev/DualshockPad.cpp +++ b/lib/inputdev/DualshockPad.cpp @@ -74,7 +74,7 @@ void DualshockPad::initialCycle() void DualshockPad::transferCycle() { - DualshockControllerState state; + DualshockPadState state; size_t recvSz = receiveUSBInterruptTransfer((uint8_t*)&state, 49); if (recvSz != 49) return; diff --git a/test/main.cpp b/test/main.cpp index 75724c6..a8a3d23 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -22,13 +22,13 @@ class DolphinSmashAdapterCallback : public IDolphinSmashAdapterCallback } }; -class DualshockPadCallback : public IDualshockControllerCallback +class DualshockPadCallback : public IDualshockPadCallback { void controllerDisconnected() { printf("CONTROLLER DISCONNECTED\n"); } - void controllerUpdate(const DualshockControllerState& state) + void controllerUpdate(const DualshockPadState& state) { static time_t timeTotal; static time_t lastTime = 0; From fa6a9047a84d151210b4424545a8e4e5da0a6954 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 18 Aug 2015 16:40:17 -0700 Subject: [PATCH 4/4] Remove libBoo.pro --- libBoo.pro | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 libBoo.pro diff --git a/libBoo.pro b/libBoo.pro deleted file mode 100644 index db56c4a..0000000 --- a/libBoo.pro +++ /dev/null @@ -1,16 +0,0 @@ -CONFIG -= Qt -CONFIG += console -#QMAKE_CXXFLAGS -= -std=c++0x -#CONFIG += c++11 -mac:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++ -mac:LIBS += -std=c++11 -lc++abi -unix:!mac:QMAKE_CXXFLAGS += -std=c++11 -unix:!mac:LIBS += -std=c++11 -lc++abi - -win32:LIBS += Setupapi.lib winusb.lib User32.lib /SUBSYSTEM:Windows - -#unix:!macx:CONFIG += link_pkgconfig -#unix:!macx:PKGCONFIG += x11 - -include(libBoo.pri) -include(test/test.pri)