mirror of
https://github.com/ndeadly/MissionControl
synced 2024-11-22 20:33:07 +00:00
Added Joycon to controller handlers
This commit is contained in:
parent
ed88ff8bb6
commit
ef48b1e7dd
5 changed files with 164 additions and 2 deletions
|
@ -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"
|
||||
|
|
77
sysmodule/include/gamepad/controllers/joycon.hpp
Normal file
77
sysmodule/include/gamepad/controllers/joycon.hpp
Normal 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);
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
namespace mc::controller {
|
||||
|
||||
enum ControllerType {
|
||||
//ControllerType_Joycon,
|
||||
ControllerType_Joycon,
|
||||
ControllerType_SwitchPro,
|
||||
ControllerType_WiiUPro,
|
||||
ControllerType_Wiimote,
|
||||
|
|
|
@ -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;
|
||||
|
|
78
sysmodule/source/gamepad/controllers/joycon.cpp
Normal file
78
sysmodule/source/gamepad/controllers/joycon.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue