Added Joycon to controller handlers

This commit is contained in:
ndeadly 2020-05-11 22:27:28 +02:00
parent ed88ff8bb6
commit ef48b1e7dd
5 changed files with 164 additions and 2 deletions

View file

@ -1,7 +1,8 @@
#pragma once
#include "gamepad/controllers/dualshock4.hpp"
#include "gamepad/controllers/joycon.hpp"
#include "gamepad/controllers/switchpro.hpp"
#include "gamepad/controllers/wiimote.hpp"
#include "gamepad/controllers/wiiupro.hpp"
#include "gamepad/controllers/dualshock4.hpp"
#include "gamepad/controllers/xboxone.hpp"

View file

@ -0,0 +1,77 @@
#pragma once
#include <switch.h>
#include "gamepad/hidgamepad.hpp"
namespace mc::controller {
union JoyconStickData {
struct __attribute__ ((__packed__)) {
uint16_t x : 12;
uint16_t : 0;
uint8_t : 8;
};
struct __attribute__ ((__packed__)) {
uint8_t : 8;
uint16_t : 4;
uint16_t y : 12;
};
};
struct JoyconButtonData {
uint8_t Y : 1;
uint8_t X : 1;
uint8_t B : 1;
uint8_t A : 1;
uint8_t : 2; // SR, SL (Right Joy)
uint8_t R : 1;
uint8_t ZR : 1;
uint8_t minus : 1;
uint8_t plus : 1;
uint8_t rstick_press : 1;
uint8_t lstick_press : 1;
uint8_t home : 1;
uint8_t capture : 1;
uint8_t : 0;
uint8_t dpad_down : 1;
uint8_t dpad_up : 1;
uint8_t dpad_right : 1;
uint8_t dpad_left : 1;
uint8_t : 2; // SR, SL (Left Joy)
uint8_t L : 1;
uint8_t ZL : 1;
};
union JoyconReportData {
struct {
uint8_t conn_info : 4;
uint8_t battery : 4;
uint8_t timer;
JoyconButtonData buttons;
JoyconStickData left_stick;
JoyconStickData right_stick;
} report0x30;
};
class JoyconController : public HidGamepad {
public:
static constexpr const HardwareID hardwareIds[] = {
{0x057e, 2006}, // Official Joycon(L) Controller
{0x057e, 2007}, // Official Joycon(R) Controller
};
JoyconController(HidInterfaceType iface) : HidGamepad(iface) {};
Result receiveReport(const HidReport *report);
private:
void mapStickValues(JoystickPosition *dst, const JoyconStickData *src);
void handleInputReport0x30(const JoyconReportData *data);
};
}

View file

@ -11,7 +11,7 @@
namespace mc::controller {
enum ControllerType {
//ControllerType_Joycon,
ControllerType_Joycon,
ControllerType_SwitchPro,
ControllerType_WiiUPro,
ControllerType_Wiimote,

View file

@ -28,6 +28,12 @@ namespace mc::controller {
}
ControllerType ControllerManager::identify(uint16_t vid, uint16_t pid) {
for (HardwareID hwId : JoyconController::hardwareIds) {
if ( (vid == hwId.vid) && (pid == hwId.pid) ) {
return ControllerType_Joycon;
}
}
for (HardwareID hwId : SwitchProController::hardwareIds) {
if ( (vid == hwId.vid) && (pid == hwId.pid) ) {
return ControllerType_SwitchPro;

View file

@ -0,0 +1,78 @@
#include <cstring>
#include <cmath>
#include "gamepad/controllers/joycon.hpp"
namespace mc::controller {
namespace {
const constexpr uint8_t joycon_joystick_nbits = 12;
}
void JoyconController::mapStickValues(JoystickPosition *dst, const JoyconStickData *src) {
dst->dx = unsigned_to_signed(src->x, joycon_joystick_nbits);
dst->dy = -unsigned_to_signed(src->y, joycon_joystick_nbits);
float angle = atan2(dst->dy, dst->dx);
float magnitude = hypot(dst->dx, dst->dy);
if (magnitude < m_innerDeadzone) {
dst->dx = 0;
dst->dy = 0;
}
else if (magnitude > m_outerDeadzone) {
dst->dx = JOYSTICK_MAX * cos(angle);
dst->dy = JOYSTICK_MAX * sin(angle);
}
}
Result JoyconController::receiveReport(const HidReport *report) {
const JoyconReportData *reportData = reinterpret_cast<const JoyconReportData *>(&report->data);
switch(report->id) {
case 0x30:
handleInputReport0x30(reportData);
break;
default:
return -1;
}
return 0;
}
void JoyconController::handleInputReport0x30(const JoyconReportData *data) {
std::memset(&m_state, 0, sizeof(m_state));
this->mapStickValues(&m_state.left_stick, &data->report0x30.left_stick);
this->mapStickValues(&m_state.right_stick, &data->report0x30.right_stick);
m_state.dpad_left = data->report0x30.buttons.dpad_left;
m_state.dpad_up = data->report0x30.buttons.dpad_up;
m_state.dpad_right = data->report0x30.buttons.dpad_right;
m_state.dpad_down = data->report0x30.buttons.dpad_down;
m_state.A = data->report0x30.buttons.A;
m_state.B = data->report0x30.buttons.B;
m_state.X = data->report0x30.buttons.X;
m_state.Y = data->report0x30.buttons.Y;
m_state.L = data->report0x30.buttons.L;
m_state.ZL = data->report0x30.buttons.ZL;
m_state.lstick_press = data->report0x30.buttons.lstick_press;
m_state.R = data->report0x30.buttons.R;
m_state.ZR = data->report0x30.buttons.ZR;
m_state.rstick_press = data->report0x30.buttons.rstick_press;
m_state.minus = data->report0x30.buttons.minus;
m_state.plus = data->report0x30.buttons.plus;
m_state.capture = data->report0x30.buttons.capture;
m_state.home = data->report0x30.buttons.home;
m_virtual->setState(&m_state);
}
}