boo/lib/inputdev/DualshockPad.cpp

146 lines
4.3 KiB
C++
Raw Normal View History

2015-08-18 22:43:30 +00:00
#include "boo/inputdev/DualshockPad.hpp"
2018-10-07 02:49:22 +00:00
#include "boo/inputdev/DeviceSignature.hpp"
2015-08-31 03:40:58 +00:00
#define _USE_MATH_DEFINES
2017-12-29 07:54:26 +00:00
#include <cmath>
2015-05-15 01:16:36 +00:00
#include <iostream>
2017-12-29 07:54:26 +00:00
#include <cstdio>
2015-05-15 01:16:36 +00:00
#include <memory.h>
2015-08-31 03:40:58 +00:00
#ifdef _WIN32
static inline uint16_t bswap16(uint16_t val) {return _byteswap_ushort(val);}
2015-09-13 03:44:11 +00:00
#elif __GNUC__ && !defined(__FreeBSD__)
2015-08-31 06:15:08 +00:00
static inline uint16_t bswap16(uint16_t val) {return __builtin_bswap16(val); }
2015-09-13 03:44:11 +00:00
#elif !defined(__FreeBSD__)
2015-08-31 03:40:58 +00:00
static inline uint16_t bswap16(uint16_t val) {return __builtin_byteswap(val);}
#endif
2017-12-30 01:06:44 +00:00
#ifndef M_PIF
#define M_PIF 3.14159265358979323846f /* pi */
#endif
#define RAD_TO_DEG (180.f/M_PIF)
2015-05-15 01:16:36 +00:00
namespace boo
{
static const uint8_t defaultReport[49] = {
0x01,
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
2015-05-15 01:16:36 +00:00
};
DualshockPad::DualshockPad(DeviceToken* token)
2018-10-07 02:49:22 +00:00
: TDeviceBase<IDualshockPadCallback>(dev_typeid(DualshockPad), token),
2015-11-21 01:12:22 +00:00
m_rumbleRequest(EDualshockMotor::None),
m_rumbleState(EDualshockMotor::None)
2015-05-15 01:16:36 +00:00
{
memcpy(m_report.buf, defaultReport, 49);
2015-05-15 01:16:36 +00:00
}
DualshockPad::~DualshockPad()
2015-05-15 01:16:36 +00:00
{
}
void DualshockPad::deviceDisconnected()
2015-05-15 01:16:36 +00:00
{
std::lock_guard<std::mutex> lk(m_callbackLock);
2015-05-15 01:16:36 +00:00
if (m_callback)
m_callback->controllerDisconnected();
}
void DualshockPad::initialCycle()
2015-05-15 01:16:36 +00:00
{
#if 0
uint8_t setupCommand[5] = {0xF4, 0x42, 0x0c, 0x00, 0x00}; //Tells controller to start sending changes on in pipe
if (!sendHIDReport(setupCommand, 5, HIDReportType::Feature, 0xF4))
2015-05-22 00:35:46 +00:00
{
deviceError("Unable to send complete packet! Request size %x\n", sizeof(setupCommand));
return;
}
2015-05-15 01:16:36 +00:00
uint8_t btAddr[8];
2017-05-07 21:24:00 +00:00
receiveHIDReport(btAddr, sizeof(btAddr), HIDReportType::Feature, 0xF5);
2015-05-15 01:16:36 +00:00
for (int i = 0; i < 6; i++)
m_btAddress[5 - i] = btAddr[i + 2]; // Copy into buffer reversed, so it is LSB first
#endif
2015-05-15 01:16:36 +00:00
}
void DualshockPad::transferCycle()
2015-05-15 01:16:36 +00:00
{
2017-05-07 21:24:00 +00:00
}
void DualshockPad::finalCycle()
{
m_report.rumble.leftDuration = 0;
m_report.rumble.leftForce = 0;
m_report.rumble.rightDuration = 0;
m_report.rumble.rightOn = false;
sendHIDReport(m_report.buf, sizeof(m_report), HIDReportType::Output, 0x01);
2017-05-07 21:24:00 +00:00
}
void DualshockPad::receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message)
{
if (message != 1 || length != 49 || tp != HIDReportType::Input)
2015-05-15 01:16:36 +00:00
return;
2017-05-07 21:24:00 +00:00
DualshockPadState state = *reinterpret_cast<const DualshockPadState*>(data);
2015-05-15 01:16:36 +00:00
for (int i = 0; i < 3; i++)
2015-08-31 03:40:58 +00:00
state.m_accelerometer[i] = bswap16(state.m_accelerometer[i]);
2015-05-15 01:16:36 +00:00
2015-08-31 03:40:58 +00:00
state.m_gyrometerZ = bswap16(state.m_gyrometerZ);
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);
2017-12-30 01:06:44 +00:00
state.accPitch = (atan2(accYval, accZval) + M_PIF) * RAD_TO_DEG;
state.accYaw = (atan2(accXval, accZval) + M_PIF) * RAD_TO_DEG;
state.gyroZ = (state.m_gyrometerZ / 1023.f);
{
std::lock_guard<std::mutex> lk(m_callbackLock);
if (m_callback)
m_callback->controllerUpdate(*this, state);
}
2015-05-15 01:16:36 +00:00
if (m_rumbleRequest != m_rumbleState)
{
2015-11-21 01:12:22 +00:00
if ((m_rumbleRequest & EDualshockMotor::Left) != EDualshockMotor::None)
2015-05-15 01:16:36 +00:00
{
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;
}
2015-11-21 01:12:22 +00:00
if ((m_rumbleRequest & EDualshockMotor::Right) != EDualshockMotor::None)
2015-05-15 01:16:36 +00:00
{
m_report.rumble.rightDuration = m_rumbleDuration[1];
m_report.rumble.rightOn = m_rumbleIntensity[1] > 0;
2015-05-15 01:16:36 +00:00
}
else
{
m_report.rumble.rightDuration = 0;
m_report.rumble.rightOn = false;
}
2017-05-07 21:24:00 +00:00
sendHIDReport(m_report.buf, sizeof(m_report), HIDReportType::Output, 0x01);
2015-05-15 01:16:36 +00:00
m_rumbleState = m_rumbleRequest;
}
else
{
2015-05-22 00:35:46 +00:00
if (state.m_reserved5[8] & 0x80)
2015-11-21 01:12:22 +00:00
m_rumbleRequest &= ~EDualshockMotor::Right;
2015-05-22 00:35:46 +00:00
if (state.m_reserved5[7] & 0x01)
2015-11-21 01:12:22 +00:00
m_rumbleRequest &= ~EDualshockMotor::Left;
2015-05-15 01:16:36 +00:00
m_rumbleState = m_rumbleRequest;
}
}
} // boo