mirror of https://github.com/AxioDL/boo.git
Initial DS3 support
This commit is contained in:
parent
cf9e12c650
commit
2234d7f143
|
@ -1,5 +1,6 @@
|
||||||
#include "inputdev/SDeviceSignature.hpp"
|
#include "inputdev/SDeviceSignature.hpp"
|
||||||
#include "inputdev/CDolphinSmashAdapter.hpp"
|
#include "inputdev/CDolphinSmashAdapter.hpp"
|
||||||
|
#include "inputdev/CDualshockPad.hpp"
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -7,6 +8,7 @@ namespace boo
|
||||||
const SDeviceSignature BOO_DEVICE_SIGS[] =
|
const SDeviceSignature BOO_DEVICE_SIGS[] =
|
||||||
{
|
{
|
||||||
DEVICE_SIG(CDolphinSmashAdapter, 0x57e, 0x337),
|
DEVICE_SIG(CDolphinSmashAdapter, 0x57e, 0x337),
|
||||||
|
DEVICE_SIG(CDualshockController, 0x54c, 0x268),
|
||||||
DEVICE_SIG_SENTINEL()
|
DEVICE_SIG_SENTINEL()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,5 +18,6 @@ namespace boo {typedef CGLXContext CGraphicsContext;}
|
||||||
#include "IGraphicsContext.hpp"
|
#include "IGraphicsContext.hpp"
|
||||||
#include "inputdev/CDeviceFinder.hpp"
|
#include "inputdev/CDeviceFinder.hpp"
|
||||||
#include "inputdev/CDolphinSmashAdapter.hpp"
|
#include "inputdev/CDolphinSmashAdapter.hpp"
|
||||||
|
#include "inputdev/CDualshockPad.hpp"
|
||||||
|
|
||||||
#endif // BOO_HPP
|
#endif // BOO_HPP
|
||||||
|
|
|
@ -34,9 +34,8 @@ public:
|
||||||
virtual void finalCycle() {}
|
virtual void finalCycle() {}
|
||||||
|
|
||||||
/* High-Level API */
|
/* High-Level API */
|
||||||
bool sendHIDReport(const uint8_t* data, size_t length);
|
bool sendHIDReport(const uint8_t* data, size_t length, uint16_t message=0);
|
||||||
virtual size_t receiveReport(uint8_t* data, size_t length) {return 0;}
|
virtual size_t receiveReport(uint8_t* data, size_t length, uint16_t message=0);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ enum EDolphinControllerButtons
|
||||||
DOL_DOWN = 1<<14,
|
DOL_DOWN = 1<<14,
|
||||||
DOL_UP = 1<<15
|
DOL_UP = 1<<15
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SDolphinControllerState
|
struct SDolphinControllerState
|
||||||
{
|
{
|
||||||
uint8_t m_leftStick[2];
|
uint8_t m_leftStick[2];
|
||||||
|
|
|
@ -1,9 +1,183 @@
|
||||||
#ifndef CDUALSHOCKPAD_HPP
|
#ifndef CDUALSHOCKPAD_HPP
|
||||||
#define CDUALSHOCKPAD_HPP
|
#define CDUALSHOCKPAD_HPP
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "CDeviceBase.hpp"
|
||||||
|
|
||||||
namespace boo
|
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
|
#endif // CDUALSHOCKPAD_HPP
|
||||||
|
|
|
@ -2,8 +2,10 @@ CONFIG -= Qt
|
||||||
CONFIG += console
|
CONFIG += console
|
||||||
#QMAKE_CXXFLAGS -= -std=c++0x
|
#QMAKE_CXXFLAGS -= -std=c++0x
|
||||||
#CONFIG += c++11
|
#CONFIG += c++11
|
||||||
unix:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++
|
mac:QMAKE_CXXFLAGS += -std=c++11 -stdlib=libc++
|
||||||
unix:LIBS += -std=c++11 -stdlib=libc++ -lc++abi
|
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
|
win32:LIBS += Setupapi.lib winusb.lib User32.lib /SUBSYSTEM:Windows
|
||||||
|
|
||||||
|
|
|
@ -47,10 +47,17 @@ size_t CDeviceBase::receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, siz
|
||||||
return false;
|
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)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,12 +102,8 @@ void CDolphinSmashAdapter::transferCycle()
|
||||||
{
|
{
|
||||||
uint8_t rumbleMessage[5] = {0x11};
|
uint8_t rumbleMessage[5] = {0x11};
|
||||||
for (int i=0 ; i<4 ; ++i)
|
for (int i=0 ; i<4 ; ++i)
|
||||||
{
|
rumbleMessage[i+1] = (rumbleReq & 1<<i);
|
||||||
if (rumbleReq & 1<<i)
|
|
||||||
rumbleMessage[i+1] = 1;
|
|
||||||
else
|
|
||||||
rumbleMessage[i+1] = 0;
|
|
||||||
}
|
|
||||||
sendUSBInterruptTransfer(0, rumbleMessage, sizeof(rumbleMessage));
|
sendUSBInterruptTransfer(0, rumbleMessage, sizeof(rumbleMessage));
|
||||||
m_rumbleState = rumbleReq;
|
m_rumbleState = rumbleReq;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,137 @@
|
||||||
#include "inputdev/CDualshockPad.hpp"
|
#include "inputdev/CDualshockPad.hpp"
|
||||||
|
#include <math.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <endian.h>
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
#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; i<buflen; i+=16) {
|
||||||
|
printf("%06x: ", i);
|
||||||
|
for (j=0; j<16; j++)
|
||||||
|
if (i+j < buflen)
|
||||||
|
printf("%02x ", buf[i+j]);
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
printf(" ");
|
||||||
|
for (j=0; j<16; j++)
|
||||||
|
if (i+j < buflen)
|
||||||
|
printf("%c", isprint(buf[i+j]) ? buf[i+j] : '.');
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace boo
|
||||||
|
{
|
||||||
|
static const uint8_t defaultReport[35] = {
|
||||||
|
0x01,
|
||||||
|
0xff, 0x00, 0xff, 0x00,
|
||||||
|
0xff, 0x80, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||||
|
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||||
|
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||||
|
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
CDualshockController::CDualshockController(CDeviceToken* token)
|
||||||
|
: CDeviceBase(token),
|
||||||
|
m_callback(nullptr),
|
||||||
|
m_rumbleRequest(0),
|
||||||
|
m_rumbleState(0)
|
||||||
|
{
|
||||||
|
memcpy(m_report.buf, defaultReport, 35);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDualshockController::~CDualshockController()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDualshockController::deviceDisconnected()
|
||||||
|
{
|
||||||
|
if (m_callback)
|
||||||
|
m_callback->controllerDisconnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -212,7 +212,7 @@ class CHIDDeviceIOKit final : public IHIDDevice
|
||||||
m_runningTransferLoop = false;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class CHIDDeviceUdev final : public IHIDDevice
|
||||||
{
|
{
|
||||||
usbdevfs_bulktransfer xfer =
|
usbdevfs_bulktransfer xfer =
|
||||||
{
|
{
|
||||||
m_usbIntfOutPipe | USB_DIR_OUT,
|
m_usbIntfOutPipe | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||||
(unsigned)length,
|
(unsigned)length,
|
||||||
0,
|
0,
|
||||||
(void*)data
|
(void*)data
|
||||||
|
@ -56,7 +56,7 @@ class CHIDDeviceUdev final : public IHIDDevice
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)
|
size_t _receiveUSBInterruptTransfer(uint8_t pipe, uint8_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (m_devFd)
|
if (m_devFd)
|
||||||
|
@ -191,17 +191,53 @@ class CHIDDeviceUdev final : public IHIDDevice
|
||||||
m_runningTransferLoop = false;
|
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;
|
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:
|
public:
|
||||||
|
|
||||||
CHIDDeviceUdev(CDeviceToken& token, CDeviceBase& devImp)
|
CHIDDeviceUdev(CDeviceToken& token, CDeviceBase& devImp)
|
||||||
: m_token(token),
|
: m_token(token),
|
||||||
m_devImp(devImp),
|
m_devImp(devImp),
|
||||||
m_devPath(token.getDevicePath())
|
m_devPath(token.getDevicePath())
|
||||||
{
|
{
|
||||||
devImp.m_hidDev = this;
|
devImp.m_hidDev = this;
|
||||||
std::unique_lock<std::mutex> lk(m_initMutex);
|
std::unique_lock<std::mutex> lk(m_initMutex);
|
||||||
|
|
|
@ -180,7 +180,7 @@ class CHIDDeviceWinUSB final : public IHIDDevice
|
||||||
m_runningTransferLoop = false;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,8 @@ class CHIDListenerUdev final : public IHIDListener
|
||||||
{
|
{
|
||||||
const char* interfacesStr = udev_list_entry_get_value(devInterfaces);
|
const char* interfacesStr = udev_list_entry_get_value(devInterfaces);
|
||||||
if (strstr(interfacesStr, ":030104") || /* HID / GenericDesktop / Joystick */
|
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* hidEnum = udev_enumerate_new(UDEV_INST);
|
||||||
udev_enumerate_add_match_parent(hidEnum, device);
|
udev_enumerate_add_match_parent(hidEnum, device);
|
||||||
|
|
|
@ -12,7 +12,8 @@ class IHIDDevice
|
||||||
virtual void _deviceDisconnected()=0;
|
virtual void _deviceDisconnected()=0;
|
||||||
virtual bool _sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)=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 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:
|
public:
|
||||||
inline virtual ~IHIDDevice() {}
|
inline virtual ~IHIDDevice() {}
|
||||||
};
|
};
|
||||||
|
|
107
test/main.cpp
107
test/main.cpp
|
@ -5,6 +5,7 @@
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <iostream>
|
||||||
#include <boo.hpp>
|
#include <boo.hpp>
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#define _WIN32_LEAN_AND_MEAN 1
|
#define _WIN32_LEAN_AND_MEAN 1
|
||||||
|
@ -32,22 +33,78 @@ class CDolphinSmashAdapterCallback : public IDolphinSmashAdapterCallback
|
||||||
const SDolphinControllerState& state)
|
const SDolphinControllerState& state)
|
||||||
{
|
{
|
||||||
printf("CONTROLLER %u UPDATE %d %d\n", idx, state.m_leftStick[0], state.m_leftStick[1]);
|
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
|
class CTestDeviceFinder : public CDeviceFinder
|
||||||
{
|
{
|
||||||
CDolphinSmashAdapter* smashAdapter = NULL;
|
CDolphinSmashAdapter* smashAdapter = NULL;
|
||||||
|
CDualshockController* ds3 = nullptr;
|
||||||
CDolphinSmashAdapterCallback m_cb;
|
CDolphinSmashAdapterCallback m_cb;
|
||||||
|
CDualshockControllerCallback m_ds3CB;
|
||||||
public:
|
public:
|
||||||
CTestDeviceFinder()
|
CTestDeviceFinder()
|
||||||
: CDeviceFinder({"CDolphinSmashAdapter"})
|
: CDeviceFinder({"CDolphinSmashAdapter",
|
||||||
|
"CDualshockController"})
|
||||||
{}
|
{}
|
||||||
void deviceConnected(CDeviceToken& tok)
|
void deviceConnected(CDeviceToken& tok)
|
||||||
{
|
{
|
||||||
smashAdapter = dynamic_cast<CDolphinSmashAdapter*>(tok.openAndGetDevice());
|
smashAdapter = dynamic_cast<CDolphinSmashAdapter*>(tok.openAndGetDevice());
|
||||||
smashAdapter->setCallback(&m_cb);
|
if (smashAdapter)
|
||||||
smashAdapter->startRumble(0);
|
{
|
||||||
|
smashAdapter->setCallback(&m_cb);
|
||||||
|
smashAdapter->startRumble(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ds3 = dynamic_cast<CDualshockController*>(tok.openAndGetDevice());
|
||||||
|
if (ds3)
|
||||||
|
{
|
||||||
|
ds3->setCallback(&m_ds3CB);
|
||||||
|
ds3->setLED(DS3_LED_1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void deviceDisconnected(CDeviceToken&, CDeviceBase* device)
|
void deviceDisconnected(CDeviceToken&, CDeviceBase* device)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +113,11 @@ public:
|
||||||
delete smashAdapter;
|
delete smashAdapter;
|
||||||
smashAdapter = NULL;
|
smashAdapter = NULL;
|
||||||
}
|
}
|
||||||
|
if (ds3 == device)
|
||||||
|
{
|
||||||
|
delete ds3;
|
||||||
|
ds3 = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,33 +137,33 @@ static const DEV_BROADCAST_DEVICEINTERFACE_A HOTPLUG_CONF =
|
||||||
};
|
};
|
||||||
|
|
||||||
LRESULT CALLBACK WindowProc(
|
LRESULT CALLBACK WindowProc(
|
||||||
_In_ HWND hwnd,
|
_In_ HWND hwnd,
|
||||||
_In_ UINT uMsg,
|
_In_ UINT uMsg,
|
||||||
_In_ WPARAM wParam,
|
_In_ WPARAM wParam,
|
||||||
_In_ LPARAM lParam
|
_In_ LPARAM lParam
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
/* Register hotplug notification with windows */
|
/* Register hotplug notification with windows */
|
||||||
RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE);
|
RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case WM_DEVICECHANGE:
|
case WM_DEVICECHANGE:
|
||||||
return boo::CDeviceFinder::winDevChangedHandler(wParam, lParam);
|
return boo::CDeviceFinder::winDevChangedHandler(wParam, lParam);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int APIENTRY wWinMain(
|
int APIENTRY wWinMain(
|
||||||
_In_ HINSTANCE hInstance,
|
_In_ HINSTANCE hInstance,
|
||||||
_In_ HINSTANCE,
|
_In_ HINSTANCE,
|
||||||
_In_ LPTSTR,
|
_In_ LPTSTR,
|
||||||
_In_ int
|
_In_ int
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
AllocConsole();
|
AllocConsole();
|
||||||
freopen("CONOUT$", "w", stdout);
|
freopen("CONOUT$", "w", stdout);
|
||||||
|
@ -159,6 +221,9 @@ int main(int argc, char** argv)
|
||||||
CFRunLoopRun();
|
CFRunLoopRun();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
//delete ctx;
|
//delete ctx;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue