1
0
mirror of https://github.com/cathery/sys-con.git synced 2024-11-05 08:26:32 +00:00

Dualshock 4: Add touchpad and PS buttons

This commit is contained in:
cathery 2019-11-13 19:53:23 +03:00
parent d9b2b59989
commit 9807350530
4 changed files with 28 additions and 54 deletions

View File

@ -1,5 +1,4 @@
#pragma once
#include "IController.h"
//References used:
@ -82,7 +81,9 @@ struct Dualshock4USBButtonData
bool l3 : 1;
bool r3 : 1;
uint8_t timestamp;
bool psbutton : 1;
bool touchpad_press : 1;
uint8_t timestamp : 6;
uint8_t l2_pressure;
uint8_t r2_pressure;
@ -105,7 +106,6 @@ class Dualshock4Controller : public IController
private:
IUSBEndpoint *m_inPipe = nullptr;
IUSBEndpoint *m_outPipe = nullptr;
IUSBInterface *m_interface = nullptr;
Dualshock4USBButtonData m_buttonData;
@ -125,8 +125,6 @@ public:
virtual ControllerType GetType() override { return CONTROLLER_DUALSHOCK4; }
inline const Dualshock4USBButtonData &GetButtonData() { return m_buttonData; };
float NormalizeTrigger(uint8_t value);
void NormalizeAxis(uint8_t x, uint8_t y, uint8_t deadzonePercent, float *x_out, float *y_out);

View File

@ -17,10 +17,13 @@ protected:
std::unique_ptr<IUSBDevice> m_device;
public:
uint8_t m_inputData[100];
#ifdef __APPLET__
uint8_t m_inputData[64];
bool m_UpdateCalled = false;
IController(std::unique_ptr<IUSBDevice> &&interface) : m_device(std::move(interface)) {}
#endif
IController(std::unique_ptr<IUSBDevice> &&interface) : m_device(std::move(interface))
{
}
virtual ~IController() = default;
virtual Result Initialize() = 0;

View File

@ -1,6 +1,5 @@
#include "Controllers/Dualshock4Controller.h"
#include <cmath>
#include "../../source/log.h"
static ControllerConfig _dualshock4ControllerConfig{};
@ -13,18 +12,9 @@ Dualshock4Controller::~Dualshock4Controller()
{
Exit();
}
/*
uint32_t ComputeDualshock4Checksum(const uint8_t *report_data, uint16_t length)
{
constexpr uint8_t bt_header = 0xa2;
uint32_t crc = crc32(0xffffffff, &bt_header, 1);
return unaligned_crc32(crc, report_data, length);
}
*/
Result Dualshock4Controller::SendInitBytes()
{
constexpr uint8_t init_bytes[32] = {
0x05, 0x07, 0x00, 0x00,
0x7f, 0x7f,
@ -45,12 +35,6 @@ Result Dualshock4Controller::Initialize()
rc = SendInitBytes();
if (R_FAILED(rc))
return rc;
WriteToLog("Max IN packet size: ", m_inPipe->GetDescriptor()->wMaxPacketSize);
WriteToLog("Max OUT packet size: ", m_outPipe->GetDescriptor()->wMaxPacketSize);
return GetInput();
return rc;
}
void Dualshock4Controller::Exit()
@ -65,7 +49,7 @@ Result Dualshock4Controller::OpenInterfaces()
if (R_FAILED(rc))
return rc;
//This will open each interface and try to acquire Dualshock 4 controller's in and out endpoints, if it hasn't already
//Open each interface, send it a setup packet and get the endpoints if it succeeds
std::vector<std::unique_ptr<IUSBInterface>> &interfaces = m_device->GetInterfaces();
for (auto &&interface : interfaces)
{
@ -73,14 +57,9 @@ Result Dualshock4Controller::OpenInterfaces()
if (R_FAILED(rc))
return rc;
if (interface->GetDescriptor()->bInterfaceProtocol != 0)
continue;
if (interface->GetDescriptor()->bNumEndpoints < 2)
continue;
m_interface = interface.get();
if (!m_inPipe)
{
for (int i = 0; i != 15; ++i)
@ -88,7 +67,7 @@ Result Dualshock4Controller::OpenInterfaces()
IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, i);
if (inEndpoint)
{
rc = inEndpoint->Open(100);
rc = inEndpoint->Open();
if (R_FAILED(rc))
return 61;
@ -105,7 +84,7 @@ Result Dualshock4Controller::OpenInterfaces()
IUSBEndpoint *outEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_OUT, i);
if (outEndpoint)
{
rc = outEndpoint->Open(100);
rc = outEndpoint->Open();
if (R_FAILED(rc))
return 62;
@ -129,26 +108,29 @@ void Dualshock4Controller::CloseInterfaces()
Result Dualshock4Controller::GetInput()
{
uint8_t input_bytes[64];
Result rc = m_inPipe->Read(input_bytes, sizeof(input_bytes));
if (R_FAILED(rc))
{
m_inputData[0] = static_cast<uint8_t>(rc);
return rc;
}
uint8_t type = input_bytes[0];
if (type == 0x01)
#ifdef __APPLET__
for (int i = 0; i != 64; ++i)
m_inputData[i] = input_bytes[i];
m_UpdateCalled = true;
#endif
if (input_bytes[0] == 0x01)
{
m_buttonData = *reinterpret_cast<Dualshock4USBButtonData *>(input_bytes);
}
return rc;
}
float Dualshock4Controller::NormalizeTrigger(uint8_t value)
{
uint16_t deadzone = (UINT8_MAX * _dualshock4ControllerConfig.triggerDeadzonePercent) / 100;
uint8_t deadzone = (UINT8_MAX * _dualshock4ControllerConfig.triggerDeadzonePercent) / 100;
//If the given value is below the trigger zone, save the calc and return 0, otherwise adjust the value to the deadzone
return value < deadzone
? 0
@ -219,8 +201,8 @@ NormalizedButtonData Dualshock4Controller::GetNormalizedButtonData()
(m_buttonData.dpad == DS4_RIGHT) || (m_buttonData.dpad == DS4_UPRIGHT) || (m_buttonData.dpad == DS4_DOWNRIGHT),
(m_buttonData.dpad == DS4_DOWN) || (m_buttonData.dpad == DS4_DOWNRIGHT) || (m_buttonData.dpad == DS4_DOWNLEFT),
(m_buttonData.dpad == DS4_LEFT) || (m_buttonData.dpad == DS4_UPLEFT) || (m_buttonData.dpad == DS4_DOWNLEFT),
false, //m_buttonData.touchpad_press,
false, //m_buttonData.psbutton,
m_buttonData.touchpad_press,
m_buttonData.psbutton,
};
for (int i = 0; i != NUM_CONTROLLERBUTTONS; ++i)
@ -234,17 +216,8 @@ NormalizedButtonData Dualshock4Controller::GetNormalizedButtonData()
Result Dualshock4Controller::SetRumble(uint8_t strong_magnitude, uint8_t weak_magnitude)
{
//Not implemented yet
return 9;
/*
uint8_t rumble_data[]{
0x09, 0x00,
m_rumbleDataCounter++,
0x09, 0x00, 0x0f, 0x00, 0x00,
strong_magnitude,
weak_magnitude,
0xff, 0x00, 0x00};
return m_outPipe->Write(rumble_data, sizeof(rumble_data));
*/
}
void Dualshock4Controller::LoadConfig(const ControllerConfig *config)

View File

@ -156,7 +156,7 @@ Result mainLoop()
{
if (handler->GetController()->m_UpdateCalled)
{
for (int i = 0; i != 100; ++i)
for (int i = 0; i != 64; ++i)
printf("0x%02X ", handler->GetController()->m_inputData[i]);
printf("\n");
handler->GetController()->m_UpdateCalled = false;
@ -218,7 +218,7 @@ Result mainLoop()
UsbHsInterface interfaces[4];
s32 total_entries;
if (R_SUCCEEDED(QueryVendorProduct(interfaces, sizeof(interfaces), &total_entries, VENDOR_SONY, PRODUCT_DUALSHOCK3)))
if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_HID, 0, 0)))
{
WriteToLog("Registering DS3 controller");
devicePtr = std::make_unique<SwitchUSBDevice>(interfaces, total_entries);
@ -305,6 +305,6 @@ Result mainLoop()
usbHsDestroyInterfaceAvailableEvent(&catchAllEvent, 1);
usbHsDestroyInterfaceAvailableEvent(&ds4Event, 2);
//controllerInterfaces.clear();
controllerInterfaces.clear();
return rc;
}