|
|
@ -5,10 +5,322 @@ |
|
|
#pragma once |
|
|
#pragma once |
|
|
|
|
|
|
|
|
#include "core/hle/service/service.h" |
|
|
#include "core/hle/service/service.h" |
|
|
|
|
|
#include "core/settings.h" |
|
|
|
|
|
|
|
|
namespace Service { |
|
|
namespace Service { |
|
|
namespace HID { |
|
|
namespace HID { |
|
|
|
|
|
|
|
|
|
|
|
// Begin enums and output structs |
|
|
|
|
|
|
|
|
|
|
|
enum ControllerType : u32 { |
|
|
|
|
|
ControllerType_ProController = 1 << 0, |
|
|
|
|
|
ControllerType_Handheld = 1 << 1, |
|
|
|
|
|
ControllerType_JoyconPair = 1 << 2, |
|
|
|
|
|
ControllerType_JoyconLeft = 1 << 3, |
|
|
|
|
|
ControllerType_JoyconRight = 1 << 4, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum ControllerLayoutType : u32 { |
|
|
|
|
|
Layout_ProController = 0, // Pro Controller or HID gamepad |
|
|
|
|
|
Layout_Handheld = 1, // Two Joy-Con docked to rails |
|
|
|
|
|
Layout_Single = 2, // Horizontal single Joy-Con or pair of Joy-Con, adjusted for orientation |
|
|
|
|
|
Layout_Left = 3, // Only raw left Joy-Con state, no orientation adjustment |
|
|
|
|
|
Layout_Right = 4, // Only raw right Joy-Con state, no orientation adjustment |
|
|
|
|
|
Layout_DefaultDigital = 5, // Same as next, but sticks have 8-direction values only |
|
|
|
|
|
Layout_Default = 6, // Safe default, single Joy-Con have buttons/sticks rotated for orientation |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum ControllerColorDescription { |
|
|
|
|
|
ColorDesc_ColorsNonexistent = 1 << 1, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum ControllerConnectionState { |
|
|
|
|
|
ConnectionState_Connected = 1 << 0, |
|
|
|
|
|
ConnectionState_Wired = 1 << 1, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum ControllerID { |
|
|
|
|
|
Controller_Player1 = 0, |
|
|
|
|
|
Controller_Player2 = 1, |
|
|
|
|
|
Controller_Player3 = 2, |
|
|
|
|
|
Controller_Player4 = 3, |
|
|
|
|
|
Controller_Player5 = 4, |
|
|
|
|
|
Controller_Player6 = 5, |
|
|
|
|
|
Controller_Player7 = 6, |
|
|
|
|
|
Controller_Player8 = 7, |
|
|
|
|
|
Controller_Handheld = 8, |
|
|
|
|
|
Controller_Unknown = 9, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// End enums and output structs |
|
|
|
|
|
|
|
|
|
|
|
// Begin TouchScreen |
|
|
|
|
|
|
|
|
|
|
|
struct TouchScreenHeader { |
|
|
|
|
|
u64 timestampTicks; |
|
|
|
|
|
u64 numEntries; |
|
|
|
|
|
u64 latestEntry; |
|
|
|
|
|
u64 maxEntryIndex; |
|
|
|
|
|
u64 timestamp; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(TouchScreenHeader) == 0x28, |
|
|
|
|
|
"HID touch screen header structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct TouchScreenEntryHeader { |
|
|
|
|
|
u64 timestamp; |
|
|
|
|
|
u64 numTouches; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(TouchScreenEntryHeader) == 0x10, |
|
|
|
|
|
"HID touch screen entry header structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct TouchScreenEntryTouch { |
|
|
|
|
|
u64 timestamp; |
|
|
|
|
|
u32 padding; |
|
|
|
|
|
u32 touchIndex; |
|
|
|
|
|
u32 x; |
|
|
|
|
|
u32 y; |
|
|
|
|
|
u32 diameterX; |
|
|
|
|
|
u32 diameterY; |
|
|
|
|
|
u32 angle; |
|
|
|
|
|
u32 padding_2; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(TouchScreenEntryTouch) == 0x28, |
|
|
|
|
|
"HID touch screen touch structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct TouchScreenEntry { |
|
|
|
|
|
TouchScreenEntryHeader header; |
|
|
|
|
|
std::array<TouchScreenEntryTouch, 16> touches; |
|
|
|
|
|
u64 unk; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(TouchScreenEntry) == 0x298, |
|
|
|
|
|
"HID touch screen entry structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct TouchScreen { |
|
|
|
|
|
TouchScreenHeader header; |
|
|
|
|
|
std::array<TouchScreenEntry, 17> entries; |
|
|
|
|
|
std::array<u8, 0x3c0> padding; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(TouchScreen) == 0x3000, "HID touch screen structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
// End TouchScreen |
|
|
|
|
|
|
|
|
|
|
|
// Begin Mouse |
|
|
|
|
|
|
|
|
|
|
|
struct MouseHeader { |
|
|
|
|
|
u64 timestampTicks; |
|
|
|
|
|
u64 numEntries; |
|
|
|
|
|
u64 latestEntry; |
|
|
|
|
|
u64 maxEntryIndex; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(MouseHeader) == 0x20, "HID mouse header structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct MouseButtonState { |
|
|
|
|
|
union { |
|
|
|
|
|
u64 hex{}; |
|
|
|
|
|
|
|
|
|
|
|
// Buttons |
|
|
|
|
|
BitField<0, 1, u64> left; |
|
|
|
|
|
BitField<1, 1, u64> right; |
|
|
|
|
|
BitField<2, 1, u64> middle; |
|
|
|
|
|
BitField<3, 1, u64> forward; |
|
|
|
|
|
BitField<4, 1, u64> back; |
|
|
|
|
|
}; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct MouseEntry { |
|
|
|
|
|
u64 timestamp; |
|
|
|
|
|
u64 timestamp_2; |
|
|
|
|
|
u32 x; |
|
|
|
|
|
u32 y; |
|
|
|
|
|
u32 velocityX; |
|
|
|
|
|
u32 velocityY; |
|
|
|
|
|
u32 scrollVelocityX; |
|
|
|
|
|
u32 scrollVelocityY; |
|
|
|
|
|
MouseButtonState buttons; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(MouseEntry) == 0x30, "HID mouse entry structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct Mouse { |
|
|
|
|
|
MouseHeader header; |
|
|
|
|
|
std::array<MouseEntry, 17> entries; |
|
|
|
|
|
std::array<u8, 0xB0> padding; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(Mouse) == 0x400, "HID mouse structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
// End Mouse |
|
|
|
|
|
|
|
|
|
|
|
// Begin Keyboard |
|
|
|
|
|
|
|
|
|
|
|
struct KeyboardHeader { |
|
|
|
|
|
u64 timestampTicks; |
|
|
|
|
|
u64 numEntries; |
|
|
|
|
|
u64 latestEntry; |
|
|
|
|
|
u64 maxEntryIndex; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(KeyboardHeader) == 0x20, "HID keyboard header structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct KeyboardModifierKeyState { |
|
|
|
|
|
union { |
|
|
|
|
|
u64 hex{}; |
|
|
|
|
|
|
|
|
|
|
|
// Buttons |
|
|
|
|
|
BitField<0, 1, u64> lctrl; |
|
|
|
|
|
BitField<1, 1, u64> lshift; |
|
|
|
|
|
BitField<2, 1, u64> lalt; |
|
|
|
|
|
BitField<3, 1, u64> lmeta; |
|
|
|
|
|
BitField<4, 1, u64> rctrl; |
|
|
|
|
|
BitField<5, 1, u64> rshift; |
|
|
|
|
|
BitField<6, 1, u64> ralt; |
|
|
|
|
|
BitField<7, 1, u64> rmeta; |
|
|
|
|
|
BitField<8, 1, u64> capslock; |
|
|
|
|
|
BitField<9, 1, u64> scrolllock; |
|
|
|
|
|
BitField<10, 1, u64> numlock; |
|
|
|
|
|
}; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct KeyboardEntry { |
|
|
|
|
|
u64 timestamp; |
|
|
|
|
|
u64 timestamp_2; |
|
|
|
|
|
KeyboardModifierKeyState modifier; |
|
|
|
|
|
u32 keys[8]; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(KeyboardEntry) == 0x38, "HID keyboard entry structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct Keyboard { |
|
|
|
|
|
KeyboardHeader header; |
|
|
|
|
|
std::array<KeyboardEntry, 17> entries; |
|
|
|
|
|
std::array<u8, 0x28> padding; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(Keyboard) == 0x400, "HID keyboard structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
// End Keyboard |
|
|
|
|
|
|
|
|
|
|
|
// Begin Controller |
|
|
|
|
|
|
|
|
|
|
|
struct ControllerMAC { |
|
|
|
|
|
u64 timestamp; |
|
|
|
|
|
std::array<u8, 0x8> mac; |
|
|
|
|
|
u64 unk; |
|
|
|
|
|
u64 timestamp_2; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(ControllerMAC) == 0x20, "HID controller MAC structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct ControllerHeader { |
|
|
|
|
|
u32 type; |
|
|
|
|
|
u32 isHalf; |
|
|
|
|
|
u32 singleColorsDescriptor; |
|
|
|
|
|
u32 singleColorBody; |
|
|
|
|
|
u32 singleColorButtons; |
|
|
|
|
|
u32 splitColorsDescriptor; |
|
|
|
|
|
u32 leftColorBody; |
|
|
|
|
|
u32 leftColorButtons; |
|
|
|
|
|
u32 rightColorBody; |
|
|
|
|
|
u32 rightColorbuttons; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(ControllerHeader) == 0x28, |
|
|
|
|
|
"HID controller header structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct ControllerLayoutHeader { |
|
|
|
|
|
u64 timestampTicks; |
|
|
|
|
|
u64 numEntries; |
|
|
|
|
|
u64 latestEntry; |
|
|
|
|
|
u64 maxEntryIndex; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(ControllerLayoutHeader) == 0x20, |
|
|
|
|
|
"HID controller layout header structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct ControllerPadState { |
|
|
|
|
|
union { |
|
|
|
|
|
u64 hex{}; |
|
|
|
|
|
|
|
|
|
|
|
// Buttons |
|
|
|
|
|
BitField<0, 1, u64> a; |
|
|
|
|
|
BitField<1, 1, u64> b; |
|
|
|
|
|
BitField<2, 1, u64> x; |
|
|
|
|
|
BitField<3, 1, u64> y; |
|
|
|
|
|
BitField<4, 1, u64> lstick; |
|
|
|
|
|
BitField<5, 1, u64> rstick; |
|
|
|
|
|
BitField<6, 1, u64> l; |
|
|
|
|
|
BitField<7, 1, u64> r; |
|
|
|
|
|
BitField<8, 1, u64> zl; |
|
|
|
|
|
BitField<9, 1, u64> zr; |
|
|
|
|
|
BitField<10, 1, u64> plus; |
|
|
|
|
|
BitField<11, 1, u64> minus; |
|
|
|
|
|
|
|
|
|
|
|
// D-pad buttons |
|
|
|
|
|
BitField<12, 1, u64> dleft; |
|
|
|
|
|
BitField<13, 1, u64> dup; |
|
|
|
|
|
BitField<14, 1, u64> dright; |
|
|
|
|
|
BitField<15, 1, u64> ddown; |
|
|
|
|
|
|
|
|
|
|
|
// Left stick directions |
|
|
|
|
|
BitField<16, 1, u64> lstick_left; |
|
|
|
|
|
BitField<17, 1, u64> lstick_up; |
|
|
|
|
|
BitField<18, 1, u64> lstick_right; |
|
|
|
|
|
BitField<19, 1, u64> lstick_down; |
|
|
|
|
|
|
|
|
|
|
|
// Right stick directions |
|
|
|
|
|
BitField<20, 1, u64> rstick_left; |
|
|
|
|
|
BitField<21, 1, u64> rstick_up; |
|
|
|
|
|
BitField<22, 1, u64> rstick_right; |
|
|
|
|
|
BitField<23, 1, u64> rstick_down; |
|
|
|
|
|
|
|
|
|
|
|
BitField<24, 1, u64> sl; |
|
|
|
|
|
BitField<25, 1, u64> sr; |
|
|
|
|
|
}; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct ControllerInputEntry { |
|
|
|
|
|
u64 timestamp; |
|
|
|
|
|
u64 timestamp_2; |
|
|
|
|
|
ControllerPadState buttons; |
|
|
|
|
|
u32 joystickLeftX; |
|
|
|
|
|
u32 joystickLeftY; |
|
|
|
|
|
u32 joystickRightX; |
|
|
|
|
|
u32 joystickRightY; |
|
|
|
|
|
u64 connectionState; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(ControllerInputEntry) == 0x30, |
|
|
|
|
|
"HID controller input entry structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct ControllerLayout { |
|
|
|
|
|
ControllerLayoutHeader header; |
|
|
|
|
|
std::array<ControllerInputEntry, 17> entries; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(ControllerLayout) == 0x350, |
|
|
|
|
|
"HID controller layout structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
struct Controller { |
|
|
|
|
|
ControllerHeader header; |
|
|
|
|
|
std::array<ControllerLayout, 7> layouts; |
|
|
|
|
|
std::array<u8, 0x2a70> unk_1; |
|
|
|
|
|
ControllerMAC macLeft; |
|
|
|
|
|
ControllerMAC macRight; |
|
|
|
|
|
std::array<u8, 0xdf8> unk_2; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(Controller) == 0x5000, "HID controller structure has incorrect size"); |
|
|
|
|
|
|
|
|
|
|
|
// End Controller |
|
|
|
|
|
|
|
|
|
|
|
struct SharedMemory { |
|
|
|
|
|
std::array<u8, 0x400> header; |
|
|
|
|
|
TouchScreen touchscreen; |
|
|
|
|
|
Mouse mouse; |
|
|
|
|
|
Keyboard keyboard; |
|
|
|
|
|
std::array<u8, 0x400> unkSection1; |
|
|
|
|
|
std::array<u8, 0x400> unkSection2; |
|
|
|
|
|
std::array<u8, 0x400> unkSection3; |
|
|
|
|
|
std::array<u8, 0x400> unkSection4; |
|
|
|
|
|
std::array<u8, 0x200> unkSection5; |
|
|
|
|
|
std::array<u8, 0x200> unkSection6; |
|
|
|
|
|
std::array<u8, 0x200> unkSection7; |
|
|
|
|
|
std::array<u8, 0x800> unkSection8; |
|
|
|
|
|
std::array<u8, 0x4000> controllerSerials; |
|
|
|
|
|
std::array<Controller, 10> controllers; |
|
|
|
|
|
std::array<u8, 0x4600> unkSection9; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(SharedMemory) == 0x40000, "HID Shared Memory structure has incorrect size"); |
|
|
|
|
|
|
|
|
/// Reload input devices. Used when input configuration changed |
|
|
/// Reload input devices. Used when input configuration changed |
|
|
void ReloadInputDevices(); |
|
|
void ReloadInputDevices(); |
|
|
|
|
|
|
|
|
|