mirror of
https://github.com/ndeadly/MissionControl
synced 2024-11-26 06:10:20 +00:00
mc.mitm: misc. code cleanup and style improvements
This commit is contained in:
parent
e68f6035c4
commit
5287296cb3
74 changed files with 2044 additions and 2012 deletions
|
@ -23,7 +23,7 @@ namespace ams::async {
|
|||
const size_t ThreadStackSize = 0x2000;
|
||||
const s32 ThreadPriority = 10;
|
||||
|
||||
alignas(os::MemoryPageSize) uint8_t g_thread_stacks[ThreadCount][ThreadStackSize];
|
||||
alignas(os::MemoryPageSize) u8 g_thread_stacks[ThreadCount][ThreadStackSize];
|
||||
os::ThreadType g_thread_pool[ThreadCount];
|
||||
|
||||
const size_t MessageBufferSize = 32;
|
||||
|
@ -61,7 +61,7 @@ namespace ams::async {
|
|||
os::StartThread(&g_thread_pool[i]);
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace ams::bluetooth::ble {
|
|||
|
||||
os::Event g_init_event(os::EventClearMode_ManualClear);
|
||||
os::Event g_data_read_event(os::EventClearMode_AutoClear);
|
||||
|
||||
}
|
||||
|
||||
bool IsInitialized() {
|
||||
|
@ -64,7 +65,7 @@ namespace ams::bluetooth::ble {
|
|||
|
||||
g_data_read_event.Signal();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void HandleEvent() {
|
||||
|
|
|
@ -52,17 +52,20 @@ namespace ams::bluetooth {
|
|||
u32 readOffset = this->readOffset;
|
||||
u32 writeOffset = this->writeOffset;
|
||||
|
||||
if (!this->isInitialized)
|
||||
if (!this->isInitialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 size;
|
||||
if (readOffset <= writeOffset)
|
||||
if (readOffset <= writeOffset) {
|
||||
size = (BLUETOOTH_BUFFER_SIZE - 1) - writeOffset + readOffset;
|
||||
else
|
||||
} else {
|
||||
size = readOffset - writeOffset - 1;
|
||||
}
|
||||
|
||||
if (size > BLUETOOTH_BUFFER_SIZE)
|
||||
if (size > BLUETOOTH_BUFFER_SIZE) {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -73,8 +76,9 @@ namespace ams::bluetooth {
|
|||
|
||||
u64 CircularBuffer::Write(u8 type, void *data, size_t size) {
|
||||
|
||||
if (!this->isInitialized)
|
||||
if (!this->isInitialized) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::scoped_lock lk(this->mutex);
|
||||
|
||||
|
@ -107,18 +111,21 @@ namespace ams::bluetooth {
|
|||
CircularBufferPacket *packet;
|
||||
TimeSpan timespan;
|
||||
do {
|
||||
if (this->readOffset == this->writeOffset)
|
||||
if (this->readOffset == this->writeOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
packet = reinterpret_cast<CircularBufferPacket *>(&this->data[this->readOffset]);
|
||||
if (packet->header.type != 0xff) {
|
||||
|
||||
if (packet->header.type != type)
|
||||
if (packet->header.type != type) {
|
||||
return;
|
||||
}
|
||||
|
||||
timespan = os::ConvertToTimeSpan(os::GetSystemTick() - packet->header.timestamp);
|
||||
if (timespan.GetMilliSeconds() <= ageLimit)
|
||||
if (timespan.GetMilliSeconds() <= ageLimit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->Free();
|
||||
|
@ -131,17 +138,20 @@ namespace ams::bluetooth {
|
|||
}
|
||||
|
||||
u64 CircularBuffer::Free() {
|
||||
if (!this->isInitialized)
|
||||
if (!this->isInitialized) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this->readOffset == this->writeOffset)
|
||||
if (this->readOffset == this->writeOffset) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto packet = reinterpret_cast<CircularBufferPacket *>(&this->data[this->readOffset]);
|
||||
u32 newOffset = this->readOffset + packet->header.size + sizeof(packet->header);
|
||||
|
||||
if (newOffset >= BLUETOOTH_BUFFER_SIZE)
|
||||
if (newOffset >= BLUETOOTH_BUFFER_SIZE) {
|
||||
newOffset = 0;
|
||||
}
|
||||
|
||||
if (newOffset < BLUETOOTH_BUFFER_SIZE) {
|
||||
this->readOffset = newOffset;
|
||||
|
@ -152,15 +162,17 @@ namespace ams::bluetooth {
|
|||
}
|
||||
|
||||
void CircularBuffer::_setReadOffset(u32 offset) {
|
||||
if (offset >= BLUETOOTH_BUFFER_SIZE)
|
||||
if (offset >= BLUETOOTH_BUFFER_SIZE) {
|
||||
fatalThrow(-1);
|
||||
}
|
||||
|
||||
this->readOffset = offset;
|
||||
}
|
||||
|
||||
void CircularBuffer::_setWriteOffset(u32 offset) {
|
||||
if (offset >= BLUETOOTH_BUFFER_SIZE)
|
||||
if (offset >= BLUETOOTH_BUFFER_SIZE) {
|
||||
fatalThrow(-1);
|
||||
}
|
||||
|
||||
this->writeOffset = offset;
|
||||
}
|
||||
|
@ -180,20 +192,23 @@ namespace ams::bluetooth {
|
|||
packet->header.size = size;
|
||||
|
||||
if (type != 0xff) {
|
||||
if (data && (size > 0))
|
||||
if (data && (size > 0)) {
|
||||
memcpy(&packet->data, data, size);
|
||||
else
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
u32 newOffset = this->writeOffset + size + sizeof(CircularBufferPacketHeader);
|
||||
if (newOffset > BLUETOOTH_BUFFER_SIZE)
|
||||
if (newOffset > BLUETOOTH_BUFFER_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (newOffset == BLUETOOTH_BUFFER_SIZE)
|
||||
if (newOffset == BLUETOOTH_BUFFER_SIZE) {
|
||||
this->writeOffset = 0;
|
||||
else
|
||||
} else {
|
||||
this->writeOffset = newOffset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -201,8 +216,9 @@ namespace ams::bluetooth {
|
|||
void CircularBuffer::_updateUtilization() {
|
||||
u32 newCapacity = this->isInitialized ? this->GetWriteableSize() : 0;
|
||||
|
||||
if (this->size > newCapacity + 1000)
|
||||
if (this->size > newCapacity + 1000) {
|
||||
this->size = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
CircularBufferPacket *CircularBuffer::_read() {
|
||||
|
@ -210,21 +226,25 @@ namespace ams::bluetooth {
|
|||
CircularBufferPacket *packet;
|
||||
u32 newOffset;
|
||||
do {
|
||||
if (this->readOffset == this->writeOffset)
|
||||
if (this->readOffset == this->writeOffset) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
packet = reinterpret_cast<CircularBufferPacket *>(&this->data[this->readOffset]);
|
||||
|
||||
if (packet->header.type != 0xff)
|
||||
if (packet->header.type != 0xff) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
if (!this->isInitialized)
|
||||
if (!this->isInitialized) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (this->readOffset != this->writeOffset) {
|
||||
newOffset = this->readOffset + packet->header.size + sizeof(packet->header);
|
||||
if (newOffset >= BLUETOOTH_BUFFER_SIZE)
|
||||
if (newOffset >= BLUETOOTH_BUFFER_SIZE) {
|
||||
newOffset = 0;
|
||||
}
|
||||
|
||||
this->_setReadOffset(newOffset);
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ namespace ams::bluetooth {
|
|||
};
|
||||
|
||||
struct CircularBufferPacketHeader{
|
||||
u8 type;
|
||||
u8 type;
|
||||
os::Tick timestamp;
|
||||
u64 size;
|
||||
u64 size;
|
||||
};
|
||||
|
||||
struct CircularBufferPacket{
|
||||
|
@ -70,14 +70,14 @@ namespace ams::bluetooth {
|
|||
os::SdkMutex mutex;
|
||||
os::EventType *event;
|
||||
|
||||
u8 data[BLUETOOTH_BUFFER_SIZE];
|
||||
u32 writeOffset;
|
||||
u32 readOffset;
|
||||
s64 size;
|
||||
u8 data[BLUETOOTH_BUFFER_SIZE];
|
||||
u32 writeOffset;
|
||||
u32 readOffset;
|
||||
s64 size;
|
||||
char name[16];
|
||||
u8 _unk1;
|
||||
u8 _unk1;
|
||||
bool isInitialized;
|
||||
u8 _unk2[6];
|
||||
u8 _unk2[6];
|
||||
|
||||
public:
|
||||
CircularBufferType type;
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace ams::bluetooth::core {
|
|||
os::Event g_data_read_event(os::EventClearMode_AutoClear);
|
||||
|
||||
bluetooth::Address ReverseBluetoothAddress(bluetooth::Address address) {
|
||||
uint64_t tmp;
|
||||
u64 tmp;
|
||||
std::memcpy(&tmp, &address, sizeof(address));
|
||||
tmp = util::SwapEndian(tmp) >> 16;
|
||||
return *reinterpret_cast<bluetooth::Address *>(&tmp);
|
||||
|
@ -134,21 +134,22 @@ namespace ams::bluetooth::core {
|
|||
if (program_id == ncm::SystemProgramId::Btm) {
|
||||
auto event_info = reinterpret_cast<bluetooth::EventInfo *>(buffer);
|
||||
|
||||
if (hos::GetVersion() < hos::Version_12_0_0)
|
||||
if (hos::GetVersion() < hos::Version_12_0_0) {
|
||||
ModifyEventInfov1(event_info, g_current_event_type);
|
||||
else
|
||||
} else {
|
||||
ModifyEventInfov12(event_info, g_current_event_type);
|
||||
}
|
||||
}
|
||||
|
||||
g_data_read_event.Signal();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
inline void HandlePinCodeRequestEventV1(bluetooth::EventInfo *event_info) {
|
||||
// Default pin used by bluetooth service
|
||||
bluetooth::PinCode pin = {"0000"};
|
||||
uint8_t pin_length = std::strlen(pin.code);
|
||||
u8 pin_length = std::strlen(pin.code);
|
||||
|
||||
// Reverse host address as pin code for wii devices
|
||||
if (std::strncmp(event_info->pairing_pin_code_request.name, controller::wii_controller_prefix, std::strlen(controller::wii_controller_prefix)) == 0) {
|
||||
|
@ -193,11 +194,9 @@ namespace ams::bluetooth::core {
|
|||
if (!g_redirect_core_events) {
|
||||
if ((hos::GetVersion() < hos::Version_12_0_0) && (g_current_event_type == BtdrvEventTypeOld_PairingPinCodeRequest)) {
|
||||
HandlePinCodeRequestEventV1(&g_event_info);
|
||||
}
|
||||
else if ((hos::GetVersion() >= hos::Version_12_0_0) && (g_current_event_type == BtdrvEventType_PairingPinCodeRequest)) {
|
||||
} else if ((hos::GetVersion() >= hos::Version_12_0_0) && (g_current_event_type == BtdrvEventType_PairingPinCodeRequest)) {
|
||||
HandlePinCodeRequestEventV12(&g_event_info);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_system_event_fwd.Signal();
|
||||
g_data_read_event.Wait();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ams::bluetooth::events {
|
|||
|
||||
const s32 ThreadPriority = 9;
|
||||
const size_t ThreadStackSize = 0x2000;
|
||||
alignas(os::ThreadStackAlignment) uint8_t g_thread_stack[ThreadStackSize];
|
||||
alignas(os::ThreadStackAlignment) u8 g_thread_stack[ThreadStackSize];
|
||||
os::ThreadType g_thread;
|
||||
|
||||
os::MultiWaitType g_manager;
|
||||
|
@ -88,7 +88,7 @@ namespace ams::bluetooth::events {
|
|||
os::SetThreadNamePointer(&g_thread, "mc::EventThread");
|
||||
os::StartThread(&g_thread);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace ams::bluetooth::hid {
|
|||
|
||||
g_data_read_event.Signal();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
inline void HandleConnectionStateEventV1(bluetooth::HidEventInfo *event_info) {
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace ams::bluetooth::hid::report {
|
|||
|
||||
const s32 ThreadPriority = -11;
|
||||
const size_t ThreadStackSize = 0x1000;
|
||||
alignas(os::ThreadStackAlignment) uint8_t g_thread_stack[ThreadStackSize];
|
||||
alignas(os::ThreadStackAlignment) u8 g_thread_stack[ThreadStackSize];
|
||||
os::ThreadType g_thread;
|
||||
|
||||
// This is only required on fw < 7.0.0
|
||||
|
@ -77,8 +77,9 @@ namespace ams::bluetooth::hid::report {
|
|||
}
|
||||
|
||||
os::SharedMemory *GetRealSharedMemory() {
|
||||
if (hos::GetVersion() < hos::Version_7_0_0)
|
||||
if (hos::GetVersion() < hos::Version_7_0_0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &g_real_bt_shmem;
|
||||
}
|
||||
|
@ -111,7 +112,7 @@ namespace ams::bluetooth::hid::report {
|
|||
os::SetThreadNamePointer(&g_thread, "mc::HidReportThread");
|
||||
os::StartThread(&g_thread);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
|
@ -123,7 +124,7 @@ namespace ams::bluetooth::hid::report {
|
|||
g_real_bt_shmem.Map(os::MemoryPermission_ReadWrite);
|
||||
g_real_buffer = reinterpret_cast<bluetooth::CircularBuffer *>(g_real_bt_shmem.GetMappedAddress());
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InitializeReportBuffer() {
|
||||
|
@ -133,15 +134,14 @@ namespace ams::bluetooth::hid::report {
|
|||
g_fake_buffer->type = bluetooth::CircularBufferType_HidReport;
|
||||
g_fake_buffer->_unk3 = 1;
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WriteHidDataReport(const bluetooth::Address address, const bluetooth::HidReport *report) {
|
||||
if (hos::GetVersion() >= hos::Version_9_0_0) {
|
||||
g_fake_report_event_info.data_report.v9.addr = address;
|
||||
std::memcpy(&g_fake_report_event_info.data_report.v9.report, report, report->size + sizeof(report->size));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Todo: check this may still be necessary
|
||||
//g_fake_report_event_info.data_report.v7.size = g_fake_report_event_info.data_report.v7.report.size + 0x11;
|
||||
g_fake_report_event_info.data_report.v7.addr = address;
|
||||
|
@ -151,17 +151,17 @@ namespace ams::bluetooth::hid::report {
|
|||
g_fake_buffer->Write(hos::GetVersion() >= hos::Version_12_0_0 ? BtdrvHidEventType_Data : BtdrvHidEventTypeOld_Data, &g_fake_report_event_info, report->size + 0x11);
|
||||
g_system_event_fwd.Signal();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WriteHidSetReport(const bluetooth::Address address, uint32_t status) {
|
||||
Result WriteHidSetReport(const bluetooth::Address address, u32 status) {
|
||||
g_fake_report_event_info.set_report.addr = address;
|
||||
g_fake_report_event_info.set_report.res = status;
|
||||
|
||||
g_fake_buffer->Write(hos::GetVersion() >= hos::Version_12_0_0 ? BtdrvHidEventType_Data : BtdrvHidEventTypeOld_Data, &g_fake_report_event_info, sizeof(g_fake_report_event_info.set_report));
|
||||
g_system_event_fwd.Signal();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WriteHidGetReport(const bluetooth::Address address, const bluetooth::HidReport *report) {
|
||||
|
@ -169,8 +169,7 @@ namespace ams::bluetooth::hid::report {
|
|||
g_fake_report_event_info.get_report.v9.addr = address;
|
||||
g_fake_report_event_info.get_report.v9.res = 0;
|
||||
std::memcpy(&g_fake_report_event_info.get_report.v9.report, report, report->size + sizeof(report->size));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
g_fake_report_event_info.get_report.v1.addr = address;
|
||||
g_fake_report_event_info.get_report.v1.res = 0;
|
||||
std::memcpy(&g_fake_report_event_info.get_report.v1.report, report, report->size + sizeof(report->size));
|
||||
|
@ -179,7 +178,7 @@ namespace ams::bluetooth::hid::report {
|
|||
g_fake_buffer->Write(hos::GetVersion() >= hos::Version_12_0_0 ? BtdrvHidEventType_GetReport : BtdrvHidEventTypeOld_GetReport, &g_fake_report_event_info, report->size + 0x11);
|
||||
g_system_event_fwd.Signal();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Only used for < 7.0.0. Newer firmwares read straight from shared memory */
|
||||
|
@ -188,8 +187,9 @@ namespace ams::bluetooth::hid::report {
|
|||
|
||||
while (true) {
|
||||
auto packet = g_fake_buffer->Read();
|
||||
if (!packet)
|
||||
if (!packet) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_fake_buffer->Free();
|
||||
|
||||
|
@ -220,7 +220,7 @@ namespace ams::bluetooth::hid::report {
|
|||
}
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
inline void HandleHidReportEventV1() {
|
||||
|
@ -259,8 +259,9 @@ namespace ams::bluetooth::hid::report {
|
|||
inline void HandleHidReportEventV7() {
|
||||
while (true) {
|
||||
auto real_packet = g_real_buffer->Read();
|
||||
if (!real_packet)
|
||||
if (!real_packet) {
|
||||
break;
|
||||
}
|
||||
|
||||
g_real_buffer->Free();
|
||||
|
||||
|
@ -300,8 +301,9 @@ namespace ams::bluetooth::hid::report {
|
|||
inline void HandleHidReportEventV12() {
|
||||
while (true) {
|
||||
auto real_packet = g_real_buffer->Read();
|
||||
if (!real_packet)
|
||||
if (!real_packet) {
|
||||
break;
|
||||
}
|
||||
|
||||
g_real_buffer->Free();
|
||||
|
||||
|
@ -344,12 +346,13 @@ namespace ams::bluetooth::hid::report {
|
|||
g_report_read_event.Wait();
|
||||
}
|
||||
|
||||
if (hos::GetVersion() >= hos::Version_12_0_0)
|
||||
if (hos::GetVersion() >= hos::Version_12_0_0) {
|
||||
HandleHidReportEventV12();
|
||||
else if (hos::GetVersion() >= hos::Version_7_0_0)
|
||||
} else if (hos::GetVersion() >= hos::Version_7_0_0) {
|
||||
HandleHidReportEventV7();
|
||||
else
|
||||
} else {
|
||||
HandleHidReportEventV1();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace ams::bluetooth::hid::report {
|
|||
Result InitializeReportBuffer();
|
||||
|
||||
Result WriteHidDataReport(const bluetooth::Address address, const bluetooth::HidReport *report);
|
||||
Result WriteHidSetReport(const bluetooth::Address address, uint32_t status);
|
||||
Result WriteHidSetReport(const bluetooth::Address address, u32 status);
|
||||
Result WriteHidGetReport(const bluetooth::Address address, const bluetooth::HidReport *report);
|
||||
|
||||
Result GetEventInfo(bluetooth::HidEventType *type, void *buffer, size_t size);
|
||||
|
|
|
@ -19,23 +19,23 @@
|
|||
|
||||
namespace ams::bluetooth {
|
||||
|
||||
typedef BtdrvAddress Address;
|
||||
typedef BtdrvClassOfDevice DeviceClass;
|
||||
typedef BtdrvBluetoothPinCode PinCode;
|
||||
typedef BtdrvAdapterProperty AdapterProperty;
|
||||
typedef BtdrvHidReport HidReport;
|
||||
typedef BtdrvBluetoothHhReportType HhReportType;
|
||||
typedef SetSysBluetoothDevicesSettings DevicesSettings;
|
||||
using Address = ::BtdrvAddress;
|
||||
using DeviceClass = ::BtdrvClassOfDevice;
|
||||
using PinCode = ::BtdrvBluetoothPinCode;
|
||||
using AdapterProperty = ::BtdrvAdapterProperty;
|
||||
using HidReport = ::BtdrvHidReport;
|
||||
using HhReportType = ::BtdrvBluetoothHhReportType;
|
||||
using DevicesSettings = ::SetSysBluetoothDevicesSettings;
|
||||
|
||||
typedef BtdrvEventType EventType;
|
||||
typedef BtdrvEventInfo EventInfo;
|
||||
using EventType = ::BtdrvEventType;
|
||||
using EventInfo = ::BtdrvEventInfo;
|
||||
|
||||
typedef BtdrvHidEventType HidEventType;
|
||||
typedef BtdrvHidEventInfo HidEventInfo;
|
||||
using HidEventType = ::BtdrvHidEventType;
|
||||
using HidEventInfo = ::BtdrvHidEventInfo;
|
||||
|
||||
typedef BtdrvBleEventType BleEventType;
|
||||
typedef BtdrvBleEventInfo BleEventInfo;
|
||||
using BleEventType = ::BtdrvBleEventType;
|
||||
using BleEventInfo = ::BtdrvBleEventInfo;
|
||||
|
||||
typedef BtdrvHidReportEventInfo HidReportEventInfo;
|
||||
using HidReportEventInfo = ::BtdrvHidReportEventInfo;
|
||||
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace ams::mitm::bluetooth {
|
|||
os::SetThreadNamePointer(&g_thread, "mc::BtdrvMitmThread");
|
||||
os::StartThread(&g_thread);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void WaitFinished() {
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace ams::mitm::bluetooth {
|
|||
out_handle.SetValue(ams::bluetooth::core::GetUserForwardEvent()->GetReadableHandle(), false);
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::EnableBluetooth() {
|
||||
|
@ -56,11 +56,11 @@ namespace ams::mitm::bluetooth {
|
|||
// Wait until mc.mitm module initialisation has completed before returning
|
||||
ams::mitm::WaitInitialized();
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::GetEventInfo(sf::Out<ams::bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
return ams::bluetooth::core::GetEventInfo(m_client_info.program_id, out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize());
|
||||
R_RETURN(ams::bluetooth::core::GetEventInfo(m_client_info.program_id, out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize()));
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::InitializeHid(sf::OutCopyHandle out_handle, u16 version) {
|
||||
|
@ -77,12 +77,11 @@ namespace ams::mitm::bluetooth {
|
|||
|
||||
// Signal that the interface is initialised
|
||||
ams::bluetooth::hid::SignalInitialized();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
out_handle.SetValue(ams::bluetooth::hid::GetUserForwardEvent()->GetReadableHandle(), false);
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::WriteHidData(ams::bluetooth::Address address, const sf::InPointerBuffer &buffer) {
|
||||
|
@ -92,12 +91,11 @@ namespace ams::mitm::bluetooth {
|
|||
if (device) {
|
||||
device->HandleOutputDataReport(report);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
R_TRY(btdrvWriteHidDataFwd(m_forward_service.get(), &address, report));
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::WriteHidData2(ams::bluetooth::Address address, const sf::InPointerBuffer &buffer) {
|
||||
|
@ -115,53 +113,46 @@ namespace ams::mitm::bluetooth {
|
|||
}
|
||||
|
||||
Result BtdrvMitmService::GetHidEventInfo(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
return ams::bluetooth::hid::GetEventInfo(out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize());
|
||||
R_RETURN(ams::bluetooth::hid::GetEventInfo(out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize()));
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::SetTsi(ams::bluetooth::Address address, u8 tsi) {
|
||||
auto device = controller::LocateHandler(&address);
|
||||
if (!device || device->SupportsSetTsiCommand())
|
||||
if (!device || device->SupportsSetTsiCommand()) {
|
||||
return sm::mitm::ResultShouldForwardToSession();
|
||||
}
|
||||
|
||||
if (hos::GetVersion() < hos::Version_9_0_0) {
|
||||
const struct {
|
||||
uint32_t type;
|
||||
u32 type;
|
||||
ams::bluetooth::Address address;
|
||||
uint8_t pad[2];
|
||||
uint32_t status;
|
||||
u8 pad[2];
|
||||
u32 status;
|
||||
} event_data = {tsi == 0xff ? 1u : 0u, address, {0, 0}, 0};
|
||||
|
||||
ams::bluetooth::hid::SignalFakeEvent(BtdrvHidEventTypeOld_Ext, &event_data, sizeof(event_data));
|
||||
}
|
||||
else if (hos::GetVersion() < hos::Version_12_0_0) {
|
||||
} else if (hos::GetVersion() < hos::Version_12_0_0) {
|
||||
const struct {
|
||||
uint32_t type;
|
||||
uint32_t status;
|
||||
u32 type;
|
||||
u32 status;
|
||||
ams::bluetooth::Address address;
|
||||
uint8_t pad[2];
|
||||
u8 pad[2];
|
||||
} event_data = {tsi == 0xff ? 1u : 0u, 0, address, {0, 0}};
|
||||
|
||||
ams::bluetooth::hid::SignalFakeEvent(BtdrvHidEventTypeOld_Ext, &event_data, sizeof(event_data));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
const struct {
|
||||
ams::bluetooth::Address address;
|
||||
uint8_t flag;
|
||||
uint8_t tsi;
|
||||
u8 flag;
|
||||
u8 tsi;
|
||||
} event_data = { address, 1, tsi };
|
||||
|
||||
ams::bluetooth::core::SignalFakeEvent(BtdrvEventType_Tsi, &event_data, sizeof(event_data));
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* 1.0.0 - 3.0.2 */
|
||||
Result BtdrvMitmService::RegisterHidReportEventDeprecated(sf::OutCopyHandle out_handle) {
|
||||
return RegisterHidReportEvent(out_handle);
|
||||
}
|
||||
|
||||
/* 4.0.0+ */
|
||||
Result BtdrvMitmService::RegisterHidReportEvent(sf::OutCopyHandle out_handle) {
|
||||
if (!ams::bluetooth::hid::report::IsInitialized()) {
|
||||
// Forward to the real function to obtain the system event handle
|
||||
|
@ -176,39 +167,20 @@ namespace ams::mitm::bluetooth {
|
|||
|
||||
// Signal that the interface is initialised
|
||||
ams::bluetooth::hid::report::SignalInitialized();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
out_handle.SetValue(ams::bluetooth::hid::report::GetUserForwardEvent()->GetReadableHandle(), false);
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* 1.0.0 - 6.2.0 */
|
||||
Result _GetHidReportEventInfoDeprecated(Service *srv, sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
AMS_UNUSED(srv);
|
||||
|
||||
return ams::bluetooth::hid::report::GetEventInfo(out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize());
|
||||
}
|
||||
|
||||
/* 1.0.0 - 3.0.2 */
|
||||
Result BtdrvMitmService::GetHidReportEventInfoDeprecated1(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
return _GetHidReportEventInfoDeprecated(m_forward_service.get(), out_type, out_buffer);
|
||||
}
|
||||
|
||||
/* 4.0.0 - 6.2.0 */
|
||||
Result BtdrvMitmService::GetHidReportEventInfoDeprecated2(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
return _GetHidReportEventInfoDeprecated(m_forward_service.get(), out_type, out_buffer);
|
||||
}
|
||||
|
||||
/* 7.0.0+ */
|
||||
Result BtdrvMitmService::GetHidReportEventInfo(sf::OutCopyHandle out_handle) {
|
||||
os::NativeHandle handle = os::InvalidNativeHandle;
|
||||
R_TRY(btdrvGetHidReportEventInfoFwd(m_forward_service.get(), &handle));
|
||||
R_TRY(ams::bluetooth::hid::report::MapRemoteSharedMemory(handle));
|
||||
out_handle.SetValue(ams::bluetooth::hid::report::GetFakeSharedMemory()->GetHandle(), false);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::InitializeBle(sf::OutCopyHandle out_handle) {
|
||||
|
@ -225,30 +197,54 @@ namespace ams::mitm::bluetooth {
|
|||
|
||||
// Signal that the interface is initialised
|
||||
ams::bluetooth::ble::SignalInitialized();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
out_handle.SetValue(ams::bluetooth::ble::GetUserForwardEvent()->GetReadableHandle(), false);
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::GetBleManagedEventInfoDeprecated(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
return GetBleManagedEventInfo(out_type, out_buffer);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::GetBleManagedEventInfo(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
return ams::bluetooth::ble::GetEventInfo(out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize());
|
||||
R_RETURN(ams::bluetooth::ble::GetEventInfo(out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize()));
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
|
||||
/* 1.0.0 - 3.0.2 */
|
||||
Result BtdrvMitmService::RegisterHidReportEventDeprecated(sf::OutCopyHandle out_handle) {
|
||||
R_RETURN(this->RegisterHidReportEvent(out_handle));
|
||||
}
|
||||
|
||||
/* 1.0.0 - 6.2.0 */
|
||||
Result _GetHidReportEventInfoDeprecated(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
R_RETURN(ams::bluetooth::hid::report::GetEventInfo(out_type.GetPointer(), out_buffer.GetPointer(), out_buffer.GetSize()));
|
||||
}
|
||||
|
||||
/* 1.0.0 - 3.0.2 */
|
||||
Result BtdrvMitmService::GetHidReportEventInfoDeprecated1(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
R_RETURN(_GetHidReportEventInfoDeprecated(out_type, out_buffer));
|
||||
}
|
||||
|
||||
/* 4.0.0 - 6.2.0 */
|
||||
Result BtdrvMitmService::GetHidReportEventInfoDeprecated2(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
R_RETURN(_GetHidReportEventInfoDeprecated(out_type, out_buffer));
|
||||
}
|
||||
|
||||
/* 5.0.0 - 5.0.2 */
|
||||
Result BtdrvMitmService::GetBleManagedEventInfoDeprecated(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer) {
|
||||
R_RETURN(this->GetBleManagedEventInfo(out_type, out_buffer));
|
||||
}
|
||||
|
||||
/* Extensions */
|
||||
|
||||
Result BtdrvMitmService::GetRealSharedMemory(sf::OutCopyHandle out_handle) {
|
||||
out_handle.SetValue(ams::bluetooth::hid::report::GetRealSharedMemory()->GetHandle(), false);
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtdrvMitmService::GetFakeSharedMemory(sf::OutCopyHandle out_handle) {
|
||||
out_handle.SetValue(ams::bluetooth::hid::report::GetFakeSharedMemory()->GetHandle(), false);
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void BtdrvMitmService::RedirectCoreEvents(bool redirect) {
|
||||
|
|
|
@ -19,28 +19,28 @@
|
|||
|
||||
#define AMS_BTDRV_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, InitializeBluetooth, (sf::OutCopyHandle out_handle), (out_handle)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, EnableBluetooth, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, EnableBluetooth, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 15, Result, GetEventInfo, (sf::Out<ams::bluetooth::EventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 16, Result, InitializeHid, (sf::OutCopyHandle out_handle, u16 version), (out_handle, version)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 19, Result, WriteHidData, (ams::bluetooth::Address address, const sf::InPointerBuffer &buffer), (address, buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, WriteHidData2, (ams::bluetooth::Address address, const sf::InPointerBuffer &buffer), (address, buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 27, Result, GetHidEventInfo, (sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 28, Result, SetTsi, (ams::bluetooth::Address address, u8 tsi), (address, tsi)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 36, Result, RegisterHidReportEventDeprecated, (sf::OutCopyHandle out_handle), (out_handle), hos::Version_1_0_0, hos::Version_3_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 37, Result, RegisterHidReportEvent, (sf::OutCopyHandle out_handle), (out_handle), hos::Version_4_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 37, Result, GetHidReportEventInfoDeprecated1, (sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer), hos::Version_1_0_0, hos::Version_3_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 38, Result, GetHidReportEventInfoDeprecated2, (sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer), hos::Version_4_0_0, hos::Version_6_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 38, Result, GetHidReportEventInfo, (sf::OutCopyHandle out_handle), (out_handle), hos::Version_7_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 46, Result, InitializeBle, (sf::OutCopyHandle out_handle), (out_handle), hos::Version_5_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 78, Result, GetBleManagedEventInfoDeprecated, (sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer), hos::Version_5_0_0, hos::Version_5_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 79, Result, GetBleManagedEventInfo, (sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer), hos::Version_5_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 36, Result, RegisterHidReportEventDeprecated, (sf::OutCopyHandle out_handle), (out_handle), hos::Version_1_0_0, hos::Version_3_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 37, Result, GetHidReportEventInfoDeprecated1, (sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer), hos::Version_1_0_0, hos::Version_3_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 38, Result, GetHidReportEventInfoDeprecated2, (sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer), hos::Version_4_0_0, hos::Version_6_2_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 78, Result, GetBleManagedEventInfoDeprecated, (sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer), (out_type, out_buffer), hos::Version_5_0_0, hos::Version_5_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65000, Result, GetRealSharedMemory, (sf::OutCopyHandle out_handle), (out_handle), hos::Version_7_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65001, Result, GetFakeSharedMemory, (sf::OutCopyHandle out_handle), (out_handle)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65002, void, RedirectCoreEvents, (bool redirect), (redirect)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65003, void, RedirectHidEvents, (bool redirect), (redirect)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65004, void, RedirectHidReportEvents, (bool redirect), (redirect)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65005, void, RedirectBleEvents, (bool redirect), (redirect)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65006, void, SignalHidReportRead, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65006, void, SignalHidReportRead, (), ()) \
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(ams::mitm::bluetooth, IBtdrvMitmInterface, AMS_BTDRV_MITM_INTERFACE_INFO, 0xAACFC9A7)
|
||||
|
||||
|
@ -66,16 +66,18 @@ namespace ams::mitm::bluetooth {
|
|||
Result WriteHidData2(ams::bluetooth::Address address, const sf::InPointerBuffer &buffer);
|
||||
Result GetHidEventInfo(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
Result SetTsi(ams::bluetooth::Address address, u8 tsi);
|
||||
Result RegisterHidReportEventDeprecated(sf::OutCopyHandle out_handle);
|
||||
Result RegisterHidReportEvent(sf::OutCopyHandle out_handle);
|
||||
Result GetHidReportEventInfoDeprecated1(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
Result GetHidReportEventInfoDeprecated2(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
Result GetHidReportEventInfo(sf::OutCopyHandle out_handle);
|
||||
/* 5.0.0+ */
|
||||
Result InitializeBle(sf::OutCopyHandle out_handle);
|
||||
Result GetBleManagedEventInfoDeprecated(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
Result GetBleManagedEventInfo(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
|
||||
/* Deprecated */
|
||||
Result RegisterHidReportEventDeprecated(sf::OutCopyHandle out_handle);
|
||||
Result GetHidReportEventInfoDeprecated1(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
Result GetHidReportEventInfoDeprecated2(sf::Out<ams::bluetooth::HidEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
Result GetBleManagedEventInfoDeprecated(sf::Out<ams::bluetooth::BleEventType> out_type, const sf::OutPointerBuffer &out_buffer);
|
||||
|
||||
/* Extensions */
|
||||
Result GetRealSharedMemory(sf::OutCopyHandle out_handle);
|
||||
Result GetFakeSharedMemory(sf::OutCopyHandle out_handle);
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
namespace ams::btm {
|
||||
|
||||
using Profile = ::BtmProfile;
|
||||
|
||||
struct DeviceConditionV100 : public sf::LargeData {
|
||||
BtmDeviceConditionV100 condition;
|
||||
};
|
||||
|
|
|
@ -32,37 +32,9 @@ namespace ams::mitm::btm {
|
|||
|
||||
}
|
||||
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated1(sf::Out<ams::btm::DeviceConditionV100> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV100 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated1Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated2(sf::Out<ams::btm::DeviceConditionV510> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV510 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated2Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated3(sf::Out<ams::btm::DeviceConditionV800> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV800 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated3Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated4(sf::Out<ams::btm::DeviceConditionV900> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV900 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated4Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtmMitmService::GetDeviceCondition(u32 id, const sf::OutArray<ams::btm::ConnectedDevice> &out, sf::Out<s32> total_out) {
|
||||
Result BtmMitmService::GetDeviceCondition(ams::btm::Profile profile, const sf::OutArray<ams::btm::ConnectedDevice> &out, sf::Out<s32> total_out) {
|
||||
auto device_condition = reinterpret_cast<BtmConnectedDeviceV13 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionFwd(m_forward_service.get(), id, device_condition, out.GetSize(), total_out.GetPointer()));
|
||||
R_TRY(btmGetDeviceConditionFwd(m_forward_service.get(), profile, device_condition, out.GetSize(), total_out.GetPointer()));
|
||||
|
||||
for (int i = 0; i < total_out.GetValue(); ++i) {
|
||||
auto device = &device_condition[i];
|
||||
|
@ -71,9 +43,62 @@ namespace ams::mitm::btm {
|
|||
}
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result BtmMitmService::GetDeviceInfo(ams::btm::Profile profile, const sf::OutArray<ams::btm::DeviceInfo> &out, sf::Out<s32> total_out) {
|
||||
auto device_info = reinterpret_cast<BtmDeviceInfoV13 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceInfoFwd(m_forward_service.get(), profile, device_info, out.GetSize(), total_out.GetPointer()));
|
||||
|
||||
for (int i = 0; i < total_out.GetValue(); ++i) {
|
||||
auto device = &device_info[i];
|
||||
if (!controller::IsOfficialSwitchControllerName(device->name)) {
|
||||
std::strncpy(device->name, controller::pro_controller_name, sizeof(device->name) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
|
||||
/* 1.0.0 - 5.0.2 */
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated1(sf::Out<ams::btm::DeviceConditionV100> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV100 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated1Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* 5.1.0 - 7.0.1 */
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated2(sf::Out<ams::btm::DeviceConditionV510> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV510 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated2Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* 8.0.0 - 8.1.1 */
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated3(sf::Out<ams::btm::DeviceConditionV800> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV800 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated3Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* 9.0.0 - 12.1.0 */
|
||||
Result BtmMitmService::GetDeviceConditionDeprecated4(sf::Out<ams::btm::DeviceConditionV900> out) {
|
||||
auto device_condition = reinterpret_cast<BtmDeviceConditionV900 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceConditionDeprecated4Fwd(m_forward_service.get(), device_condition));
|
||||
RenameConnectedDevices(device_condition->devices, device_condition->connected_count);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* 1.0.0 - 12.1.0 */
|
||||
Result BtmMitmService::GetDeviceInfoDeprecated(sf::Out<ams::btm::DeviceInfoList> out) {
|
||||
auto device_info = reinterpret_cast<BtmDeviceInfoList *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceInfoDeprecatedFwd(m_forward_service.get(), device_info));
|
||||
|
@ -85,21 +110,7 @@ namespace ams::mitm::btm {
|
|||
}
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
Result BtmMitmService::GetDeviceInfo(u32 id, const sf::OutArray<ams::btm::DeviceInfo> &out, sf::Out<s32> total_out) {
|
||||
auto device_info = reinterpret_cast<BtmDeviceInfoV13 *>(out.GetPointer());
|
||||
R_TRY(btmGetDeviceInfoFwd(m_forward_service.get(), id, device_info, out.GetSize(), total_out.GetPointer()));
|
||||
|
||||
for (int i = 0; i < total_out.GetValue(); ++i) {
|
||||
auto device = &device_info[i];
|
||||
if (!controller::IsOfficialSwitchControllerName(device->name)) {
|
||||
std::strncpy(device->name, controller::pro_controller_name, sizeof(device->name) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
#include <stratosphere.hpp>
|
||||
#include "btm/btm_types.hpp"
|
||||
|
||||
#define AMS_BTM_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated1, (sf::Out<ams::btm::DeviceConditionV100> out), (out), hos::Version_1_0_0, hos::Version_5_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated2, (sf::Out<ams::btm::DeviceConditionV510> out), (out), hos::Version_5_1_0, hos::Version_7_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated3, (sf::Out<ams::btm::DeviceConditionV800> out), (out), hos::Version_8_0_0, hos::Version_8_1_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated4, (sf::Out<ams::btm::DeviceConditionV900> out), (out), hos::Version_9_0_0, hos::Version_12_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceCondition, (u32 id, const sf::OutArray<ams::btm::ConnectedDevice> &out, sf::Out<s32> total_out), (id, out, total_out), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, GetDeviceInfoDeprecated, (sf::Out<ams::btm::DeviceInfoList> out), (out), hos::Version_1_0_0, hos::Version_12_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, GetDeviceInfo, (u32 id, const sf::OutArray<ams::btm::DeviceInfo> &out, sf::Out<s32> total_out), (id, out, total_out), hos::Version_13_0_0) \
|
||||
#define AMS_BTM_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceCondition, (ams::btm::Profile profile, const sf::OutArray<ams::btm::ConnectedDevice> &out, sf::Out<s32> total_out), (profile, out, total_out), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, GetDeviceInfo, (ams::btm::Profile profile, const sf::OutArray<ams::btm::DeviceInfo> &out, sf::Out<s32> total_out), (profile, out, total_out), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated1, (sf::Out<ams::btm::DeviceConditionV100> out), (out), hos::Version_1_0_0, hos::Version_5_0_2) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated2, (sf::Out<ams::btm::DeviceConditionV510> out), (out), hos::Version_5_1_0, hos::Version_7_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated3, (sf::Out<ams::btm::DeviceConditionV800> out), (out), hos::Version_8_0_0, hos::Version_8_1_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetDeviceConditionDeprecated4, (sf::Out<ams::btm::DeviceConditionV900> out), (out), hos::Version_9_0_0, hos::Version_12_1_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, GetDeviceInfoDeprecated, (sf::Out<ams::btm::DeviceInfoList> out), (out), hos::Version_1_0_0, hos::Version_12_1_0) \
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(ams::mitm::btm, IBtmMitmInterface, AMS_BTM_MITM_INTERFACE_INFO, 0xB5E45686)
|
||||
|
||||
|
@ -41,13 +41,15 @@ namespace ams::mitm::btm {
|
|||
}
|
||||
|
||||
public:
|
||||
Result GetDeviceCondition(ams::btm::Profile profile, const sf::OutArray<ams::btm::ConnectedDevice> &out, sf::Out<s32> total_out);
|
||||
Result GetDeviceInfo(ams::btm::Profile profile, const sf::OutArray<ams::btm::DeviceInfo> &out, sf::Out<s32> total_out);
|
||||
|
||||
/* Deprecated */
|
||||
Result GetDeviceConditionDeprecated1(sf::Out<ams::btm::DeviceConditionV100> out);
|
||||
Result GetDeviceConditionDeprecated2(sf::Out<ams::btm::DeviceConditionV510> out);
|
||||
Result GetDeviceConditionDeprecated3(sf::Out<ams::btm::DeviceConditionV800> out);
|
||||
Result GetDeviceConditionDeprecated4(sf::Out<ams::btm::DeviceConditionV900> out);
|
||||
Result GetDeviceCondition(u32 id, const sf::OutArray<ams::btm::ConnectedDevice> &out, sf::Out<s32> total_out);
|
||||
Result GetDeviceInfoDeprecated(sf::Out<ams::btm::DeviceInfoList> out);
|
||||
Result GetDeviceInfo(u32 id, const sf::OutArray<ams::btm::DeviceInfo> &out, sf::Out<s32> total_out);
|
||||
};
|
||||
static_assert(IsIBtmMitmInterface<BtmMitmService>);
|
||||
|
||||
|
|
|
@ -16,6 +16,22 @@
|
|||
#include "btm_shim.h"
|
||||
#include <stratosphere/sf/sf_mitm_dispatch.h>
|
||||
|
||||
Result btmGetDeviceConditionFwd(Service* s, BtmProfile profile, BtmConnectedDeviceV13 *condition, size_t count, s32 *total_out) {
|
||||
return serviceMitmDispatchInOut(s, 3, profile, *total_out,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
.buffers = { {condition, sizeof(BtmConnectedDeviceV13)*count} },
|
||||
);
|
||||
}
|
||||
|
||||
Result btmGetDeviceInfoFwd(Service* s, BtmProfile profile, BtmDeviceInfoV13 *devices, size_t count, s32 *total_out) {
|
||||
return serviceMitmDispatchInOut(s, 9, profile, *total_out,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
.buffers = { {devices, sizeof(BtmDeviceInfoV13)*count} },
|
||||
);
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
|
||||
Result btmGetDeviceConditionDeprecated1Fwd(Service* s, BtmDeviceConditionV100 *condition) {
|
||||
return serviceMitmDispatch(s, 3,
|
||||
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
|
@ -44,23 +60,9 @@ Result btmGetDeviceConditionDeprecated4Fwd(Service* s, BtmDeviceConditionV900 *c
|
|||
);
|
||||
}
|
||||
|
||||
Result btmGetDeviceConditionFwd(Service* s, u32 id, BtmConnectedDeviceV13 *condition, size_t count, s32 *total_out) {
|
||||
return serviceMitmDispatchInOut(s, 3, id, *total_out,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
.buffers = { {condition, sizeof(BtmConnectedDeviceV13)*count} },
|
||||
);
|
||||
}
|
||||
|
||||
Result btmGetDeviceInfoDeprecatedFwd(Service* s, BtmDeviceInfoList *devices) {
|
||||
return serviceMitmDispatch(s, 9,
|
||||
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
.buffers = { {devices, sizeof(BtmDeviceInfoList)} }
|
||||
);
|
||||
}
|
||||
|
||||
Result btmGetDeviceInfoFwd(Service* s, u32 id, BtmDeviceInfoV13 *devices, size_t count, s32 *total_out) {
|
||||
return serviceMitmDispatchInOut(s, 9, id, *total_out,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
.buffers = { {devices, sizeof(BtmDeviceInfoV13)*count} },
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,15 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
Result btmGetDeviceConditionFwd(Service* s, BtmProfile profile, BtmConnectedDeviceV13 *condition, size_t count, s32 *total_out);
|
||||
Result btmGetDeviceInfoFwd(Service* s, BtmProfile profile, BtmDeviceInfoV13 *devices, size_t count, s32 *total_out);
|
||||
|
||||
/* Deprecated */
|
||||
Result btmGetDeviceConditionDeprecated1Fwd(Service* s, BtmDeviceConditionV100 *condition);
|
||||
Result btmGetDeviceConditionDeprecated2Fwd(Service* s, BtmDeviceConditionV510 *condition);
|
||||
Result btmGetDeviceConditionDeprecated3Fwd(Service* s, BtmDeviceConditionV800 *condition);
|
||||
Result btmGetDeviceConditionDeprecated4Fwd(Service* s, BtmDeviceConditionV900 *condition);
|
||||
Result btmGetDeviceConditionFwd(Service* s, u32 id, BtmConnectedDeviceV13 *condition, size_t count, s32 *total_out);
|
||||
Result btmGetDeviceInfoDeprecatedFwd(Service* s, BtmDeviceInfoList *devices);
|
||||
Result btmGetDeviceInfoFwd(Service* s, u32 id, BtmDeviceInfoV13 *devices, size_t count, s32 *total_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace ams::mitm::btm {
|
|||
os::SetThreadNamePointer(&g_thread, "mc::BtmMitmThread");
|
||||
os::StartThread(&g_thread);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void WaitFinished() {
|
||||
|
|
|
@ -39,49 +39,48 @@ namespace ams::controller {
|
|||
|
||||
void EightBitDoController::MapInputReport0x01(const EightBitDoReportData *src) {
|
||||
if (m_controller_type == EightBitDoControllerType_Zero) {
|
||||
m_buttons.dpad_down = (src->input0x01_v1.dpad == EightBitDoDPadV1_S) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SE) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SW);
|
||||
m_buttons.dpad_up = (src->input0x01_v1.dpad == EightBitDoDPadV1_N) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NE) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NW);
|
||||
m_buttons.dpad_right = (src->input0x01_v1.dpad == EightBitDoDPadV1_E) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NE) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SE);
|
||||
m_buttons.dpad_left = (src->input0x01_v1.dpad == EightBitDoDPadV1_W) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NW) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SW);
|
||||
}
|
||||
else {
|
||||
m_buttons.dpad_down = (src->input0x01_v1.dpad == EightBitDoDPadV1_S) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SE) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SW);
|
||||
m_buttons.dpad_up = (src->input0x01_v1.dpad == EightBitDoDPadV1_N) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NE) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NW);
|
||||
m_buttons.dpad_right = (src->input0x01_v1.dpad == EightBitDoDPadV1_E) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NE) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SE);
|
||||
m_buttons.dpad_left = (src->input0x01_v1.dpad == EightBitDoDPadV1_W) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_NW) ||
|
||||
(src->input0x01_v1.dpad == EightBitDoDPadV1_SW);
|
||||
} else {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01_v2.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01_v2.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01_v2.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01_v2.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01_v2.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01_v2.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01_v2.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01_v2.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_S) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SW);
|
||||
m_buttons.dpad_up = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_N) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NW);
|
||||
m_buttons.dpad_right = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_E) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SE);
|
||||
m_buttons.dpad_left = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_W) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NW) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SW);
|
||||
m_buttons.dpad_down = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_S) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SW);
|
||||
m_buttons.dpad_up = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_N) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NW);
|
||||
m_buttons.dpad_right = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_E) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NE) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SE);
|
||||
m_buttons.dpad_left = (src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_W) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_NW) ||
|
||||
(src->input0x01_v2.buttons.dpad == EightBitDoDPadV2_SW);
|
||||
|
||||
m_buttons.A = src->input0x01_v2.buttons.B;
|
||||
m_buttons.B = src->input0x01_v2.buttons.A;
|
||||
m_buttons.X = src->input0x01_v2.buttons.Y;
|
||||
m_buttons.Y = src->input0x01_v2.buttons.X;
|
||||
|
||||
m_buttons.L = src->input0x01_v2.buttons.L1;
|
||||
m_buttons.R = src->input0x01_v2.buttons.R1;
|
||||
m_buttons.L = src->input0x01_v2.buttons.L1;
|
||||
m_buttons.R = src->input0x01_v2.buttons.R1;
|
||||
|
||||
if (m_controller_type == EightBitDoControllerType_Sn30ProXboxCloud) {
|
||||
m_buttons.ZL = src->input0x01_v2.left_trigger > 0x7f;
|
||||
|
@ -121,8 +120,7 @@ namespace ams::controller {
|
|||
|
||||
m_buttons.minus = src->input0x03_v1.buttons.select;
|
||||
m_buttons.plus = src->input0x03_v1.buttons.start;
|
||||
}
|
||||
else if (fmt == EightBitDoReportFormat_ZeroV2) {
|
||||
} else if (fmt == EightBitDoReportFormat_ZeroV2) {
|
||||
m_buttons.dpad_down = src->input0x03_v2.left_stick.y == 0xff;
|
||||
m_buttons.dpad_up = src->input0x03_v2.left_stick.y == 0x00;
|
||||
m_buttons.dpad_right = src->input0x03_v2.left_stick.x == 0xff;
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace ams::controller {
|
|||
EightBitDoReportFormat_Other
|
||||
};
|
||||
|
||||
enum EightBitDoDPadDirectionV1 : uint16_t {
|
||||
enum EightBitDoDPadDirectionV1 : u16 {
|
||||
EightBitDoDPadV1_Released = 0x0000,
|
||||
EightBitDoDPadV1_N = 0x0052,
|
||||
EightBitDoDPadV1_NE = 0x524f,
|
||||
|
@ -56,109 +56,109 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct EightBitDoStickData8 {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoStickData16 {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} __attribute__((packed));
|
||||
u16 x;
|
||||
u16 y;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoButtonDataV1 {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
|
||||
uint8_t : 2;
|
||||
uint8_t select : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t : 0;
|
||||
}__attribute__((packed));
|
||||
u8 : 2;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoButtonDataV2 {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint8_t select : 1;
|
||||
uint8_t : 2;
|
||||
uint8_t start : 1;
|
||||
uint8_t home : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 1;
|
||||
u8 select : 1;
|
||||
u8 : 2;
|
||||
u8 start : 1;
|
||||
u8 home : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 1;
|
||||
} v1;
|
||||
|
||||
struct {
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
uint8_t select : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t home : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 1;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 home : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 1;
|
||||
} v2;
|
||||
};
|
||||
|
||||
uint8_t dpad;
|
||||
} __attribute__((packed));
|
||||
u8 dpad;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x01V1 {
|
||||
uint8_t _unk0[2];
|
||||
uint16_t dpad;
|
||||
uint8_t _unk1[4];
|
||||
} __attribute__((packed));
|
||||
u8 _unk0[2];
|
||||
u16 dpad;
|
||||
u8 _unk1[4];
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x01V2 {
|
||||
EightBitDoButtonDataV2 buttons;
|
||||
EightBitDoStickData16 left_stick;
|
||||
EightBitDoStickData16 right_stick;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
uint8_t _unk0;
|
||||
} __attribute__((packed));
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
u8 _unk0;
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x03V1 {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
EightBitDoStickData8 left_stick;
|
||||
EightBitDoStickData8 right_stick;
|
||||
uint8_t _unk[3];
|
||||
u8 _unk[3];
|
||||
EightBitDoButtonDataV1 buttons;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoInputReport0x03V2 {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
EightBitDoStickData8 left_stick;
|
||||
EightBitDoStickData8 right_stick;
|
||||
uint8_t _unk[2];
|
||||
u8 _unk[2];
|
||||
EightBitDoButtonDataV1 buttons;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct EightBitDoReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
EightBitDoInputReport0x01V1 input0x01_v1;
|
||||
EightBitDoInputReport0x01V2 input0x01_v2;
|
||||
EightBitDoInputReport0x03V1 input0x03_v1;
|
||||
EightBitDoInputReport0x03V2 input0x03_v2;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class EightBitDoController : public EmulatedSwitchController {
|
||||
class EightBitDoController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -47,21 +47,21 @@ namespace ams::controller {
|
|||
);
|
||||
m_right_stick.SetData(
|
||||
STICK_ZERO,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.x)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.x)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == AtGamesDPad_S) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == AtGamesDPad_N) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == AtGamesDPad_E) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == AtGamesDPad_W) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == AtGamesDPad_S) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == AtGamesDPad_N) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == AtGamesDPad_E) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == AtGamesDPad_W) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x01.play;
|
||||
m_buttons.B = src->input0x01.rewind;
|
||||
|
@ -80,21 +80,21 @@ namespace ams::controller {
|
|||
);
|
||||
m_right_stick.SetData(
|
||||
STICK_ZERO,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.x)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.x)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == AtGamesDPad_S) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == AtGamesDPad_N) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == AtGamesDPad_E) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == AtGamesDPad_W) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == AtGamesDPad_S) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == AtGamesDPad_N) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == AtGamesDPad_E) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NE) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == AtGamesDPad_W) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_NW) ||
|
||||
(src->input0x01.dpad == AtGamesDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x01.a_button;
|
||||
m_buttons.B = src->input0x01.b_button;
|
||||
|
|
|
@ -31,44 +31,44 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct AtGamesStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct AtGamesInputReport0x01 {
|
||||
uint8_t rewind : 1;
|
||||
uint8_t nudge_front : 1;
|
||||
uint8_t b_button : 1;
|
||||
uint8_t y_button : 1;
|
||||
uint8_t nudge_left : 1;
|
||||
uint8_t flipper_right : 1;
|
||||
uint8_t x_button : 1;
|
||||
uint8_t play : 1;
|
||||
u8 rewind : 1;
|
||||
u8 nudge_front : 1;
|
||||
u8 b_button : 1;
|
||||
u8 y_button : 1;
|
||||
u8 nudge_left : 1;
|
||||
u8 flipper_right : 1;
|
||||
u8 x_button : 1;
|
||||
u8 play : 1;
|
||||
|
||||
uint8_t a_button : 1;
|
||||
uint8_t home_twirl : 1;
|
||||
uint8_t flipper_left : 1;
|
||||
uint8_t nudge_right : 1;
|
||||
uint8_t z_button : 1;
|
||||
uint8_t c_button : 1;
|
||||
uint8_t : 0;
|
||||
u8 a_button : 1;
|
||||
u8 home_twirl : 1;
|
||||
u8 flipper_left : 1;
|
||||
u8 nudge_right : 1;
|
||||
u8 z_button : 1;
|
||||
u8 c_button : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t unk1[2];
|
||||
uint8_t dpad;
|
||||
u8 unk1[2];
|
||||
u8 dpad;
|
||||
AtGamesStickData left_stick;
|
||||
AtGamesStickData right_stick; // Only right stick y-axis is used for plunger
|
||||
uint8_t unk2;
|
||||
u8 unk2;
|
||||
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct AtGamesReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
AtGamesInputReport0x01 input0x01;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class AtGamesController : public EmulatedSwitchController {
|
||||
class AtGamesController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -33,10 +33,10 @@ namespace ams::controller {
|
|||
"MD/Gen Control Pad",
|
||||
};
|
||||
|
||||
constexpr auto cod_major_peripheral = 0x05;
|
||||
constexpr auto cod_minor_gamepad = 0x08;
|
||||
constexpr auto cod_minor_joystick = 0x04;
|
||||
constexpr auto cod_minor_keyboard = 0x40;
|
||||
constexpr auto cod_major_peripheral = 0x05;
|
||||
constexpr auto cod_minor_gamepad = 0x08;
|
||||
constexpr auto cod_minor_joystick = 0x04;
|
||||
constexpr auto cod_minor_keyboard = 0x40;
|
||||
|
||||
os::Mutex g_controller_lock(false);
|
||||
std::vector<std::shared_ptr<SwitchController>> g_controllers;
|
||||
|
@ -117,8 +117,8 @@ namespace ams::controller {
|
|||
for (auto hwId : NvidiaShieldController::hardware_ids) {
|
||||
if ( (device->vid == hwId.vid) && (device->pid == hwId.pid) ) {
|
||||
return ControllerType_NvidiaShield;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto hwId : EightBitDoController::hardware_ids) {
|
||||
if ( (device->vid == hwId.vid) && (device->pid == hwId.pid) ) {
|
||||
|
@ -156,13 +156,13 @@ namespace ams::controller {
|
|||
}
|
||||
}
|
||||
|
||||
for (auto hwId : LanShenController::hardware_ids) {
|
||||
for (auto hwId : LanShenController::hardware_ids) {
|
||||
if ( (device->vid == hwId.vid) && (device->pid == hwId.pid) ) {
|
||||
return ControllerType_LanShen;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto hwId : AtGamesController::hardware_ids) {
|
||||
for (auto hwId : AtGamesController::hardware_ids) {
|
||||
if ( (device->vid == hwId.vid) && (device->pid == hwId.pid) ) {
|
||||
return ControllerType_AtGames;
|
||||
}
|
||||
|
@ -297,9 +297,9 @@ namespace ams::controller {
|
|||
std::scoped_lock lk(g_controller_lock);
|
||||
|
||||
for (auto it = g_controllers.begin(); it < g_controllers.end(); ++it) {
|
||||
if (utils::BluetoothAddressCompare(&(*it)->Address(), address)) {
|
||||
return (*it);
|
||||
}
|
||||
if (utils::BluetoothAddressCompare(&(*it)->Address(), address)) {
|
||||
return (*it);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
namespace ams::controller {
|
||||
|
||||
uint8_t convert_battery_100(uint8_t level) {
|
||||
u8 convert_battery_100(u8 level) {
|
||||
return level ? (((level - 1) / 25) + 1) << 1 : 0;
|
||||
}
|
||||
|
||||
uint8_t convert_battery_255(uint8_t level) {
|
||||
u8 convert_battery_255(u8 level) {
|
||||
return level ? ((level / 64) + 1) << 1 : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
namespace ams::controller {
|
||||
|
||||
uint8_t convert_battery_100(uint8_t level);
|
||||
uint8_t convert_battery_255(uint8_t level);
|
||||
u8 convert_battery_100(u8 level);
|
||||
u8 convert_battery_255(u8 level);
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::controller {
|
|||
constexpr float accel_scale_factor = 65535 / 16000.0f * 1000;
|
||||
constexpr float gyro_scale_factor = 65535 / (13371 * 360.0f) * 1000;
|
||||
|
||||
const uint8_t player_led_flags[] = {
|
||||
const u8 player_led_flags[] = {
|
||||
// Mimic the Switch's player LEDs
|
||||
0x01,
|
||||
0x03,
|
||||
|
@ -38,7 +38,7 @@ namespace ams::controller {
|
|||
0x0A
|
||||
};
|
||||
|
||||
const uint8_t new_player_led_flags[] = {
|
||||
const u8 new_player_led_flags[] = {
|
||||
0x04,
|
||||
0x02,
|
||||
0x05,
|
||||
|
@ -64,7 +64,7 @@ namespace ams::controller {
|
|||
{0x10, 0x00, 0x30} // purple
|
||||
};
|
||||
|
||||
constexpr uint32_t crc_seed = 0x8C36CCAE; // CRC32 of {0xa2, 0x31} bytes at beginning of output report
|
||||
constexpr u32 crc_seed = 0x8C36CCAE; // CRC32 of {0xa2, 0x31} bytes at beginning of output report
|
||||
|
||||
}
|
||||
|
||||
|
@ -78,12 +78,12 @@ namespace ams::controller {
|
|||
// Request motion calibration data from DualSense
|
||||
R_TRY(this->GetCalibrationData(&m_motion_calibration));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result DualsenseController::SetVibration(const SwitchRumbleData *rumble_data) {
|
||||
m_rumble_state.amp_motor_left = static_cast<uint8_t>(255 * std::max(rumble_data[0].low_band_amp, rumble_data[1].low_band_amp));
|
||||
m_rumble_state.amp_motor_right = static_cast<uint8_t>(255 * std::max(rumble_data[0].high_band_amp, rumble_data[1].high_band_amp));
|
||||
m_rumble_state.amp_motor_left = static_cast<u8>(255 * std::max(rumble_data[0].low_band_amp, rumble_data[1].low_band_amp));
|
||||
m_rumble_state.amp_motor_right = static_cast<u8>(255 * std::max(rumble_data[0].high_band_amp, rumble_data[1].high_band_amp));
|
||||
return this->PushRumbleLedState();
|
||||
}
|
||||
|
||||
|
@ -93,13 +93,13 @@ namespace ams::controller {
|
|||
return this->PushRumbleLedState();
|
||||
}
|
||||
|
||||
Result DualsenseController::SetPlayerLed(uint8_t led_mask) {
|
||||
Result DualsenseController::SetPlayerLed(u8 led_mask) {
|
||||
auto config = mitm::GetGlobalConfig();
|
||||
|
||||
uint8_t player_number;
|
||||
u8 player_number;
|
||||
R_TRY(LedsMaskToPlayerNumber(led_mask, &player_number));
|
||||
|
||||
uint16_t fw_version = *reinterpret_cast<uint16_t *>(&m_version_info.data[43]);
|
||||
u16 fw_version = *reinterpret_cast<u16 *>(&m_version_info.data[43]);
|
||||
|
||||
if (!config->misc.enable_dualsense_player_leds) {
|
||||
m_led_flags = 0x00;
|
||||
|
@ -113,13 +113,13 @@ namespace ams::controller {
|
|||
m_led_flags |= 0x20;
|
||||
|
||||
RGBColour colour = player_led_colours[player_number];
|
||||
return this->SetLightbarColour(colour);
|
||||
R_RETURN(this->SetLightbarColour(colour));
|
||||
}
|
||||
|
||||
Result DualsenseController::SetLightbarColour(RGBColour colour) {
|
||||
auto config = mitm::GetGlobalConfig();
|
||||
m_led_colour = config->misc.enable_dualsense_lightbar ? colour : led_disable;
|
||||
return this->PushRumbleLedState();
|
||||
R_RETURN(this->PushRumbleLedState());
|
||||
}
|
||||
|
||||
void DualsenseController::ProcessInputData(const bluetooth::HidReport *report) {
|
||||
|
@ -137,12 +137,12 @@ namespace ams::controller {
|
|||
|
||||
void DualsenseController::MapInputReport0x01(const DualsenseReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
this->MapButtons(&src->input0x01.buttons);
|
||||
|
@ -151,38 +151,41 @@ namespace ams::controller {
|
|||
void DualsenseController::MapInputReport0x31(const DualsenseReportData *src) {
|
||||
m_ext_power = src->input0x31.usb;
|
||||
|
||||
if (!src->input0x31.usb || src->input0x31.full)
|
||||
if (!src->input0x31.usb || src->input0x31.full) {
|
||||
m_charging = false;
|
||||
else
|
||||
} else {
|
||||
m_charging = true;
|
||||
}
|
||||
|
||||
uint8_t battery_level = src->input0x31.battery_level;
|
||||
if (!src->input0x31.usb)
|
||||
u8 battery_level = src->input0x31.battery_level;
|
||||
if (!src->input0x31.usb) {
|
||||
battery_level++;
|
||||
if (battery_level > 10)
|
||||
}
|
||||
if (battery_level > 10) {
|
||||
battery_level = 10;
|
||||
}
|
||||
|
||||
m_battery = static_cast<uint8_t>(8 * (battery_level + 2) / 10) & 0x0e;
|
||||
m_battery = static_cast<u8>(8 * (battery_level + 2) / 10) & 0x0e;
|
||||
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x31.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x31.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x31.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x31.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x31.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x31.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x31.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x31.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
this->MapButtons(&src->input0x31.buttons);
|
||||
|
||||
if (m_enable_motion) {
|
||||
int16_t acc_x = -static_cast<int16_t>(accel_scale_factor * src->input0x31.acc_z / float(m_motion_calibration.acc.z_max));
|
||||
int16_t acc_y = -static_cast<int16_t>(accel_scale_factor * src->input0x31.acc_x / float(m_motion_calibration.acc.x_max));
|
||||
int16_t acc_z = static_cast<int16_t>(accel_scale_factor * src->input0x31.acc_y / float(m_motion_calibration.acc.y_max));
|
||||
s16 acc_x = -static_cast<s16>(accel_scale_factor * src->input0x31.acc_z / float(m_motion_calibration.acc.z_max));
|
||||
s16 acc_y = -static_cast<s16>(accel_scale_factor * src->input0x31.acc_x / float(m_motion_calibration.acc.x_max));
|
||||
s16 acc_z = static_cast<s16>(accel_scale_factor * src->input0x31.acc_y / float(m_motion_calibration.acc.y_max));
|
||||
|
||||
int16_t vel_x = -static_cast<int16_t>(0.85 * gyro_scale_factor * (src->input0x31.vel_z - m_motion_calibration.gyro.roll_bias) / ((m_motion_calibration.gyro.roll_max - m_motion_calibration.gyro.roll_bias) / m_motion_calibration.gyro.speed_max));
|
||||
int16_t vel_y = -static_cast<int16_t>(0.85 * gyro_scale_factor * (src->input0x31.vel_x - m_motion_calibration.gyro.pitch_bias) / ((m_motion_calibration.gyro.pitch_max - m_motion_calibration.gyro.pitch_bias) / m_motion_calibration.gyro.speed_max));
|
||||
int16_t vel_z = static_cast<int16_t>(0.85 * gyro_scale_factor * (src->input0x31.vel_y - m_motion_calibration.gyro.yaw_bias) / ((m_motion_calibration.gyro.yaw_max- m_motion_calibration.gyro.yaw_bias) / m_motion_calibration.gyro.speed_max));
|
||||
s16 vel_x = -static_cast<s16>(0.85 * gyro_scale_factor * (src->input0x31.vel_z - m_motion_calibration.gyro.roll_bias) / ((m_motion_calibration.gyro.roll_max - m_motion_calibration.gyro.roll_bias) / m_motion_calibration.gyro.speed_max));
|
||||
s16 vel_y = -static_cast<s16>(0.85 * gyro_scale_factor * (src->input0x31.vel_x - m_motion_calibration.gyro.pitch_bias) / ((m_motion_calibration.gyro.pitch_max - m_motion_calibration.gyro.pitch_bias) / m_motion_calibration.gyro.speed_max));
|
||||
s16 vel_z = static_cast<s16>(0.85 * gyro_scale_factor * (src->input0x31.vel_y - m_motion_calibration.gyro.yaw_bias) / ((m_motion_calibration.gyro.yaw_max- m_motion_calibration.gyro.yaw_bias) / m_motion_calibration.gyro.speed_max));
|
||||
|
||||
m_motion_data[0].gyro_1 = vel_x;
|
||||
m_motion_data[0].gyro_2 = vel_y;
|
||||
|
@ -204,25 +207,24 @@ namespace ams::controller {
|
|||
m_motion_data[2].accel_x = acc_x;
|
||||
m_motion_data[2].accel_y = acc_y;
|
||||
m_motion_data[2].accel_z = acc_z;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
std::memset(&m_motion_data, 0, sizeof(m_motion_data));
|
||||
}
|
||||
}
|
||||
|
||||
void DualsenseController::MapButtons(const DualsenseButtonData *buttons) {
|
||||
m_buttons.dpad_down = (buttons->dpad == DualsenseDPad_S) ||
|
||||
(buttons->dpad == DualsenseDPad_SE) ||
|
||||
(buttons->dpad == DualsenseDPad_SW);
|
||||
m_buttons.dpad_up = (buttons->dpad == DualsenseDPad_N) ||
|
||||
(buttons->dpad == DualsenseDPad_NE) ||
|
||||
(buttons->dpad == DualsenseDPad_NW);
|
||||
m_buttons.dpad_right = (buttons->dpad == DualsenseDPad_E) ||
|
||||
(buttons->dpad == DualsenseDPad_NE) ||
|
||||
(buttons->dpad == DualsenseDPad_SE);
|
||||
m_buttons.dpad_left = (buttons->dpad == DualsenseDPad_W) ||
|
||||
(buttons->dpad == DualsenseDPad_NW) ||
|
||||
(buttons->dpad == DualsenseDPad_SW);
|
||||
m_buttons.dpad_down = (buttons->dpad == DualsenseDPad_S) ||
|
||||
(buttons->dpad == DualsenseDPad_SE) ||
|
||||
(buttons->dpad == DualsenseDPad_SW);
|
||||
m_buttons.dpad_up = (buttons->dpad == DualsenseDPad_N) ||
|
||||
(buttons->dpad == DualsenseDPad_NE) ||
|
||||
(buttons->dpad == DualsenseDPad_NW);
|
||||
m_buttons.dpad_right = (buttons->dpad == DualsenseDPad_E) ||
|
||||
(buttons->dpad == DualsenseDPad_NE) ||
|
||||
(buttons->dpad == DualsenseDPad_SE);
|
||||
m_buttons.dpad_left = (buttons->dpad == DualsenseDPad_W) ||
|
||||
(buttons->dpad == DualsenseDPad_NW) ||
|
||||
(buttons->dpad == DualsenseDPad_SW);
|
||||
|
||||
m_buttons.A = buttons->circle;
|
||||
m_buttons.B = buttons->cross;
|
||||
|
@ -251,7 +253,7 @@ namespace ams::controller {
|
|||
auto response = reinterpret_cast<DualsenseReportData *>(&output.data);
|
||||
std::memcpy(version_info, &response->feature0x20.version_info, sizeof(DualsenseVersionInfo));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result DualsenseController::GetCalibrationData(DualsenseImuCalibrationData *calibration) {
|
||||
|
@ -261,7 +263,7 @@ namespace ams::controller {
|
|||
auto response = reinterpret_cast<DualsenseReportData *>(&output.data);
|
||||
std::memcpy(calibration, &response->feature0x05.calibration, sizeof(DualsenseImuCalibrationData));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result DualsenseController::PushRumbleLedState() {
|
||||
|
@ -289,7 +291,7 @@ namespace ams::controller {
|
|||
m_output_report.size = sizeof(report.output0x31) + sizeof(report.id);
|
||||
std::memcpy(m_output_report.data, &report, m_output_report.size);
|
||||
|
||||
return this->WriteDataReport(&m_output_report);
|
||||
R_RETURN(this->WriteDataReport(&m_output_report));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,114 +31,114 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct DualsenseStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseButtonData {
|
||||
uint8_t dpad : 4;
|
||||
uint8_t square : 1;
|
||||
uint8_t cross : 1;
|
||||
uint8_t circle : 1;
|
||||
uint8_t triangle : 1;
|
||||
u8 dpad : 4;
|
||||
u8 square : 1;
|
||||
u8 cross : 1;
|
||||
u8 circle : 1;
|
||||
u8 triangle : 1;
|
||||
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
uint8_t share : 1;
|
||||
uint8_t options : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
u8 share : 1;
|
||||
u8 options : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
|
||||
uint8_t ps : 1;
|
||||
uint8_t tpad : 1;
|
||||
uint8_t counter : 6;
|
||||
} __attribute__((packed));
|
||||
u8 ps : 1;
|
||||
u8 tpad : 1;
|
||||
u8 counter : 6;
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseRumbleData {
|
||||
uint8_t amp_motor_left;
|
||||
uint8_t amp_motor_right;
|
||||
} __attribute__((packed));
|
||||
u8 amp_motor_left;
|
||||
u8 amp_motor_right;
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseImuCalibrationData {
|
||||
struct {
|
||||
int16_t pitch_bias;
|
||||
int16_t yaw_bias;
|
||||
int16_t roll_bias;
|
||||
int16_t pitch_max;
|
||||
int16_t pitch_min;
|
||||
int16_t yaw_max;
|
||||
int16_t yaw_min;
|
||||
int16_t roll_max;
|
||||
int16_t roll_min;
|
||||
int16_t speed_max;
|
||||
int16_t speed_min;
|
||||
s16 pitch_bias;
|
||||
s16 yaw_bias;
|
||||
s16 roll_bias;
|
||||
s16 pitch_max;
|
||||
s16 pitch_min;
|
||||
s16 yaw_max;
|
||||
s16 yaw_min;
|
||||
s16 roll_max;
|
||||
s16 roll_min;
|
||||
s16 speed_max;
|
||||
s16 speed_min;
|
||||
} gyro;
|
||||
|
||||
struct {
|
||||
int16_t x_max;
|
||||
int16_t x_min;
|
||||
int16_t y_max;
|
||||
int16_t y_min;
|
||||
int16_t z_max;
|
||||
int16_t z_min;
|
||||
s16 x_max;
|
||||
s16 x_min;
|
||||
s16 y_max;
|
||||
s16 y_min;
|
||||
s16 z_max;
|
||||
s16 z_min;
|
||||
} acc;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseVersionInfo {
|
||||
char data[64];
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseFeatureReport0x05 {
|
||||
DualsenseImuCalibrationData calibration;
|
||||
uint32_t crc;
|
||||
} __attribute__((packed));
|
||||
u32 crc;
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseFeatureReport0x20 {
|
||||
DualsenseVersionInfo version_info;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseOutputReport0x31 {
|
||||
struct {
|
||||
uint8_t data[73];
|
||||
u8 data[73];
|
||||
};
|
||||
uint32_t crc;
|
||||
} __attribute__((packed));
|
||||
u32 crc;
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseInputReport0x01 {
|
||||
DualsenseStickData left_stick;
|
||||
DualsenseStickData right_stick;
|
||||
DualsenseButtonData buttons;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
} __attribute__((packed));
|
||||
DualsenseStickData left_stick;
|
||||
DualsenseStickData right_stick;
|
||||
DualsenseButtonData buttons;
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseInputReport0x31 {
|
||||
uint8_t _unk0;
|
||||
DualsenseStickData left_stick;
|
||||
DualsenseStickData right_stick;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
uint8_t counter;
|
||||
DualsenseButtonData buttons;
|
||||
uint8_t _unk1[5];
|
||||
int16_t vel_x;
|
||||
int16_t vel_y;
|
||||
int16_t vel_z;
|
||||
int16_t acc_x;
|
||||
int16_t acc_y;
|
||||
int16_t acc_z;
|
||||
uint8_t _unk2[25];
|
||||
u8 _unk0;
|
||||
DualsenseStickData left_stick;
|
||||
DualsenseStickData right_stick;
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
u8 counter;
|
||||
DualsenseButtonData buttons;
|
||||
u8 _unk1[5];
|
||||
s16 vel_x;
|
||||
s16 vel_y;
|
||||
s16 vel_z;
|
||||
s16 acc_x;
|
||||
s16 acc_y;
|
||||
s16 acc_z;
|
||||
u8 _unk2[25];
|
||||
|
||||
uint8_t battery_level : 4;
|
||||
uint8_t usb : 1;
|
||||
uint8_t full : 1;
|
||||
uint8_t : 0;
|
||||
} __attribute__((packed));
|
||||
u8 battery_level : 4;
|
||||
u8 usb : 1;
|
||||
u8 full : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct DualsenseReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
DualsenseFeatureReport0x05 feature0x05;
|
||||
DualsenseFeatureReport0x20 feature0x20;
|
||||
|
@ -146,9 +146,9 @@ namespace ams::controller {
|
|||
DualsenseInputReport0x01 input0x01;
|
||||
DualsenseInputReport0x31 input0x31;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class DualsenseController : public EmulatedSwitchController {
|
||||
class DualsenseController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
@ -165,7 +165,7 @@ namespace ams::controller {
|
|||
Result Initialize();
|
||||
Result SetVibration(const SwitchRumbleData *rumble_data);
|
||||
Result CancelVibration();
|
||||
Result SetPlayerLed(uint8_t led_mask);
|
||||
Result SetPlayerLed(u8 led_mask);
|
||||
Result SetLightbarColour(RGBColour colour);
|
||||
|
||||
void ProcessInputData(const bluetooth::HidReport *report) override;
|
||||
|
@ -180,7 +180,7 @@ namespace ams::controller {
|
|||
Result GetCalibrationData(DualsenseImuCalibrationData *calibration);
|
||||
Result PushRumbleLedState();
|
||||
|
||||
uint8_t m_led_flags;
|
||||
u8 m_led_flags;
|
||||
RGBColour m_led_colour;
|
||||
DualsenseRumbleData m_rumble_state;
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace ams::controller {
|
|||
{0x10, 0x00, 0x30} // purple
|
||||
};
|
||||
|
||||
constexpr uint32_t crc_seed = 0xB758EC66; // CRC32 of {0xa2, 0x11} bytes at beginning of output report
|
||||
constexpr u32 crc_seed = 0xB758EC66; // CRC32 of {0xa2, 0x11} bytes at beginning of output report
|
||||
|
||||
}
|
||||
|
||||
|
@ -55,32 +55,32 @@ namespace ams::controller {
|
|||
m_enable_motion = false;
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Dualshock4Controller::SetVibration(const SwitchRumbleData *rumble_data) {
|
||||
m_rumble_state.amp_motor_left = static_cast<uint8_t>(255 * std::max(rumble_data[0].low_band_amp, rumble_data[1].low_band_amp));
|
||||
m_rumble_state.amp_motor_right = static_cast<uint8_t>(255 * std::max(rumble_data[0].high_band_amp, rumble_data[1].high_band_amp));
|
||||
return this->PushRumbleLedState();
|
||||
m_rumble_state.amp_motor_left = static_cast<u8>(255 * std::max(rumble_data[0].low_band_amp, rumble_data[1].low_band_amp));
|
||||
m_rumble_state.amp_motor_right = static_cast<u8>(255 * std::max(rumble_data[0].high_band_amp, rumble_data[1].high_band_amp));
|
||||
R_RETURN(this->PushRumbleLedState());
|
||||
}
|
||||
|
||||
Result Dualshock4Controller::CancelVibration() {
|
||||
m_rumble_state.amp_motor_left = 0;
|
||||
m_rumble_state.amp_motor_right = 0;
|
||||
return this->PushRumbleLedState();
|
||||
R_RETURN(this->PushRumbleLedState());
|
||||
}
|
||||
|
||||
Result Dualshock4Controller::SetPlayerLed(uint8_t led_mask) {
|
||||
uint8_t player_number;
|
||||
Result Dualshock4Controller::SetPlayerLed(u8 led_mask) {
|
||||
u8 player_number;
|
||||
R_TRY(LedsMaskToPlayerNumber(led_mask, &player_number));
|
||||
RGBColour colour = player_led_colours[player_number];
|
||||
return this->SetLightbarColour(colour);
|
||||
R_RETURN(this->SetLightbarColour(colour));
|
||||
}
|
||||
|
||||
Result Dualshock4Controller::SetLightbarColour(RGBColour colour) {
|
||||
auto config = mitm::GetGlobalConfig();
|
||||
m_led_colour = config->misc.enable_dualshock4_lightbar ? colour : led_disable;
|
||||
return this->PushRumbleLedState();
|
||||
R_RETURN(this->PushRumbleLedState());
|
||||
}
|
||||
|
||||
void Dualshock4Controller::ProcessInputData(const bluetooth::HidReport *report) {
|
||||
|
@ -98,12 +98,12 @@ namespace ams::controller {
|
|||
|
||||
void Dualshock4Controller::MapInputReport0x01(const Dualshock4ReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
this->MapButtons(&src->input0x01.buttons);
|
||||
|
@ -112,38 +112,41 @@ namespace ams::controller {
|
|||
void Dualshock4Controller::MapInputReport0x11(const Dualshock4ReportData *src) {
|
||||
m_ext_power = src->input0x11.usb;
|
||||
|
||||
if (!src->input0x11.usb || src->input0x11.battery_level > 10)
|
||||
if (!src->input0x11.usb || src->input0x11.battery_level > 10) {
|
||||
m_charging = false;
|
||||
else
|
||||
} else {
|
||||
m_charging = true;
|
||||
}
|
||||
|
||||
uint8_t battery_level = src->input0x11.battery_level;
|
||||
if (!src->input0x11.usb)
|
||||
u8 battery_level = src->input0x11.battery_level;
|
||||
if (!src->input0x11.usb) {
|
||||
battery_level++;
|
||||
if (battery_level > 10)
|
||||
}
|
||||
if (battery_level > 10) {
|
||||
battery_level = 10;
|
||||
}
|
||||
|
||||
m_battery = static_cast<uint8_t>(8 * (battery_level + 2) / 10) & 0x0e;
|
||||
m_battery = static_cast<u8>(8 * (battery_level + 2) / 10) & 0x0e;
|
||||
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x11.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x11.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x11.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x11.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x11.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x11.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x11.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x11.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
this->MapButtons(&src->input0x11.buttons);
|
||||
|
||||
if (m_enable_motion) {
|
||||
int16_t acc_x = -static_cast<int16_t>(accel_scale_factor * src->input0x11.acc_z / float(m_motion_calibration.acc.z_max));
|
||||
int16_t acc_y = -static_cast<int16_t>(accel_scale_factor * src->input0x11.acc_x / float(m_motion_calibration.acc.x_max));
|
||||
int16_t acc_z = static_cast<int16_t>(accel_scale_factor * src->input0x11.acc_y / float(m_motion_calibration.acc.y_max));
|
||||
s16 acc_x = -static_cast<s16>(accel_scale_factor * src->input0x11.acc_z / float(m_motion_calibration.acc.z_max));
|
||||
s16 acc_y = -static_cast<s16>(accel_scale_factor * src->input0x11.acc_x / float(m_motion_calibration.acc.x_max));
|
||||
s16 acc_z = static_cast<s16>(accel_scale_factor * src->input0x11.acc_y / float(m_motion_calibration.acc.y_max));
|
||||
|
||||
int16_t vel_x = -static_cast<int16_t>(0.85 * gyro_scale_factor * (src->input0x11.vel_z - m_motion_calibration.gyro.roll_bias) / ((m_motion_calibration.gyro.roll_max - m_motion_calibration.gyro.roll_bias) / m_motion_calibration.gyro.speed_max));
|
||||
int16_t vel_y = -static_cast<int16_t>(0.85 * gyro_scale_factor * (src->input0x11.vel_x - m_motion_calibration.gyro.pitch_bias) / ((m_motion_calibration.gyro.pitch_max - m_motion_calibration.gyro.pitch_bias) / m_motion_calibration.gyro.speed_max));
|
||||
int16_t vel_z = static_cast<int16_t>(0.85 * gyro_scale_factor * (src->input0x11.vel_y - m_motion_calibration.gyro.yaw_bias) / ((m_motion_calibration.gyro.yaw_max- m_motion_calibration.gyro.yaw_bias) / m_motion_calibration.gyro.speed_max));
|
||||
s16 vel_x = -static_cast<s16>(0.85 * gyro_scale_factor * (src->input0x11.vel_z - m_motion_calibration.gyro.roll_bias) / ((m_motion_calibration.gyro.roll_max - m_motion_calibration.gyro.roll_bias) / m_motion_calibration.gyro.speed_max));
|
||||
s16 vel_y = -static_cast<s16>(0.85 * gyro_scale_factor * (src->input0x11.vel_x - m_motion_calibration.gyro.pitch_bias) / ((m_motion_calibration.gyro.pitch_max - m_motion_calibration.gyro.pitch_bias) / m_motion_calibration.gyro.speed_max));
|
||||
s16 vel_z = static_cast<s16>(0.85 * gyro_scale_factor * (src->input0x11.vel_y - m_motion_calibration.gyro.yaw_bias) / ((m_motion_calibration.gyro.yaw_max- m_motion_calibration.gyro.yaw_bias) / m_motion_calibration.gyro.speed_max));
|
||||
|
||||
m_motion_data[0].gyro_1 = vel_x;
|
||||
m_motion_data[0].gyro_2 = vel_y;
|
||||
|
@ -165,8 +168,7 @@ namespace ams::controller {
|
|||
m_motion_data[2].accel_x = acc_x;
|
||||
m_motion_data[2].accel_y = acc_y;
|
||||
m_motion_data[2].accel_z = acc_z;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
std::memset(&m_motion_data, 0, sizeof(m_motion_data));
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +214,7 @@ namespace ams::controller {
|
|||
auto response = reinterpret_cast<Dualshock4ReportData *>(&output.data);
|
||||
std::memcpy(version_info, &response->feature0x06.version_info, sizeof(Dualshock4VersionInfo));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Dualshock4Controller::GetCalibrationData(Dualshock4ImuCalibrationData *calibration) {
|
||||
|
@ -222,7 +224,7 @@ namespace ams::controller {
|
|||
auto response = reinterpret_cast<Dualshock4ReportData *>(&output.data);
|
||||
std::memcpy(calibration, &response->feature0x05.calibration, sizeof(Dualshock4ImuCalibrationData));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Dualshock4Controller::PushRumbleLedState() {
|
||||
|
@ -230,7 +232,7 @@ namespace ams::controller {
|
|||
|
||||
Dualshock4ReportData report = {};
|
||||
report.id = 0x11;
|
||||
report.output0x11.data[0] = static_cast<uint8_t>(0xc0 | (m_report_rate & 0xff));
|
||||
report.output0x11.data[0] = static_cast<u8>(0xc0 | (m_report_rate & 0xff));
|
||||
report.output0x11.data[1] = 0x20;
|
||||
report.output0x11.data[2] = 0xf3;
|
||||
report.output0x11.data[3] = 0x04;
|
||||
|
@ -244,7 +246,7 @@ namespace ams::controller {
|
|||
m_output_report.size = sizeof(report.output0x11) + sizeof(report.id);
|
||||
std::memcpy(m_output_report.data, &report, m_output_report.size);
|
||||
|
||||
return this->WriteDataReport(&m_output_report);
|
||||
R_RETURN(this->WriteDataReport(&m_output_report));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,135 +57,135 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct Dualshock4StickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4ButtonData {
|
||||
uint8_t dpad : 4;
|
||||
uint8_t square : 1;
|
||||
uint8_t cross : 1;
|
||||
uint8_t circle : 1;
|
||||
uint8_t triangle : 1;
|
||||
u8 dpad : 4;
|
||||
u8 square : 1;
|
||||
u8 cross : 1;
|
||||
u8 circle : 1;
|
||||
u8 triangle : 1;
|
||||
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
uint8_t share : 1;
|
||||
uint8_t options : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
u8 share : 1;
|
||||
u8 options : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
|
||||
uint8_t ps : 1;
|
||||
uint8_t tpad : 1;
|
||||
uint8_t counter : 6;
|
||||
} __attribute__((packed));
|
||||
u8 ps : 1;
|
||||
u8 tpad : 1;
|
||||
u8 counter : 6;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4RumbleData {
|
||||
uint8_t amp_motor_left;
|
||||
uint8_t amp_motor_right;
|
||||
} __attribute__((packed));
|
||||
u8 amp_motor_left;
|
||||
u8 amp_motor_right;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4ImuCalibrationData {
|
||||
struct {
|
||||
int16_t pitch_bias;
|
||||
int16_t yaw_bias;
|
||||
int16_t roll_bias;
|
||||
int16_t pitch_max;
|
||||
int16_t yaw_max;
|
||||
int16_t roll_max;
|
||||
int16_t pitch_min;
|
||||
int16_t yaw_min;
|
||||
int16_t roll_min;
|
||||
int16_t speed_max;
|
||||
int16_t speed_min;
|
||||
s16 pitch_bias;
|
||||
s16 yaw_bias;
|
||||
s16 roll_bias;
|
||||
s16 pitch_max;
|
||||
s16 yaw_max;
|
||||
s16 roll_max;
|
||||
s16 pitch_min;
|
||||
s16 yaw_min;
|
||||
s16 roll_min;
|
||||
s16 speed_max;
|
||||
s16 speed_min;
|
||||
} gyro;
|
||||
|
||||
struct {
|
||||
int16_t x_max;
|
||||
int16_t x_min;
|
||||
int16_t y_max;
|
||||
int16_t y_min;
|
||||
int16_t z_max;
|
||||
int16_t z_min;
|
||||
s16 x_max;
|
||||
s16 x_min;
|
||||
s16 y_max;
|
||||
s16 y_min;
|
||||
s16 z_max;
|
||||
s16 z_min;
|
||||
} acc;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4VersionInfo {
|
||||
char date[48];
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4FeatureReport0x05 {
|
||||
Dualshock4ImuCalibrationData calibration;
|
||||
uint32_t crc;
|
||||
} __attribute__((packed));
|
||||
u32 crc;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4FeatureReport0x06 {
|
||||
Dualshock4VersionInfo version_info;
|
||||
uint32_t crc;
|
||||
} __attribute__((packed));
|
||||
u32 crc;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4FeatureReport0xa3 {
|
||||
Dualshock4VersionInfo version_info;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4OutputReport0x11 {
|
||||
struct {
|
||||
uint8_t data[73];
|
||||
u8 data[73];
|
||||
};
|
||||
uint32_t crc;
|
||||
} __attribute__((packed));
|
||||
u32 crc;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4InputReport0x01 {
|
||||
Dualshock4StickData left_stick;
|
||||
Dualshock4StickData right_stick;
|
||||
Dualshock4ButtonData buttons;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
} __attribute__((packed));
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4InputReport0x11 {
|
||||
uint8_t _unk0[2];
|
||||
u8 _unk0[2];
|
||||
Dualshock4StickData left_stick;
|
||||
Dualshock4StickData right_stick;
|
||||
Dualshock4ButtonData buttons;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
uint16_t timestamp;
|
||||
uint8_t battery;
|
||||
int16_t vel_x;
|
||||
int16_t vel_y;
|
||||
int16_t vel_z;
|
||||
int16_t acc_x;
|
||||
int16_t acc_y;
|
||||
int16_t acc_z;
|
||||
uint8_t _unk1[5];
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
u16 timestamp;
|
||||
u8 battery;
|
||||
s16 vel_x;
|
||||
s16 vel_y;
|
||||
s16 vel_z;
|
||||
s16 acc_x;
|
||||
s16 acc_y;
|
||||
s16 acc_z;
|
||||
u8 _unk1[5];
|
||||
|
||||
uint8_t battery_level : 4;
|
||||
uint8_t usb : 1;
|
||||
uint8_t mic : 1;
|
||||
uint8_t phone : 1;
|
||||
uint8_t : 0;
|
||||
u8 battery_level : 4;
|
||||
u8 usb : 1;
|
||||
u8 mic : 1;
|
||||
u8 phone : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint16_t _unk2;
|
||||
uint8_t tpad_packets;
|
||||
uint8_t packet_counter;
|
||||
} __attribute__((packed));
|
||||
u16 _unk2;
|
||||
u8 tpad_packets;
|
||||
u8 packet_counter;
|
||||
} PACKED;
|
||||
|
||||
struct Dualshock4ReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
Dualshock4FeatureReport0x05 feature0x05;
|
||||
Dualshock4FeatureReport0x06 feature0x06;
|
||||
Dualshock4FeatureReport0xa3 feature0xa3;
|
||||
Dualshock4OutputReport0x11 output0x11;
|
||||
Dualshock4InputReport0x01 input0x01;
|
||||
Dualshock4InputReport0x11 input0x11;
|
||||
Dualshock4OutputReport0x11 output0x11;
|
||||
Dualshock4InputReport0x01 input0x01;
|
||||
Dualshock4InputReport0x11 input0x11;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class Dualshock4Controller : public EmulatedSwitchController {
|
||||
class Dualshock4Controller final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
@ -205,7 +205,7 @@ namespace ams::controller {
|
|||
Result Initialize();
|
||||
Result SetVibration(const SwitchRumbleData *rumble_data);
|
||||
Result CancelVibration();
|
||||
Result SetPlayerLed(uint8_t led_mask);
|
||||
Result SetPlayerLed(u8 led_mask);
|
||||
Result SetLightbarColour(RGBColour colour);
|
||||
|
||||
void ProcessInputData(const bluetooth::HidReport *report) override;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace ams::controller {
|
|||
|
||||
// Frequency in Hz rounded to nearest int
|
||||
// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md#frequency-table
|
||||
const uint16_t rumble_freq_lut[] = {
|
||||
const u16 rumble_freq_lut[] = {
|
||||
0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031,
|
||||
0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0039, 0x003a, 0x003b,
|
||||
0x003c, 0x003e, 0x003f, 0x0040, 0x0042, 0x0043, 0x0045, 0x0046, 0x0048,
|
||||
|
@ -42,7 +42,7 @@ namespace ams::controller {
|
|||
0x039d, 0x03b1, 0x03c6, 0x03db, 0x03f1, 0x0407, 0x041d, 0x0434, 0x044c,
|
||||
0x0464, 0x047d, 0x0496, 0x04af, 0x04ca, 0x04e5
|
||||
};
|
||||
constexpr size_t rumble_freq_lut_size = sizeof(rumble_freq_lut) / sizeof(uint16_t);
|
||||
constexpr size_t rumble_freq_lut_size = sizeof(rumble_freq_lut) / sizeof(u16);
|
||||
|
||||
// Floats from dekunukem repo normalised and scaled by function used by yuzu
|
||||
// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md#amplitude-table
|
||||
|
@ -66,29 +66,27 @@ namespace ams::controller {
|
|||
};
|
||||
constexpr size_t rumble_amp_lut_f_size = sizeof(rumble_amp_lut_f) / sizeof(float);
|
||||
|
||||
Result DecodeRumbleValues(const uint8_t enc[], SwitchRumbleData *dec) {
|
||||
uint8_t hi_freq_ind = 0x20 + (enc[0] >> 2) + ((enc[1] & 0x01) * 0x40) - 1;
|
||||
uint8_t hi_amp_ind = (enc[1] & 0xfe) >> 1;
|
||||
uint8_t lo_freq_ind = (enc[2] & 0x7f) - 1;
|
||||
uint8_t lo_amp_ind = ((enc[3] - 0x40) << 1) + ((enc[2] & 0x80) >> 7);
|
||||
void DecodeRumbleValues(const u8 enc[], SwitchRumbleData *dec) {
|
||||
u8 hi_freq_ind = 0x20 + (enc[0] >> 2) + ((enc[1] & 0x01) * 0x40) - 1;
|
||||
u8 hi_amp_ind = (enc[1] & 0xfe) >> 1;
|
||||
u8 lo_freq_ind = (enc[2] & 0x7f) - 1;
|
||||
u8 lo_amp_ind = ((enc[3] - 0x40) << 1) + ((enc[2] & 0x80) >> 7);
|
||||
|
||||
if (!((hi_freq_ind < rumble_freq_lut_size) &&
|
||||
(hi_amp_ind < rumble_amp_lut_f_size) &&
|
||||
(lo_freq_ind < rumble_freq_lut_size) &&
|
||||
(lo_amp_ind < rumble_amp_lut_f_size))) {
|
||||
std::memset(dec, 0, sizeof(SwitchRumbleData));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dec->high_band_freq = float(rumble_freq_lut[hi_freq_ind]);
|
||||
dec->high_band_amp = rumble_amp_lut_f[hi_amp_ind];
|
||||
dec->low_band_freq = float(rumble_freq_lut[lo_freq_ind]);
|
||||
dec->low_band_amp = rumble_amp_lut_f[lo_amp_ind];
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
// CRC-8 with polynomial 0x7 for NFC/IR packets
|
||||
uint8_t crc8_lut[] = {
|
||||
u8 crc8_lut[] = {
|
||||
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
|
||||
0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
|
||||
0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
|
||||
|
@ -107,10 +105,10 @@ namespace ams::controller {
|
|||
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
|
||||
};
|
||||
|
||||
uint8_t ComputeCrc8(const void *data, size_t size) {
|
||||
auto *bytes = reinterpret_cast<const uint8_t *>(data);
|
||||
u8 ComputeCrc8(const void *data, size_t size) {
|
||||
auto *bytes = reinterpret_cast<const u8 *>(data);
|
||||
|
||||
uint8_t crc = 0x00;
|
||||
u8 crc = 0x00;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
crc = crc8_lut[crc ^ bytes[i]];
|
||||
}
|
||||
|
@ -144,7 +142,7 @@ namespace ams::controller {
|
|||
|
||||
R_TRY(m_virtual_memory.Initialize((controller_dir + "/spi_flash.bin").c_str()));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void EmulatedSwitchController::ClearControllerState() {
|
||||
|
@ -189,7 +187,7 @@ namespace ams::controller {
|
|||
break;
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleRumbleData(const SwitchRumbleDataEncoded *encoded) {
|
||||
|
@ -200,7 +198,7 @@ namespace ams::controller {
|
|||
R_TRY(this->SetVibration(rumble_data));
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommand(const SwitchHidCommand *command) {
|
||||
|
@ -272,7 +270,7 @@ namespace ams::controller {
|
|||
break;
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandGetDeviceInfo(const SwitchHidCommand *command) {
|
||||
|
@ -294,7 +292,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandSetDataFormat(const SwitchHidCommand *command) {
|
||||
|
@ -305,7 +303,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandLRButtonDetection(const SwitchHidCommand *command) {
|
||||
|
@ -314,7 +312,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandClearPairingInfo(const SwitchHidCommand *command) {
|
||||
|
@ -325,7 +323,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandShipment(const SwitchHidCommand *command) {
|
||||
|
@ -339,7 +337,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandSerialFlashRead(const SwitchHidCommand *command) {
|
||||
|
@ -369,7 +367,7 @@ namespace ams::controller {
|
|||
|
||||
if (read_addr == 0x6050) {
|
||||
if (ams::mitm::GetSystemLanguage() == 10) {
|
||||
uint8_t data[] = {0xff, 0xd7, 0x00, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7};
|
||||
u8 data[] = {0xff, 0xd7, 0x00, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7};
|
||||
std::memcpy(response.data.serial_flash_read.data, data, sizeof(data));
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +390,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandSerialFlashSectorErase(const SwitchHidCommand *command) {
|
||||
|
@ -408,7 +406,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandMcuPollingEnable(const SwitchHidCommand *command) {
|
||||
|
@ -420,7 +418,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandMcuPollingDisable(const SwitchHidCommand *command) {
|
||||
|
@ -432,7 +430,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandMcuWrite(const SwitchHidCommand *command) {
|
||||
|
@ -450,7 +448,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandMcuResume(const SwitchHidCommand *command) {
|
||||
|
@ -459,7 +457,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandSetIndicatorLed(const SwitchHidCommand *command) {
|
||||
|
@ -471,7 +469,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandGetIndicatorLed(const SwitchHidCommand *command) {
|
||||
|
@ -485,7 +483,7 @@ namespace ams::controller {
|
|||
}
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandSetNotificationLed(const SwitchHidCommand *command) {
|
||||
|
@ -494,7 +492,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandSensorSleep(const SwitchHidCommand *command) {
|
||||
|
@ -512,7 +510,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandSensorConfig(const SwitchHidCommand *command) {
|
||||
|
@ -537,7 +535,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleHidCommandMotorEnable(const SwitchHidCommand *command) {
|
||||
|
@ -548,7 +546,7 @@ namespace ams::controller {
|
|||
.id = command->id
|
||||
};
|
||||
|
||||
return this->FakeHidCommandResponse(&response);
|
||||
R_RETURN(this->FakeHidCommandResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::FakeHidCommandResponse(const SwitchHidCommandResponse *response) {
|
||||
|
@ -568,10 +566,10 @@ namespace ams::controller {
|
|||
m_input_report.size = offsetof(SwitchInputReport, type0x21) + sizeof(input_report->type0x21);
|
||||
|
||||
// Write a fake response into the report buffer
|
||||
return bluetooth::hid::report::WriteHidDataReport(m_address, &m_input_report);
|
||||
R_RETURN(bluetooth::hid::report::WriteHidDataReport(m_address, &m_input_report));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::HandleNfcIrData(const uint8_t *nfc_ir) {
|
||||
Result EmulatedSwitchController::HandleNfcIrData(const u8 *nfc_ir) {
|
||||
AMS_UNUSED(nfc_ir);
|
||||
|
||||
SwitchNfcIrResponse response = {};
|
||||
|
@ -579,7 +577,7 @@ namespace ams::controller {
|
|||
// Send device not ready response for now
|
||||
response.data[0] = 0xff;
|
||||
|
||||
return this->FakeNfcIrResponse(&response);
|
||||
R_RETURN(this->FakeNfcIrResponse(&response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::FakeNfcIrResponse(const SwitchNfcIrResponse *response) {
|
||||
|
@ -601,7 +599,7 @@ namespace ams::controller {
|
|||
m_input_report.size = offsetof(SwitchInputReport, type0x31) + sizeof(input_report->type0x31);
|
||||
|
||||
// Write a fake response into the report buffer
|
||||
return bluetooth::hid::report::WriteHidDataReport(m_address, &m_input_report);
|
||||
R_RETURN(bluetooth::hid::report::WriteHidDataReport(m_address, &m_input_report));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
|
||||
namespace ams::controller {
|
||||
|
||||
inline uint8_t ScaleRumbleAmplitude(float amp, uint8_t lower, uint8_t upper) {
|
||||
return amp > 0.0 ? static_cast<uint8_t>(amp * (upper - lower) + lower) : 0;
|
||||
}
|
||||
|
||||
class EmulatedSwitchController : public SwitchController {
|
||||
|
||||
public:
|
||||
|
@ -36,16 +32,16 @@ namespace ams::controller {
|
|||
|
||||
protected:
|
||||
void ClearControllerState();
|
||||
virtual Result SetVibration(const SwitchRumbleData *rumble_data) { AMS_UNUSED(rumble_data); return ams::ResultSuccess(); }
|
||||
virtual Result CancelVibration() { return ams::ResultSuccess(); }
|
||||
virtual Result SetPlayerLed(uint8_t led_mask) { AMS_UNUSED(led_mask); return ams::ResultSuccess(); }
|
||||
virtual Result SetVibration(const SwitchRumbleData *rumble_data) { AMS_UNUSED(rumble_data); R_SUCCEED(); }
|
||||
virtual Result CancelVibration() { R_SUCCEED(); }
|
||||
virtual Result SetPlayerLed(u8 led_mask) { AMS_UNUSED(led_mask); R_SUCCEED(); }
|
||||
|
||||
void UpdateControllerState(const bluetooth::HidReport *report) override;
|
||||
virtual void ProcessInputData(const bluetooth::HidReport *report) { AMS_UNUSED(report); }
|
||||
|
||||
Result HandleRumbleData(const SwitchRumbleDataEncoded *encoded);
|
||||
Result HandleHidCommand(const SwitchHidCommand *command);
|
||||
Result HandleNfcIrData(const uint8_t *nfc_ir);
|
||||
Result HandleNfcIrData(const u8 *nfc_ir);
|
||||
|
||||
Result HandleHidCommandGetDeviceInfo(const SwitchHidCommand *command);
|
||||
Result HandleHidCommandSetDataFormat(const SwitchHidCommand *command);
|
||||
|
@ -71,18 +67,18 @@ namespace ams::controller {
|
|||
|
||||
bool m_charging;
|
||||
bool m_ext_power;
|
||||
uint8_t m_battery;
|
||||
uint8_t m_led_pattern;
|
||||
u8 m_battery;
|
||||
u8 m_led_pattern;
|
||||
|
||||
SwitchButtonData m_buttons;
|
||||
SwitchAnalogStick m_left_stick;
|
||||
SwitchAnalogStick m_right_stick;
|
||||
Switch6AxisData m_motion_data[3];
|
||||
|
||||
uint16_t m_gyro_sensitivity;
|
||||
uint16_t m_acc_sensitivity;
|
||||
u16 m_gyro_sensitivity;
|
||||
u16 m_acc_sensitivity;
|
||||
|
||||
uint8_t m_input_report_mode;
|
||||
u8 m_input_report_mode;
|
||||
|
||||
bool m_enable_rumble;
|
||||
bool m_enable_motion;
|
||||
|
|
|
@ -41,26 +41,26 @@ namespace ams::controller {
|
|||
|
||||
void GamesirController::MapInputReport0x03(const GamesirReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x03.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x03.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x03.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x03.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x03.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x03.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x03.buttons.dpad == GamesirDpad2_S) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SE) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SW);
|
||||
m_buttons.dpad_up = (src->input0x03.buttons.dpad == GamesirDpad2_N) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NE) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NW);
|
||||
m_buttons.dpad_right = (src->input0x03.buttons.dpad == GamesirDpad2_E) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NE) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SE);
|
||||
m_buttons.dpad_left = (src->input0x03.buttons.dpad == GamesirDpad2_W) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NW) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SW);
|
||||
m_buttons.dpad_down = (src->input0x03.buttons.dpad == GamesirDpad2_S) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SE) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SW);
|
||||
m_buttons.dpad_up = (src->input0x03.buttons.dpad == GamesirDpad2_N) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NE) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NW);
|
||||
m_buttons.dpad_right = (src->input0x03.buttons.dpad == GamesirDpad2_E) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NE) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SE);
|
||||
m_buttons.dpad_left = (src->input0x03.buttons.dpad == GamesirDpad2_W) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_NW) ||
|
||||
(src->input0x03.buttons.dpad == GamesirDpad2_SW);
|
||||
|
||||
m_buttons.A = src->input0x03.buttons.B;
|
||||
m_buttons.B = src->input0x03.buttons.A;
|
||||
|
@ -87,12 +87,12 @@ namespace ams::controller {
|
|||
|
||||
void GamesirController::MapInputReport0xc4(const GamesirReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0xc4.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0xc4.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0xc4.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0xc4.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0xc4.buttons.dpad == GamesirDpad_S) ||
|
||||
|
|
|
@ -43,68 +43,68 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct GamesirStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct GamesirButtonData {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t LB : 1;
|
||||
uint8_t RB : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 LB : 1;
|
||||
u8 RB : 1;
|
||||
|
||||
uint8_t LT : 1;
|
||||
uint8_t RT : 1;
|
||||
uint8_t select : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t home : 1; // Only present in report 0x03
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 0;
|
||||
u8 LT : 1;
|
||||
u8 RT : 1;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 home : 1; // Only present in report 0x03
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t dpad;
|
||||
} __attribute__((packed));
|
||||
u8 dpad;
|
||||
} PACKED;
|
||||
|
||||
struct GamesirReport0x03 {
|
||||
GamesirButtonData buttons;
|
||||
GamesirStickData left_stick;
|
||||
GamesirStickData right_stick;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
uint8_t _unk[2];
|
||||
} __attribute__((packed));
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
u8 _unk[2];
|
||||
} PACKED;
|
||||
|
||||
struct GamesirReport0x12 {
|
||||
uint8_t : 3;
|
||||
uint8_t home : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 3;
|
||||
u8 home : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t _unk[2];
|
||||
} __attribute__((packed));
|
||||
u8 _unk[2];
|
||||
} PACKED;
|
||||
|
||||
struct GamesirReport0xc4 {
|
||||
GamesirStickData left_stick;
|
||||
GamesirStickData right_stick;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
GamesirButtonData buttons;
|
||||
uint8_t _unk;
|
||||
} __attribute__((packed));
|
||||
u8 _unk;
|
||||
} PACKED;
|
||||
|
||||
struct GamesirReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
GamesirReport0x03 input0x03;
|
||||
GamesirReport0x12 input0x12;
|
||||
GamesirReport0xc4 input0xc4;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class GamesirController : public EmulatedSwitchController {
|
||||
class GamesirController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -44,26 +44,26 @@ namespace ams::controller {
|
|||
|
||||
void GamestickController::MapInputReport0x03(const GamestickReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x03.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x03.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x03.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x03.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x03.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x03.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x03.dpad == GamestickDPad_S) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SE) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x03.dpad == GamestickDPad_N) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NE) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x03.dpad == GamestickDPad_E) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NE) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x03.dpad == GamestickDPad_W) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NW) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x03.dpad == GamestickDPad_S) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SE) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x03.dpad == GamestickDPad_N) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NE) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x03.dpad == GamestickDPad_E) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NE) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x03.dpad == GamestickDPad_W) ||
|
||||
(src->input0x03.dpad == GamestickDPad_NW) ||
|
||||
(src->input0x03.dpad == GamestickDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x03.buttons.B;
|
||||
m_buttons.B = src->input0x03.buttons.A;
|
||||
|
@ -82,7 +82,7 @@ namespace ams::controller {
|
|||
m_buttons.R = !m_buttons.ZR;
|
||||
}
|
||||
|
||||
m_buttons.plus = src->input0x03.buttons.start;
|
||||
m_buttons.plus = src->input0x03.buttons.start;
|
||||
|
||||
m_buttons.lstick_press = src->input0x03.buttons.lstick_press;
|
||||
m_buttons.rstick_press = src->input0x03.buttons.rstick_press;
|
||||
|
|
|
@ -31,58 +31,58 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct GamestickStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct GamestickInputReport0x01 {
|
||||
uint8_t _unk0;
|
||||
u8 _unk0;
|
||||
|
||||
struct {
|
||||
uint8_t : 4;
|
||||
uint8_t home : 1;
|
||||
uint8_t back : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 4;
|
||||
u8 home : 1;
|
||||
u8 back : 1;
|
||||
u8 : 0;
|
||||
} buttons;
|
||||
|
||||
uint8_t _unk1[6];
|
||||
} __attribute__((packed));
|
||||
u8 _unk1[6];
|
||||
} PACKED;
|
||||
|
||||
struct GamestickInputReport0x03 {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
GamestickStickData left_stick;
|
||||
GamestickStickData right_stick;
|
||||
uint8_t _unk0[2];
|
||||
u8 _unk0[2];
|
||||
|
||||
struct {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L : 1;
|
||||
uint8_t R : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L : 1;
|
||||
u8 R : 1;
|
||||
|
||||
uint8_t : 3;
|
||||
uint8_t start : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t lstick_press : 1;
|
||||
uint8_t rstick_press : 1;
|
||||
uint8_t : 1;
|
||||
u8 : 3;
|
||||
u8 start : 1;
|
||||
u8 : 1;
|
||||
u8 lstick_press : 1;
|
||||
u8 rstick_press : 1;
|
||||
u8 : 1;
|
||||
} buttons;
|
||||
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct GamestickReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
GamestickInputReport0x01 input0x01;
|
||||
GamestickInputReport0x03 input0x03;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class GamestickController : public EmulatedSwitchController {
|
||||
class GamestickController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -44,26 +44,26 @@ namespace ams::controller {
|
|||
|
||||
void GemboxController::MapInputReport0x07(const GemboxReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x07.left_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x07.left_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * -static_cast<s8>(~src->input0x07.left_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX + static_cast<s8>(~src->input0x07.left_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x07.right_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x07.right_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * -static_cast<s8>(~src->input0x07.right_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX + static_cast<s8>(~src->input0x07.right_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x07.dpad == GemboxDPad_S) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SE) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x07.dpad == GemboxDPad_N) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NE) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x07.dpad == GemboxDPad_E) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NE) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x07.dpad == GemboxDPad_W) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NW) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x07.dpad == GemboxDPad_S) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SE) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x07.dpad == GemboxDPad_N) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NE) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x07.dpad == GemboxDPad_E) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NE) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x07.dpad == GemboxDPad_W) ||
|
||||
(src->input0x07.dpad == GemboxDPad_NW) ||
|
||||
(src->input0x07.dpad == GemboxDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x07.buttons.B;
|
||||
m_buttons.B = src->input0x07.buttons.A;
|
||||
|
@ -75,7 +75,7 @@ namespace ams::controller {
|
|||
m_buttons.L = src->input0x07.buttons.LB;
|
||||
m_buttons.ZL = src->input0x07.left_trigger > 0;
|
||||
|
||||
m_buttons.plus = src->input0x07.buttons.start;
|
||||
m_buttons.plus = src->input0x07.buttons.start;
|
||||
|
||||
m_buttons.lstick_press = src->input0x07.buttons.L3;
|
||||
m_buttons.rstick_press = src->input0x07.buttons.R3;
|
||||
|
|
|
@ -31,58 +31,58 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct GemboxStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
u8 x;
|
||||
u8 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct GemboxButtonData {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t LB : 1;
|
||||
uint8_t RB : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 LB : 1;
|
||||
u8 RB : 1;
|
||||
|
||||
uint8_t : 3;
|
||||
uint8_t start : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 3;
|
||||
u8 start : 1;
|
||||
u8 : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct GemboxInputReport0x02 {
|
||||
union {
|
||||
struct {
|
||||
uint8_t : 6;
|
||||
uint8_t back : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 6;
|
||||
u8 back : 1;
|
||||
u8 : 0;
|
||||
};
|
||||
|
||||
uint8_t buttons;
|
||||
u8 buttons;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct GemboxInputReport0x07 {
|
||||
uint8_t dpad;
|
||||
GemboxStickData left_stick;
|
||||
GemboxStickData right_stick;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
GemboxButtonData buttons;
|
||||
} __attribute__((packed));
|
||||
u8 dpad;
|
||||
GemboxStickData left_stick;
|
||||
GemboxStickData right_stick;
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
GemboxButtonData buttons;
|
||||
} PACKED;
|
||||
|
||||
struct GemboxReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
GemboxInputReport0x02 input0x02;
|
||||
GemboxInputReport0x07 input0x07;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class GemboxController : public EmulatedSwitchController {
|
||||
class GemboxController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -34,18 +34,18 @@ namespace ams::controller {
|
|||
}
|
||||
|
||||
void HyperkinController::MapInputReport0x3f(const HyperkinReportData *src) {
|
||||
m_buttons.dpad_down = (src->input0x3f.buttons.dpad == HyperkinDPad_S) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SE) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x3f.buttons.dpad == HyperkinDPad_N) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NE) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x3f.buttons.dpad == HyperkinDPad_E) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NE) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x3f.buttons.dpad == HyperkinDPad_W) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NW) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x3f.buttons.dpad == HyperkinDPad_S) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SE) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x3f.buttons.dpad == HyperkinDPad_N) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NE) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x3f.buttons.dpad == HyperkinDPad_E) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NE) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x3f.buttons.dpad == HyperkinDPad_W) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_NW) ||
|
||||
(src->input0x3f.buttons.dpad == HyperkinDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x3f.buttons.A;
|
||||
m_buttons.B = src->input0x3f.buttons.B;
|
||||
|
|
|
@ -31,41 +31,41 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct HyperkinStickData {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
u16 x;
|
||||
u16 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct HyperkinButtonData {
|
||||
uint8_t B : 1;
|
||||
uint8_t A : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t L : 1;
|
||||
uint8_t R : 1;
|
||||
uint8_t : 0;
|
||||
u8 B : 1;
|
||||
u8 A : 1;
|
||||
u8 Y : 1;
|
||||
u8 X : 1;
|
||||
u8 L : 1;
|
||||
u8 R : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t select : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t : 0;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t dpad;
|
||||
} __attribute__((packed));
|
||||
u8 dpad;
|
||||
} PACKED;
|
||||
|
||||
struct HyperkinInputReport0x3f{
|
||||
HyperkinButtonData buttons;
|
||||
HyperkinStickData left_stick;
|
||||
HyperkinStickData right_stick;
|
||||
uint8_t unk;
|
||||
u8 unk;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct HyperkinReportData{
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
HyperkinInputReport0x3f input0x3f;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class HyperkinController : public EmulatedSwitchController {
|
||||
class HyperkinController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -19,17 +19,17 @@
|
|||
namespace ams::controller {
|
||||
|
||||
struct ICadeInputReport0x01 {
|
||||
uint8_t keys[9];
|
||||
} __attribute__((packed));
|
||||
u8 keys[9];
|
||||
} PACKED;
|
||||
|
||||
struct ICadeReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
ICadeInputReport0x01 input0x01;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class ICadeController : public EmulatedSwitchController {
|
||||
class ICadeController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -43,26 +43,26 @@ namespace ams::controller {
|
|||
|
||||
void IpegaController::MapInputReport0x07(const IpegaReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x07.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x07.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x07.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x07.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x07.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x07.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x07.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x07.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x07.buttons.dpad == IpegaDPad_S) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SE) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x07.buttons.dpad == IpegaDPad_N) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NE) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x07.buttons.dpad == IpegaDPad_E) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NE) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x07.buttons.dpad == IpegaDPad_W) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NW) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x07.buttons.dpad == IpegaDPad_S) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SE) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x07.buttons.dpad == IpegaDPad_N) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NE) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x07.buttons.dpad == IpegaDPad_E) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NE) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x07.buttons.dpad == IpegaDPad_W) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_NW) ||
|
||||
(src->input0x07.buttons.dpad == IpegaDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x07.buttons.B;
|
||||
m_buttons.B = src->input0x07.buttons.A;
|
||||
|
|
|
@ -31,54 +31,54 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct IpegaStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct IpegaButtonData {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t L3_g910 : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t R3_g910 : 1;
|
||||
uint8_t LB : 1;
|
||||
uint8_t RB : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 L3_g910 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 R3_g910 : 1;
|
||||
u8 LB : 1;
|
||||
u8 RB : 1;
|
||||
|
||||
uint8_t LT : 1;
|
||||
uint8_t RT : 1;
|
||||
uint8_t view : 1;
|
||||
uint8_t menu : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t lstick_press : 1;
|
||||
uint8_t rstick_press : 1;
|
||||
uint8_t : 0;
|
||||
} __attribute__((packed));
|
||||
u8 LT : 1;
|
||||
u8 RT : 1;
|
||||
u8 view : 1;
|
||||
u8 menu : 1;
|
||||
u8 : 1;
|
||||
u8 lstick_press : 1;
|
||||
u8 rstick_press : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct IpegaInputReport0x02 {
|
||||
uint8_t : 7;
|
||||
uint8_t home : 1;
|
||||
} __attribute__((packed));
|
||||
u8 : 7;
|
||||
u8 home : 1;
|
||||
} PACKED;
|
||||
|
||||
struct IpegaInputReport0x07 {
|
||||
IpegaStickData left_stick;
|
||||
IpegaStickData right_stick;
|
||||
IpegaButtonData buttons;
|
||||
uint8_t right_trigger;
|
||||
uint8_t left_trigger;
|
||||
} __attribute__((packed));
|
||||
IpegaStickData left_stick;
|
||||
IpegaStickData right_stick;
|
||||
IpegaButtonData buttons;
|
||||
u8 right_trigger;
|
||||
u8 left_trigger;
|
||||
} PACKED;
|
||||
|
||||
struct IpegaReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
IpegaInputReport0x02 input0x02;
|
||||
IpegaInputReport0x07 input0x07;
|
||||
};
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
class IpegaController : public EmulatedSwitchController {
|
||||
class IpegaController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -37,26 +37,26 @@ namespace ams::controller {
|
|||
|
||||
void LanShenController::MapInputReport0x01(const LanShenReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == LanShenDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == LanShenDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == LanShenDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == LanShenDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == LanShenDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == LanShenDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == LanShenDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == LanShenDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == LanShenDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x01.buttons.B;
|
||||
m_buttons.B = src->input0x01.buttons.A;
|
||||
|
|
|
@ -31,30 +31,30 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct LanShenStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
u8 x;
|
||||
u8 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct LanShenButtonData {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 1;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
u8 : 1;
|
||||
u8 start : 1;
|
||||
u8 : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 1;
|
||||
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
|
@ -62,17 +62,17 @@ namespace ams::controller {
|
|||
LanShenStickData left_stick;
|
||||
LanShenStickData right_stick;
|
||||
LanShenButtonData buttons;
|
||||
uint8_t _unk[4];
|
||||
u8 _unk[4];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct LanShenReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
LanShenInputReport0x01 input0x01;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class LanShenController : public EmulatedSwitchController {
|
||||
class LanShenController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -46,26 +46,26 @@ namespace ams::controller {
|
|||
|
||||
void MadCatzController::MapInputReport0x01(const MadCatzReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == MadCatzDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == MadCatzDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == MadCatzDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == MadCatzDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == MadCatzDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == MadCatzDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == MadCatzDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == MadCatzDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == MadCatzDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x01.buttons.B;
|
||||
m_buttons.B = src->input0x01.buttons.A;
|
||||
|
|
|
@ -31,46 +31,46 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct MadCatzStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
u8 x;
|
||||
u8 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MadCatzButtonData {
|
||||
uint8_t X : 1;
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
u8 X : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 Y : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
|
||||
uint8_t select : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t home : 1;
|
||||
uint8_t : 0;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 home : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MadCatzInputReport0x01 {
|
||||
MadCatzButtonData buttons;
|
||||
MadCatzStickData left_stick;
|
||||
MadCatzStickData right_stick;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MadCatzInputReport0x02 {
|
||||
uint8_t : 2;
|
||||
uint8_t volume_up : 1;
|
||||
uint8_t volume_down : 1;
|
||||
uint8_t play : 1;
|
||||
uint8_t forward : 1;
|
||||
uint8_t rewind : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 2;
|
||||
u8 volume_up : 1;
|
||||
u8 volume_down : 1;
|
||||
u8 play : 1;
|
||||
u8 forward : 1;
|
||||
u8 rewind : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MadCatzInputReport0x81 {
|
||||
|
@ -147,7 +147,7 @@ namespace ams::controller {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MadCatzReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
MadCatzInputReport0x01 input0x01;
|
||||
MadCatzInputReport0x02 input0x02;
|
||||
|
@ -155,9 +155,9 @@ namespace ams::controller {
|
|||
MadCatzInputReport0x82 input0x82;
|
||||
MadCatzInputReport0x83 input0x83;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class MadCatzController : public EmulatedSwitchController {
|
||||
class MadCatzController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -39,41 +39,41 @@ namespace ams::controller {
|
|||
|
||||
void MocuteController::MapInputReport(const MocuteReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
if (src->id == 0x01) {
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == MocuteDPad2_S) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == MocuteDPad2_N) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == MocuteDPad2_E) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == MocuteDPad2_W) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NW) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == MocuteDPad2_S) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == MocuteDPad2_N) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == MocuteDPad2_E) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == MocuteDPad2_W) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_NW) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad2_SW);
|
||||
}
|
||||
else {
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == MocuteDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == MocuteDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == MocuteDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == MocuteDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == MocuteDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == MocuteDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == MocuteDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == MocuteDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == MocuteDPad_SW);
|
||||
}
|
||||
|
||||
m_buttons.A = src->input0x01.buttons.B;
|
||||
|
|
|
@ -43,43 +43,43 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct MocuteStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
u8 x;
|
||||
u8 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MocuteButtonData {
|
||||
uint8_t dpad : 4;
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
u8 dpad : 4;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
uint8_t select : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MocuteInputReport0x01 {
|
||||
MocuteStickData left_stick;
|
||||
MocuteStickData right_stick;
|
||||
MocuteButtonData buttons;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MocuteReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
MocuteInputReport0x01 input0x01;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class MocuteController : public EmulatedSwitchController {
|
||||
class MocuteController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -39,26 +39,26 @@ namespace ams::controller {
|
|||
|
||||
void NvidiaShieldController::MapInputReport0x01(const NvidiaShieldReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == NvidiaShieldDPad_S) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SE) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == NvidiaShieldDPad_N) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NE) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == NvidiaShieldDPad_E) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NE) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == NvidiaShieldDPad_W) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NW) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == NvidiaShieldDPad_S) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SE) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == NvidiaShieldDPad_N) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NE) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == NvidiaShieldDPad_E) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NE) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == NvidiaShieldDPad_W) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_NW) ||
|
||||
(src->input0x01.dpad == NvidiaShieldDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x01.buttons.B;
|
||||
m_buttons.B = src->input0x01.buttons.A;
|
||||
|
|
|
@ -31,50 +31,50 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct NvidiaShieldStickData {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} __attribute__((packed));
|
||||
u16 x;
|
||||
u16 y;
|
||||
} PACKED;
|
||||
|
||||
struct NvidiaShieldButtonData {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t LB : 1;
|
||||
uint8_t RB : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 LB : 1;
|
||||
u8 RB : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
|
||||
uint8_t start : 1;
|
||||
uint8_t : 0;
|
||||
} __attribute__((packed));
|
||||
u8 start : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct NvidiaShieldInputReport0x01 {
|
||||
uint8_t _unk0; // maybe a counter?
|
||||
uint8_t dpad;
|
||||
u8 _unk0; // maybe a counter?
|
||||
u8 dpad;
|
||||
NvidiaShieldButtonData buttons;
|
||||
uint16_t left_trigger;
|
||||
uint16_t right_trigger;
|
||||
u16 left_trigger;
|
||||
u16 right_trigger;
|
||||
NvidiaShieldStickData left_stick;
|
||||
NvidiaShieldStickData right_stick;
|
||||
uint8_t home : 1;
|
||||
uint8_t back : 1;
|
||||
uint8_t : 0;
|
||||
} __attribute__((packed));
|
||||
u8 home : 1;
|
||||
u8 back : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct NvidiaShieldInputReport0x03 {
|
||||
uint8_t _unk[15];
|
||||
} __attribute__((packed));
|
||||
u8 _unk[15];
|
||||
} PACKED;
|
||||
|
||||
struct NvidiaShieldReportData{
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
NvidiaShieldInputReport0x01 input0x01;
|
||||
NvidiaShieldInputReport0x03 input0x03;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class NvidiaShieldController : public EmulatedSwitchController {
|
||||
class NvidiaShieldController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -44,18 +44,18 @@ namespace ams::controller {
|
|||
|
||||
void OuyaController::MapInputReport0x07(const OuyaReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x07.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x07.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x07.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x07.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x07.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x07.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x07.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x07.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = src->input0x07.buttons.dpad_down;
|
||||
m_buttons.dpad_up = src->input0x07.buttons.dpad_up;
|
||||
m_buttons.dpad_right = src->input0x07.buttons.dpad_right;
|
||||
m_buttons.dpad_left = src->input0x07.buttons.dpad_left;
|
||||
m_buttons.dpad_down = src->input0x07.buttons.dpad_down;
|
||||
m_buttons.dpad_up = src->input0x07.buttons.dpad_up;
|
||||
m_buttons.dpad_right = src->input0x07.buttons.dpad_right;
|
||||
m_buttons.dpad_left = src->input0x07.buttons.dpad_left;
|
||||
|
||||
m_buttons.A = src->input0x07.buttons.A;
|
||||
m_buttons.B = src->input0x07.buttons.O;
|
||||
|
@ -73,7 +73,7 @@ namespace ams::controller {
|
|||
m_buttons.lstick_press = src->input0x07.buttons.LS;
|
||||
m_buttons.rstick_press = src->input0x07.buttons.RS;
|
||||
|
||||
m_buttons.home = src->input0x07.buttons.center_hold;
|
||||
m_buttons.home = src->input0x07.buttons.center_hold;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,52 +19,52 @@
|
|||
namespace ams::controller {
|
||||
|
||||
struct OuyaStickData {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
u16 x;
|
||||
u16 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct OuyaButtonData {
|
||||
uint8_t O : 1;
|
||||
uint8_t U : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t A : 1;
|
||||
uint8_t LB : 1;
|
||||
uint8_t RB : 1;
|
||||
uint8_t LS : 1;
|
||||
uint8_t RS : 1;
|
||||
u8 O : 1;
|
||||
u8 U : 1;
|
||||
u8 Y : 1;
|
||||
u8 A : 1;
|
||||
u8 LB : 1;
|
||||
u8 RB : 1;
|
||||
u8 LS : 1;
|
||||
u8 RS : 1;
|
||||
|
||||
uint8_t dpad_up : 1;
|
||||
uint8_t dpad_down : 1;
|
||||
uint8_t dpad_left : 1;
|
||||
uint8_t dpad_right : 1;
|
||||
uint8_t LT : 1;
|
||||
uint8_t RT : 1;
|
||||
uint8_t center_press : 1;
|
||||
uint8_t center_hold : 1;
|
||||
u8 dpad_up : 1;
|
||||
u8 dpad_down : 1;
|
||||
u8 dpad_left : 1;
|
||||
u8 dpad_right : 1;
|
||||
u8 LT : 1;
|
||||
u8 RT : 1;
|
||||
u8 center_press : 1;
|
||||
u8 center_hold : 1;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct OuyaInputReport0x03 {
|
||||
uint8_t battery;
|
||||
uint8_t _unk[6];
|
||||
} __attribute__((packed));
|
||||
u8 battery;
|
||||
u8 _unk[6];
|
||||
} PACKED;
|
||||
|
||||
struct OuyaInputReport0x07 {
|
||||
OuyaStickData left_stick;
|
||||
OuyaStickData right_stick;
|
||||
uint16_t left_trigger;
|
||||
uint16_t right_trigger;
|
||||
OuyaButtonData buttons;
|
||||
} __attribute__((packed));
|
||||
OuyaStickData left_stick;
|
||||
OuyaStickData right_stick;
|
||||
u16 left_trigger;
|
||||
u16 right_trigger;
|
||||
OuyaButtonData buttons;
|
||||
} PACKED;
|
||||
|
||||
struct OuyaReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
OuyaInputReport0x03 input0x03;
|
||||
OuyaInputReport0x07 input0x07;
|
||||
OuyaInputReport0x03 input0x03;
|
||||
OuyaInputReport0x07 input0x07;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class OuyaController : public EmulatedSwitchController {
|
||||
class OuyaController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -40,26 +40,26 @@ namespace ams::controller {
|
|||
m_battery = convert_battery_255(src->input0x03.battery);
|
||||
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x03.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x03.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x03.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x03.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x03.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x03.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x03.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x03.buttons.dpad == PowerADPad_S) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SE) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x03.buttons.dpad == PowerADPad_N) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NE) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x03.buttons.dpad == PowerADPad_E) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NE) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x03.buttons.dpad == PowerADPad_W) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NW) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x03.buttons.dpad == PowerADPad_S) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SE) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x03.buttons.dpad == PowerADPad_N) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NE) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x03.buttons.dpad == PowerADPad_E) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NE) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x03.buttons.dpad == PowerADPad_W) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_NW) ||
|
||||
(src->input0x03.buttons.dpad == PowerADPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x03.buttons.B;
|
||||
m_buttons.B = src->input0x03.buttons.A;
|
||||
|
|
|
@ -31,44 +31,44 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct PowerAStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct PowerAButtonData {
|
||||
uint8_t dpad : 4;
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
u8 dpad : 4;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
uint8_t select : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 0;
|
||||
} __attribute__((packed));
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
u8 select : 1;
|
||||
u8 start : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct PowerAInputReport0x03 {
|
||||
PowerAStickData left_stick;
|
||||
PowerAStickData right_stick;
|
||||
PowerAButtonData buttons;
|
||||
uint8_t L2;
|
||||
uint8_t R2;
|
||||
uint8_t battery;
|
||||
uint8_t _unk;
|
||||
} __attribute__((packed));
|
||||
u8 L2;
|
||||
u8 R2;
|
||||
u8 battery;
|
||||
u8 _unk;
|
||||
} PACKED;
|
||||
|
||||
struct PowerAReportData{
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
PowerAInputReport0x03 input0x03;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class PowerAController : public EmulatedSwitchController {
|
||||
class PowerAController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -37,26 +37,26 @@ namespace ams::controller {
|
|||
|
||||
void RazerController::MapInputReport0x01(const RazerReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == RazerDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == RazerDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == RazerDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == RazerDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.buttons.dpad == RazerDPad_S) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SE) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.buttons.dpad == RazerDPad_N) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.buttons.dpad == RazerDPad_E) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NE) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.buttons.dpad == RazerDPad_W) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_NW) ||
|
||||
(src->input0x01.buttons.dpad == RazerDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x01.buttons.B;
|
||||
m_buttons.B = src->input0x01.buttons.A;
|
||||
|
|
|
@ -31,47 +31,46 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct RazerStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct RazerButtonData {
|
||||
uint8_t dpad : 4;
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
u8 dpad : 4;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
uint8_t back : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t home : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
u8 back : 1;
|
||||
u8 start : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 1;
|
||||
u8 home : 1;
|
||||
|
||||
uint8_t select : 1;
|
||||
uint8_t : 0;
|
||||
} __attribute__((packed));
|
||||
u8 select : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct RazerInputReport0x01 {
|
||||
RazerStickData left_stick;
|
||||
RazerStickData right_stick;
|
||||
RazerButtonData buttons;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
} __attribute__((packed));
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
} PACKED;
|
||||
|
||||
struct RazerReportData{
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
RazerInputReport0x01 input0x01;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
|
||||
class RazerController : public EmulatedSwitchController {
|
||||
class RazerController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -43,26 +43,26 @@ namespace ams::controller {
|
|||
|
||||
void SteelseriesController::MapInputReport0x01(const SteelseriesReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x01.left_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x01.left_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * -static_cast<s8>(~src->input0x01.left_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX + static_cast<s8>(~src->input0x01.left_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input0x01.right_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX + static_cast<int8_t>(~src->input0x01.right_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * -static_cast<s8>(~src->input0x01.right_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX + static_cast<s8>(~src->input0x01.right_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == SteelseriesDPad_S) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SE) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == SteelseriesDPad_N) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NE) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == SteelseriesDPad_E) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NE) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == SteelseriesDPad_W) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NW) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x01.dpad == SteelseriesDPad_S) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SE) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x01.dpad == SteelseriesDPad_N) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NE) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x01.dpad == SteelseriesDPad_E) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NE) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x01.dpad == SteelseriesDPad_W) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_NW) ||
|
||||
(src->input0x01.dpad == SteelseriesDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x01.buttons.B;
|
||||
m_buttons.B = src->input0x01.buttons.A;
|
||||
|
@ -82,26 +82,26 @@ namespace ams::controller {
|
|||
|
||||
void SteelseriesController::MapInputReport0xc4(const SteelseriesReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0xc4.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0xc4.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0xc4.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0xc4.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0xc4.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0xc4.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0xc4.dpad == SteelseriesDPad2_S) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SE) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SW);
|
||||
m_buttons.dpad_up = (src->input0xc4.dpad == SteelseriesDPad2_N) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NE) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NW);
|
||||
m_buttons.dpad_right = (src->input0xc4.dpad == SteelseriesDPad2_E) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NE) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SE);
|
||||
m_buttons.dpad_left = (src->input0xc4.dpad == SteelseriesDPad2_W) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NW) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SW);
|
||||
m_buttons.dpad_down = (src->input0xc4.dpad == SteelseriesDPad2_S) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SE) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SW);
|
||||
m_buttons.dpad_up = (src->input0xc4.dpad == SteelseriesDPad2_N) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NE) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NW);
|
||||
m_buttons.dpad_right = (src->input0xc4.dpad == SteelseriesDPad2_E) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NE) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SE);
|
||||
m_buttons.dpad_left = (src->input0xc4.dpad == SteelseriesDPad2_W) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_NW) ||
|
||||
(src->input0xc4.dpad == SteelseriesDPad2_SW);
|
||||
|
||||
m_buttons.A = src->input0xc4.buttons.B;
|
||||
m_buttons.B = src->input0xc4.buttons.A;
|
||||
|
@ -122,12 +122,12 @@ namespace ams::controller {
|
|||
|
||||
void SteelseriesController::MapMfiInputReport(const SteelseriesReportData *src) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input_mfi.left_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (-static_cast<int8_t>(~src->input_mfi.left_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * -static_cast<s8>(~src->input_mfi.left_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (-static_cast<s8>(~src->input_mfi.left_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * -static_cast<int8_t>(~src->input_mfi.right_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (-static_cast<int8_t>(~src->input_mfi.right_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * -static_cast<s8>(~src->input_mfi.right_stick.x + 1) + 0x7ff) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (-static_cast<s8>(~src->input_mfi.right_stick.y + 1)) + 0x7ff) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_up = src->input_mfi.buttons.dpad_up > 0;
|
||||
|
|
|
@ -43,102 +43,102 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct SteelseriesStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
u8 x;
|
||||
u8 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SteelseriesButtonData {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L : 1;
|
||||
uint8_t R : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L : 1;
|
||||
u8 R : 1;
|
||||
|
||||
uint8_t : 3;
|
||||
uint8_t start : 1;
|
||||
uint8_t select : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 3;
|
||||
u8 start : 1;
|
||||
u8 select : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SteelseriesButtonData2 {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
uint8_t start : 1;
|
||||
uint8_t select : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L3 : 1;
|
||||
uint8_t R3 : 1;
|
||||
uint8_t : 0;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
u8 start : 1;
|
||||
u8 select : 1;
|
||||
u8 : 1;
|
||||
u8 L3 : 1;
|
||||
u8 R3 : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SteelseriesMfiButtonData {
|
||||
uint8_t dpad_up;
|
||||
uint8_t dpad_right;
|
||||
uint8_t dpad_down;
|
||||
uint8_t dpad_left;
|
||||
uint8_t A;
|
||||
uint8_t B;
|
||||
uint8_t X;
|
||||
uint8_t Y;
|
||||
uint8_t L1;
|
||||
uint8_t R1;
|
||||
uint8_t L2;
|
||||
uint8_t R2;
|
||||
u8 dpad_up;
|
||||
u8 dpad_right;
|
||||
u8 dpad_down;
|
||||
u8 dpad_left;
|
||||
u8 A;
|
||||
u8 B;
|
||||
u8 X;
|
||||
u8 Y;
|
||||
u8 L1;
|
||||
u8 R1;
|
||||
u8 L2;
|
||||
u8 R2;
|
||||
|
||||
uint8_t menu : 1;
|
||||
uint8_t : 0;
|
||||
u8 menu : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SteelseriesMfiInputReport {
|
||||
SteelseriesMfiButtonData buttons;
|
||||
SteelseriesStickData left_stick;
|
||||
SteelseriesStickData right_stick;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct SteelseriesInputReport0x01 {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
SteelseriesStickData left_stick;
|
||||
SteelseriesStickData right_stick;
|
||||
SteelseriesButtonData buttons;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct SteelseriesInputReport0x12 {
|
||||
uint8_t : 3;
|
||||
uint8_t home : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 3;
|
||||
u8 home : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t _unk0[2];
|
||||
u8 _unk0[2];
|
||||
|
||||
uint8_t _unk1; // Maybe battery
|
||||
u8 _unk1; // Maybe battery
|
||||
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct SteelseriesInputReport0xc4 {
|
||||
SteelseriesStickData left_stick;
|
||||
SteelseriesStickData right_stick;
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
SteelseriesButtonData2 buttons;
|
||||
uint8_t dpad;
|
||||
uint8_t _unk[2];
|
||||
} __attribute__((packed));
|
||||
u8 dpad;
|
||||
u8 _unk[2];
|
||||
} PACKED;
|
||||
|
||||
struct SteelseriesReportData {
|
||||
union {
|
||||
struct {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
SteelseriesInputReport0x01 input0x01;
|
||||
SteelseriesInputReport0x12 input0x12;
|
||||
|
@ -148,9 +148,9 @@ namespace ams::controller {
|
|||
|
||||
SteelseriesMfiInputReport input_mfi;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class SteelseriesController : public EmulatedSwitchController {
|
||||
class SteelseriesController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -17,27 +17,27 @@
|
|||
|
||||
namespace ams::controller {
|
||||
|
||||
void SwitchAnalogStick::SetData(uint16_t x, uint16_t y) {
|
||||
void SwitchAnalogStick::SetData(u16 x, u16 y) {
|
||||
m_xy[0] = x & 0xff;
|
||||
m_xy[1] = (x >> 8) | ((y & 0xff) << 4);
|
||||
m_xy[2] = (y >> 4) & 0xff;
|
||||
}
|
||||
|
||||
void SwitchAnalogStick::SetX(uint16_t x) {
|
||||
void SwitchAnalogStick::SetX(u16 x) {
|
||||
m_xy[0] = x & 0xff;
|
||||
m_xy[1] = (m_xy[1] & 0xf0) | (x >> 8);
|
||||
}
|
||||
|
||||
void SwitchAnalogStick::SetY(uint16_t y) {
|
||||
void SwitchAnalogStick::SetY(u16 y) {
|
||||
m_xy[1] = (m_xy[1] & 0x0f) | ((y & 0xff) << 4);
|
||||
m_xy[2] = (y >> 4) & 0xff;
|
||||
}
|
||||
|
||||
uint16_t SwitchAnalogStick::GetX() {
|
||||
u16 SwitchAnalogStick::GetX() {
|
||||
return m_xy[0] | ((m_xy[1] & 0xf) << 8);
|
||||
}
|
||||
|
||||
uint16_t SwitchAnalogStick::GetY() {
|
||||
u16 SwitchAnalogStick::GetY() {
|
||||
return (m_xy[1] >> 4) | (m_xy[2] << 4);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,27 +18,27 @@
|
|||
|
||||
namespace ams::controller {
|
||||
|
||||
constexpr auto UINT12_MAX = 0xfff;
|
||||
constexpr auto STICK_ZERO = 0x800;
|
||||
constexpr auto UINT12_MAX = 0xfff;
|
||||
constexpr auto STICK_ZERO = 0x800;
|
||||
|
||||
struct SwitchAnalogStick {
|
||||
void SetData(uint16_t x, uint16_t y);
|
||||
void SetX(uint16_t x);
|
||||
void SetY(uint16_t y);
|
||||
uint16_t GetX();
|
||||
uint16_t GetY();
|
||||
void SetData(u16 x, u16 y);
|
||||
void SetX(u16 x);
|
||||
void SetY(u16 y);
|
||||
u16 GetX();
|
||||
u16 GetY();
|
||||
void InvertX();
|
||||
void InvertY();
|
||||
|
||||
uint8_t m_xy[3];
|
||||
u8 m_xy[3];
|
||||
};
|
||||
|
||||
struct SwitchAnalogStickFactoryCalibration {
|
||||
uint8_t calib[9];
|
||||
u8 calib[9];
|
||||
};
|
||||
|
||||
struct SwitchAnalogStickParameters {
|
||||
uint8_t stickvalues[18];
|
||||
u8 stickvalues[18];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ams::controller {
|
|||
|
||||
namespace {
|
||||
|
||||
const uint8_t led_player_mappings[] = {
|
||||
const u8 led_player_mappings[] = {
|
||||
SwitchPlayerNumber_Unknown, //0000
|
||||
SwitchPlayerNumber_One, //0001
|
||||
SwitchPlayerNumber_Unknown, //0010
|
||||
|
@ -42,12 +42,13 @@ namespace ams::controller {
|
|||
|
||||
}
|
||||
|
||||
Result LedsMaskToPlayerNumber(uint8_t led_mask, uint8_t *player_number) {
|
||||
Result LedsMaskToPlayerNumber(u8 led_mask, u8 *player_number) {
|
||||
*player_number = led_player_mappings[led_mask & 0xf];
|
||||
if (*player_number == SwitchPlayerNumber_Unknown)
|
||||
if (*player_number == SwitchPlayerNumber_Unknown) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
std::string GetControllerDirectory(const bluetooth::Address *address) {
|
||||
|
@ -64,10 +65,11 @@ namespace ams::controller {
|
|||
}
|
||||
|
||||
Result SwitchController::Initialize() {
|
||||
if (this->HasSetTsiDisableFlag())
|
||||
if (this->HasSetTsiDisableFlag()) {
|
||||
m_settsi_supported = false;
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
bool SwitchController::HasSetTsiDisableFlag() {
|
||||
|
@ -106,7 +108,7 @@ namespace ams::controller {
|
|||
if (input_report->type0x21.hid_command_response.id == HidCommand_SerialFlashRead) {
|
||||
if (input_report->type0x21.hid_command_response.data.serial_flash_read.address == 0x6050) {
|
||||
if (ams::mitm::GetSystemLanguage() == 10) {
|
||||
uint8_t data[] = {0xff, 0xd7, 0x00, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7};
|
||||
u8 data[] = {0xff, 0xd7, 0x00, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7, 0x00, 0x57, 0xb7};
|
||||
std::memcpy(input_report->type0x21.hid_command_response.data.serial_flash_read.data, data, sizeof(data));
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +117,7 @@ namespace ams::controller {
|
|||
|
||||
this->ApplyButtonCombos(&input_report->buttons);
|
||||
|
||||
return bluetooth::hid::report::WriteHidDataReport(m_address, &m_input_report);
|
||||
R_RETURN(bluetooth::hid::report::WriteHidDataReport(m_address, &m_input_report));
|
||||
}
|
||||
|
||||
Result SwitchController::HandleSetReportEvent(const bluetooth::HidReportEventInfo *event_info) {
|
||||
|
@ -123,10 +125,11 @@ namespace ams::controller {
|
|||
if (m_future_responses.back()->GetType() == BtdrvHidEventType_SetReport) {
|
||||
m_future_responses.back()->SetData(*event_info);
|
||||
}
|
||||
return ams::ResultSuccess();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
return bluetooth::hid::report::WriteHidSetReport(m_address, event_info->set_report.res);
|
||||
R_RETURN(bluetooth::hid::report::WriteHidSetReport(m_address, event_info->set_report.res));
|
||||
}
|
||||
|
||||
Result SwitchController::HandleGetReportEvent(const bluetooth::HidReportEventInfo *event_info) {
|
||||
|
@ -134,22 +137,23 @@ namespace ams::controller {
|
|||
if (m_future_responses.back()->GetType() == BtdrvHidEventType_GetReport) {
|
||||
m_future_responses.back()->SetData(*event_info);
|
||||
}
|
||||
return ams::ResultSuccess();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
auto report = hos::GetVersion() >= hos::Version_9_0_0 ? &event_info->get_report.v9.report : reinterpret_cast<const bluetooth::HidReport *>(&event_info->get_report.v1.report);
|
||||
return bluetooth::hid::report::WriteHidGetReport(m_address, report);
|
||||
R_RETURN(bluetooth::hid::report::WriteHidGetReport(m_address, report));
|
||||
}
|
||||
|
||||
Result SwitchController::HandleOutputDataReport(const bluetooth::HidReport *report) {
|
||||
return this->WriteDataReport(report);
|
||||
R_RETURN(this->WriteDataReport(report));
|
||||
}
|
||||
|
||||
Result SwitchController::WriteDataReport(const bluetooth::HidReport *report) {
|
||||
return btdrvWriteHidData(m_address, report);
|
||||
R_RETURN(btdrvWriteHidData(m_address, report));
|
||||
}
|
||||
|
||||
Result SwitchController::WriteDataReport(const bluetooth::HidReport *report, uint8_t response_id, bluetooth::HidReport *out_report) {
|
||||
Result SwitchController::WriteDataReport(const bluetooth::HidReport *report, u8 response_id, bluetooth::HidReport *out_report) {
|
||||
auto response = std::make_shared<HidResponse>(BtdrvHidEventType_Data);
|
||||
response->SetUserData(response_id);
|
||||
m_future_responses.push(response);
|
||||
|
@ -175,7 +179,7 @@ namespace ams::controller {
|
|||
out_report->size = data_report->size;
|
||||
std::memcpy(&out_report->data, &data_report->data, data_report->size);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result SwitchController::SetFeatureReport(const bluetooth::HidReport *report) {
|
||||
|
@ -194,7 +198,7 @@ namespace ams::controller {
|
|||
return response_data.set_report.res;
|
||||
}
|
||||
|
||||
Result SwitchController::GetFeatureReport(uint8_t id, bluetooth::HidReport *out_report) {
|
||||
Result SwitchController::GetFeatureReport(u8 id, bluetooth::HidReport *out_report) {
|
||||
auto response = std::make_shared<HidResponse>(BtdrvHidEventType_GetReport);
|
||||
m_future_responses.push(response);
|
||||
ON_SCOPE_EXIT { m_future_responses.pop(); };
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
|
||||
namespace ams::controller {
|
||||
|
||||
using HidResponse = FutureResponse<bluetooth::HidEventType, bluetooth::HidReportEventInfo, uint8_t>;
|
||||
using HidResponse = FutureResponse<bluetooth::HidEventType, bluetooth::HidReportEventInfo, u8>;
|
||||
|
||||
constexpr auto BATTERY_MAX = 8;
|
||||
|
||||
enum SwitchPlayerNumber : uint8_t {
|
||||
enum SwitchPlayerNumber : u8 {
|
||||
SwitchPlayerNumber_One,
|
||||
SwitchPlayerNumber_Two,
|
||||
SwitchPlayerNumber_Three,
|
||||
|
@ -39,14 +39,14 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct HardwareID {
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
u16 vid;
|
||||
u16 pid;
|
||||
};
|
||||
|
||||
struct RGBColour {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct ProControllerColours {
|
||||
|
@ -57,75 +57,75 @@ namespace ams::controller {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SwitchButtonData {
|
||||
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;
|
||||
u8 Y : 1;
|
||||
u8 X : 1;
|
||||
u8 B : 1;
|
||||
u8 A : 1;
|
||||
u8 : 2; // SR, SL (Right Joy)
|
||||
u8 R : 1;
|
||||
u8 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;
|
||||
u8 minus : 1;
|
||||
u8 plus : 1;
|
||||
u8 rstick_press : 1;
|
||||
u8 lstick_press : 1;
|
||||
u8 home : 1;
|
||||
u8 capture : 1;
|
||||
u8 : 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;
|
||||
u8 dpad_down : 1;
|
||||
u8 dpad_up : 1;
|
||||
u8 dpad_right : 1;
|
||||
u8 dpad_left : 1;
|
||||
u8 : 2; // SR, SL (Left Joy)
|
||||
u8 L : 1;
|
||||
u8 ZL : 1;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct Switch6AxisData {
|
||||
int16_t accel_x;
|
||||
int16_t accel_y;
|
||||
int16_t accel_z;
|
||||
int16_t gyro_1;
|
||||
int16_t gyro_2;
|
||||
int16_t gyro_3;
|
||||
s16 accel_x;
|
||||
s16 accel_y;
|
||||
s16 accel_z;
|
||||
s16 gyro_1;
|
||||
s16 gyro_2;
|
||||
s16 gyro_3;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct Switch6AxisCalibrationData {
|
||||
struct {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
s16 x;
|
||||
s16 y;
|
||||
s16 z;
|
||||
} acc_bias;
|
||||
|
||||
struct {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
s16 x;
|
||||
s16 y;
|
||||
s16 z;
|
||||
} acc_sensitivity;
|
||||
|
||||
struct {
|
||||
int16_t roll;
|
||||
int16_t pitch;
|
||||
int16_t yaw;
|
||||
s16 roll;
|
||||
s16 pitch;
|
||||
s16 yaw;
|
||||
} gyro_bias;
|
||||
|
||||
struct {
|
||||
int16_t roll;
|
||||
int16_t pitch;
|
||||
int16_t yaw;
|
||||
s16 roll;
|
||||
s16 pitch;
|
||||
s16 yaw;
|
||||
} gyro_sensitivity;
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
struct Switch6AxisHorizontalOffset {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
} __attribute__((packed));
|
||||
s16 x;
|
||||
s16 y;
|
||||
s16 z;
|
||||
} PACKED;
|
||||
|
||||
struct SwitchRumbleDataEncoded {
|
||||
uint8_t left_motor[4];
|
||||
uint8_t right_motor[4];
|
||||
u8 left_motor[4];
|
||||
u8 right_motor[4];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SwitchRumbleData {
|
||||
|
@ -135,7 +135,7 @@ namespace ams::controller {
|
|||
float low_band_amp;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
enum HidCommandType : uint8_t {
|
||||
enum HidCommandType : u8 {
|
||||
HidCommand_PairingOut = 0x01,
|
||||
HidCommand_GetDeviceInfo = 0x02,
|
||||
HidCommand_SetDataFormat = 0x03,
|
||||
|
@ -169,36 +169,36 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct SwitchHidCommand {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
uint8_t data[0x26];
|
||||
u8 data[0x26];
|
||||
|
||||
struct {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
} set_data_format;
|
||||
|
||||
struct {
|
||||
uint32_t address;
|
||||
uint8_t size;
|
||||
u32 address;
|
||||
u8 size;
|
||||
} serial_flash_read;
|
||||
|
||||
struct {
|
||||
uint32_t address;
|
||||
uint8_t size;
|
||||
uint8_t data[];
|
||||
u32 address;
|
||||
u8 size;
|
||||
u8 data[];
|
||||
} serial_flash_write;
|
||||
|
||||
struct {
|
||||
uint32_t address;
|
||||
u32 address;
|
||||
} serial_flash_sector_erase;
|
||||
|
||||
struct {
|
||||
union {
|
||||
uint8_t leds;
|
||||
u8 leds;
|
||||
|
||||
struct {
|
||||
uint8_t leds_flash : 4;
|
||||
uint8_t leds_on : 4;
|
||||
u8 leds_flash : 4;
|
||||
u8 leds_on : 4;
|
||||
};
|
||||
};
|
||||
} set_indicator_led;
|
||||
|
@ -208,10 +208,10 @@ namespace ams::controller {
|
|||
} sensor_sleep;
|
||||
|
||||
struct {
|
||||
uint8_t gyro_sensitivity;
|
||||
uint8_t acc_sensitivity;
|
||||
uint8_t gyro_perf_rate;
|
||||
uint8_t acc_aa_bandwidth;
|
||||
u8 gyro_sensitivity;
|
||||
u8 acc_sensitivity;
|
||||
u8 gyro_perf_rate;
|
||||
u8 acc_aa_bandwidth;
|
||||
} sensor_config;
|
||||
|
||||
struct {
|
||||
|
@ -221,21 +221,21 @@ namespace ams::controller {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SwitchHidCommandResponse {
|
||||
uint8_t ack;
|
||||
uint8_t id;
|
||||
u8 ack;
|
||||
u8 id;
|
||||
union {
|
||||
uint8_t raw[0x23];
|
||||
u8 raw[0x23];
|
||||
|
||||
struct {
|
||||
struct {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
u8 major;
|
||||
u8 minor;
|
||||
} fw_ver;
|
||||
uint8_t type;
|
||||
uint8_t _unk0; // Always 0x02
|
||||
u8 type;
|
||||
u8 _unk0; // Always 0x02
|
||||
bluetooth::Address address;
|
||||
uint8_t _unk1; // Always 0x01
|
||||
uint8_t _unk2; // If 01, colors in SPI are used. Otherwise default ones
|
||||
u8 _unk1; // Always 0x01
|
||||
u8 _unk2; // If 01, colors in SPI are used. Otherwise default ones
|
||||
} __attribute__ ((__packed__)) get_device_info;
|
||||
|
||||
struct {
|
||||
|
@ -243,26 +243,26 @@ namespace ams::controller {
|
|||
} shipment;
|
||||
|
||||
struct {
|
||||
uint32_t address;
|
||||
uint8_t size;
|
||||
uint8_t data[];
|
||||
u32 address;
|
||||
u8 size;
|
||||
u8 data[];
|
||||
} serial_flash_read;
|
||||
|
||||
struct {
|
||||
uint8_t status;
|
||||
u8 status;
|
||||
} serial_flash_write;
|
||||
|
||||
struct {
|
||||
uint8_t status;
|
||||
u8 status;
|
||||
} serial_flash_sector_erase;
|
||||
|
||||
struct {
|
||||
union {
|
||||
uint8_t leds;
|
||||
u8 leds;
|
||||
|
||||
struct {
|
||||
uint8_t leds_flash : 4;
|
||||
uint8_t leds_on : 4;
|
||||
u8 leds_flash : 4;
|
||||
u8 leds_on : 4;
|
||||
};
|
||||
};
|
||||
} get_indicator_led;
|
||||
|
@ -270,18 +270,18 @@ namespace ams::controller {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SwitchNfcIrResponse {
|
||||
uint8_t data[0x138];
|
||||
u8 data[0x138];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SwitchInputReport {
|
||||
uint8_t id;
|
||||
uint8_t timer;
|
||||
uint8_t conn_info : 4;
|
||||
uint8_t battery : 4;
|
||||
u8 id;
|
||||
u8 timer;
|
||||
u8 conn_info : 4;
|
||||
u8 battery : 4;
|
||||
SwitchButtonData buttons;
|
||||
SwitchAnalogStick left_stick;
|
||||
SwitchAnalogStick right_stick;
|
||||
uint8_t vibrator;
|
||||
u8 vibrator;
|
||||
|
||||
union {
|
||||
struct {
|
||||
|
@ -289,7 +289,7 @@ namespace ams::controller {
|
|||
} type0x21;
|
||||
|
||||
struct {
|
||||
uint8_t mcu_fw_data[37];
|
||||
u8 mcu_fw_data[37];
|
||||
} type0x23;
|
||||
|
||||
struct {
|
||||
|
@ -299,14 +299,14 @@ namespace ams::controller {
|
|||
struct {
|
||||
Switch6AxisData motion_data[3]; // IMU samples at 0, 5 and 10ms
|
||||
SwitchNfcIrResponse nfc_ir_response;
|
||||
uint8_t crc;
|
||||
u8 crc;
|
||||
} type0x31;
|
||||
};
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct SwitchOutputReport {
|
||||
uint8_t id;
|
||||
uint8_t counter;
|
||||
u8 id;
|
||||
u8 counter;
|
||||
SwitchRumbleDataEncoded rumble_data;
|
||||
|
||||
union {
|
||||
|
@ -315,12 +315,12 @@ namespace ams::controller {
|
|||
} type0x01;
|
||||
|
||||
struct {
|
||||
uint8_t nfc_ir_data[0x16];
|
||||
u8 nfc_ir_data[0x16];
|
||||
} type0x11;
|
||||
};
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
Result LedsMaskToPlayerNumber(uint8_t led_mask, uint8_t *player_number);
|
||||
Result LedsMaskToPlayerNumber(u8 led_mask, u8 *player_number);
|
||||
|
||||
std::string GetControllerDirectory(const bluetooth::Address *address);
|
||||
|
||||
|
@ -361,9 +361,9 @@ namespace ams::controller {
|
|||
|
||||
protected:
|
||||
Result WriteDataReport(const bluetooth::HidReport *report);
|
||||
Result WriteDataReport(const bluetooth::HidReport *report, uint8_t response_id, bluetooth::HidReport *out_report);
|
||||
Result WriteDataReport(const bluetooth::HidReport *report, u8 response_id, bluetooth::HidReport *out_report);
|
||||
Result SetFeatureReport(const bluetooth::HidReport *report);
|
||||
Result GetFeatureReport(uint8_t id, bluetooth::HidReport *out_report);
|
||||
Result GetFeatureReport(u8 id, bluetooth::HidReport *out_report);
|
||||
|
||||
virtual void UpdateControllerState(const bluetooth::HidReport *report);
|
||||
virtual void ApplyButtonCombos(SwitchButtonData *buttons);
|
||||
|
|
|
@ -49,19 +49,19 @@ namespace ams::controller {
|
|||
// Make sure that all memory regions that we care about are initialised with defaults
|
||||
R_TRY(this->EnsureInitialized());
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result VirtualSpiFlash::Read(int offset, void *data, size_t size) {
|
||||
return fs::ReadFile(m_virtual_memory_file, offset, data, size);
|
||||
R_RETURN(fs::ReadFile(m_virtual_memory_file, offset, data, size));
|
||||
}
|
||||
|
||||
Result VirtualSpiFlash::Write(int offset, const void *data, size_t size) {
|
||||
return fs::WriteFile(m_virtual_memory_file, offset, data, size, fs::WriteOption::Flush);
|
||||
R_RETURN(fs::WriteFile(m_virtual_memory_file, offset, data, size, fs::WriteOption::Flush));
|
||||
}
|
||||
|
||||
Result VirtualSpiFlash::SectorErase(int offset) {
|
||||
uint8_t buff[64];
|
||||
u8 buff[64];
|
||||
std::memset(buff, 0xff, sizeof(buff));
|
||||
|
||||
// Fill sector at offset with 0xff
|
||||
|
@ -73,22 +73,23 @@ namespace ams::controller {
|
|||
|
||||
R_TRY(fs::FlushFile(m_virtual_memory_file));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result VirtualSpiFlash::CheckMemoryRegion(int offset, size_t size, bool *is_initialized) {
|
||||
auto data = std::unique_ptr<uint8_t[]>(new uint8_t[size]());
|
||||
auto data = std::unique_ptr<u8[]>(new u8[size]());
|
||||
|
||||
R_TRY(this->Read(offset, data.get(), size));
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (data[i] != 0xff) {
|
||||
*is_initialized = true;
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
*is_initialized = false;
|
||||
return ams::ResultSuccess();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result VirtualSpiFlash::CreateFile(const char *path) {
|
||||
|
@ -99,7 +100,7 @@ namespace ams::controller {
|
|||
ON_SCOPE_EXIT { fs::CloseFile(m_virtual_memory_file); };
|
||||
|
||||
// Fill the file with 0xff
|
||||
uint8_t buff[64];
|
||||
u8 buff[64];
|
||||
std::memset(buff, 0xff, sizeof(buff));
|
||||
unsigned int offset = 0;
|
||||
while (offset < spi_flash_size) {
|
||||
|
@ -110,7 +111,7 @@ namespace ams::controller {
|
|||
|
||||
R_TRY(fs::FlushFile(m_virtual_memory_file));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result VirtualSpiFlash::EnsureMemoryRegion(int offset, const void *data, size_t size) {
|
||||
|
@ -120,7 +121,7 @@ namespace ams::controller {
|
|||
R_TRY(fs::WriteFile(m_virtual_memory_file, offset, data, size, fs::WriteOption::None));
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result VirtualSpiFlash::EnsureInitialized() {
|
||||
|
@ -157,7 +158,7 @@ namespace ams::controller {
|
|||
|
||||
R_TRY(fs::FlushFile(m_virtual_memory_file));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ namespace ams::controller {
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr uint8_t init_data1[] = {0x55};
|
||||
constexpr uint8_t init_data2[] = {0x00};
|
||||
constexpr u8 init_data1[] = {0x55};
|
||||
constexpr u8 init_data2[] = {0x00};
|
||||
|
||||
constexpr float nunchuck_stick_scale_factor = float(UINT12_MAX) / 0xb8;
|
||||
constexpr float wiiu_scale_factor = 2.0;
|
||||
|
@ -33,14 +33,14 @@ namespace ams::controller {
|
|||
constexpr float accel_scale_factor = 65535 / 16000.0f * 1000;
|
||||
constexpr float gyro_scale_factor = 65535 / (13371 * 360.0f) * 1000;
|
||||
|
||||
float CalibrateWeightData(uint16_t x, uint16_t cal_0kg, uint16_t cal_17kg, uint16_t cal_34kg) {
|
||||
float CalibrateWeightData(u16 x, u16 cal_0kg, u16 cal_17kg, u16 cal_34kg) {
|
||||
x = util::SwapEndian(x);
|
||||
|
||||
if (x < cal_0kg) {
|
||||
return 0.0f;
|
||||
} else if (x < cal_17kg) {
|
||||
return (17.0f * (x - cal_0kg)) / (cal_17kg - cal_0kg);
|
||||
} else {
|
||||
} else {
|
||||
return ((17.0f * (x - cal_17kg)) / (cal_34kg - cal_17kg)) + 17.0f;
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ namespace ams::controller {
|
|||
// Request a status report to check extension controller status
|
||||
R_TRY(this->QueryStatus());
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void WiiController::ProcessInputData(const bluetooth::HidReport *report) {
|
||||
|
@ -197,13 +197,13 @@ namespace ams::controller {
|
|||
|
||||
void WiiController::MapAccelerometerData(const WiiAccelerometerData *accel, const WiiButtonData *buttons) {
|
||||
if (m_enable_motion) {
|
||||
uint16_t x_raw = (accel->x << 2) | ((buttons->raw[0] >> 5) & 0x3);
|
||||
uint16_t y_raw = (accel->y << 2) | (((buttons->raw[1] >> 4) & 0x1) << 1);
|
||||
uint16_t z_raw = (accel->z << 2) | (((buttons->raw[1] >> 5) & 0x1) << 1);
|
||||
u16 x_raw = (accel->x << 2) | ((buttons->raw[0] >> 5) & 0x3);
|
||||
u16 y_raw = (accel->y << 2) | (((buttons->raw[1] >> 4) & 0x1) << 1);
|
||||
u16 z_raw = (accel->z << 2) | (((buttons->raw[1] >> 5) & 0x1) << 1);
|
||||
|
||||
int16_t x = -static_cast<int16_t>(accel_scale_factor * (float(x_raw - m_accel_calibration.acc_x_0g) / float(m_accel_calibration.acc_x_1g - m_accel_calibration.acc_x_0g)));
|
||||
int16_t y = -static_cast<int16_t>(accel_scale_factor * (float(y_raw - m_accel_calibration.acc_y_0g) / float(m_accel_calibration.acc_y_1g - m_accel_calibration.acc_y_0g)));
|
||||
int16_t z = static_cast<int16_t>(accel_scale_factor * (float(z_raw - m_accel_calibration.acc_z_0g) / float(m_accel_calibration.acc_z_1g - m_accel_calibration.acc_z_0g)));
|
||||
s16 x = -static_cast<s16>(accel_scale_factor * (float(x_raw - m_accel_calibration.acc_x_0g) / float(m_accel_calibration.acc_x_1g - m_accel_calibration.acc_x_0g)));
|
||||
s16 y = -static_cast<s16>(accel_scale_factor * (float(y_raw - m_accel_calibration.acc_y_0g) / float(m_accel_calibration.acc_y_1g - m_accel_calibration.acc_y_0g)));
|
||||
s16 z = static_cast<s16>(accel_scale_factor * (float(z_raw - m_accel_calibration.acc_z_0g) / float(m_accel_calibration.acc_z_1g - m_accel_calibration.acc_z_0g)));
|
||||
|
||||
if (m_orientation == WiiControllerOrientation_Horizontal) {
|
||||
m_motion_data[0].accel_x = x;
|
||||
|
@ -230,13 +230,12 @@ namespace ams::controller {
|
|||
m_motion_data[2].accel_y = -x;
|
||||
m_motion_data[2].accel_z = z;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
std::memset(&m_motion_data, 0, sizeof(m_motion_data));
|
||||
}
|
||||
}
|
||||
|
||||
void WiiController::MapExtensionBytes(const uint8_t ext[]) {
|
||||
void WiiController::MapExtensionBytes(const u8 ext[]) {
|
||||
switch(m_extension) {
|
||||
case WiiExtensionController_Nunchuck:
|
||||
this->MapNunchuckExtension(ext); break;
|
||||
|
@ -257,28 +256,28 @@ namespace ams::controller {
|
|||
}
|
||||
}
|
||||
|
||||
void WiiController::MapNunchuckExtension(const uint8_t ext[]) {
|
||||
void WiiController::MapNunchuckExtension(const u8 ext[]) {
|
||||
auto extension_data = reinterpret_cast<const WiiNunchuckExtensionData *>(ext);
|
||||
|
||||
m_left_stick.SetData(
|
||||
std::clamp<uint16_t>(static_cast<uint16_t>(nunchuck_stick_scale_factor * (extension_data->stick_x - 0x80) + STICK_ZERO), 0, 0xfff),
|
||||
std::clamp<uint16_t>(static_cast<uint16_t>(nunchuck_stick_scale_factor * (extension_data->stick_y - 0x80) + STICK_ZERO), 0, 0xfff)
|
||||
std::clamp<u16>(static_cast<u16>(nunchuck_stick_scale_factor * (extension_data->stick_x - 0x80) + STICK_ZERO), 0, 0xfff),
|
||||
std::clamp<u16>(static_cast<u16>(nunchuck_stick_scale_factor * (extension_data->stick_y - 0x80) + STICK_ZERO), 0, 0xfff)
|
||||
);
|
||||
|
||||
m_buttons.L = !extension_data->C;
|
||||
m_buttons.ZL = !extension_data->Z;
|
||||
}
|
||||
|
||||
void WiiController::MapClassicControllerExtension(const uint8_t ext[]) {
|
||||
void WiiController::MapClassicControllerExtension(const u8 ext[]) {
|
||||
auto extension_data = reinterpret_cast<const WiiClassicControllerExtensionData *>(ext);
|
||||
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(left_stick_scale_factor * (extension_data->left_stick_x - 0x20) + STICK_ZERO) & 0xfff,
|
||||
static_cast<uint16_t>(left_stick_scale_factor * (extension_data->left_stick_y - 0x20) + STICK_ZERO) & 0xfff
|
||||
static_cast<u16>(left_stick_scale_factor * (extension_data->left_stick_x - 0x20) + STICK_ZERO) & 0xfff,
|
||||
static_cast<u16>(left_stick_scale_factor * (extension_data->left_stick_y - 0x20) + STICK_ZERO) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(right_stick_scale_factor * (((extension_data->right_stick_x_43 << 3) | (extension_data->right_stick_x_21 << 1) | extension_data->right_stick_x_0) - 0x10) + STICK_ZERO) & 0xfff,
|
||||
static_cast<uint16_t>(right_stick_scale_factor * (extension_data->right_stick_y - 0x10) + STICK_ZERO) & 0xfff
|
||||
static_cast<u16>(right_stick_scale_factor * (((extension_data->right_stick_x_43 << 3) | (extension_data->right_stick_x_21 << 1) | extension_data->right_stick_x_0) - 0x10) + STICK_ZERO) & 0xfff,
|
||||
static_cast<u16>(right_stick_scale_factor * (extension_data->right_stick_y - 0x10) + STICK_ZERO) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down |= !extension_data->buttons.dpad_down;
|
||||
|
@ -302,16 +301,16 @@ namespace ams::controller {
|
|||
m_buttons.home |= !extension_data->buttons.home;
|
||||
}
|
||||
|
||||
void WiiController::MapWiiUProControllerExtension(const uint8_t ext[]) {
|
||||
void WiiController::MapWiiUProControllerExtension(const u8 ext[]) {
|
||||
auto extension_data = reinterpret_cast<const WiiUProExtensionData *>(ext);
|
||||
|
||||
m_left_stick.SetData(
|
||||
std::clamp<uint16_t>(((wiiu_scale_factor * (extension_data->left_stick_x - STICK_ZERO))) + STICK_ZERO, 0, 0xfff),
|
||||
std::clamp<uint16_t>(((wiiu_scale_factor * (extension_data->left_stick_y - STICK_ZERO))) + STICK_ZERO, 0, 0xfff)
|
||||
std::clamp<u16>(((wiiu_scale_factor * (extension_data->left_stick_x - STICK_ZERO))) + STICK_ZERO, 0, 0xfff),
|
||||
std::clamp<u16>(((wiiu_scale_factor * (extension_data->left_stick_y - STICK_ZERO))) + STICK_ZERO, 0, 0xfff)
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
std::clamp<uint16_t>(((wiiu_scale_factor * (extension_data->right_stick_x - STICK_ZERO))) + STICK_ZERO, 0, 0xfff),
|
||||
std::clamp<uint16_t>(((wiiu_scale_factor * (extension_data->right_stick_y - STICK_ZERO))) + STICK_ZERO, 0, 0xfff)
|
||||
std::clamp<u16>(((wiiu_scale_factor * (extension_data->right_stick_x - STICK_ZERO))) + STICK_ZERO, 0, 0xfff),
|
||||
std::clamp<u16>(((wiiu_scale_factor * (extension_data->right_stick_y - STICK_ZERO))) + STICK_ZERO, 0, 0xfff)
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = !extension_data->buttons.dpad_down;
|
||||
|
@ -342,7 +341,7 @@ namespace ams::controller {
|
|||
m_battery = (extension_data->buttons.battery == 0b111) ? 0 : (extension_data->buttons.battery << 1);
|
||||
}
|
||||
|
||||
void WiiController::MapTaTaConExtension(const uint8_t ext[]) {
|
||||
void WiiController::MapTaTaConExtension(const u8 ext[]) {
|
||||
auto extension_data = reinterpret_cast<const TaTaConExtensionData *>(ext);
|
||||
|
||||
m_buttons.X = !extension_data->R_rim;
|
||||
|
@ -351,7 +350,7 @@ namespace ams::controller {
|
|||
m_buttons.dpad_right |= !extension_data->L_center;
|
||||
}
|
||||
|
||||
void WiiController::MapBalanceBoardExtension(const uint8_t ext[]) {
|
||||
void WiiController::MapBalanceBoardExtension(const u8 ext[]) {
|
||||
auto extension = reinterpret_cast<const BalanceBoardExtensionData *>(ext);
|
||||
|
||||
float top_right = CalibrateWeightData(extension->top_right, m_ext_calibration.balance_board.top_right_0kg, m_ext_calibration.balance_board.top_right_17kg, m_ext_calibration.balance_board.top_right_34kg);
|
||||
|
@ -368,36 +367,36 @@ namespace ams::controller {
|
|||
}
|
||||
|
||||
m_left_stick.SetData(
|
||||
std::clamp<uint16_t>(static_cast<uint16_t>((x * (UINT12_MAX / 2)) + STICK_ZERO), 0, UINT12_MAX),
|
||||
std::clamp<uint16_t>(static_cast<uint16_t>((y * (UINT12_MAX / 2)) + STICK_ZERO), 0, UINT12_MAX)
|
||||
std::clamp<u16>(static_cast<u16>((x * (UINT12_MAX / 2)) + STICK_ZERO), 0, UINT12_MAX),
|
||||
std::clamp<u16>(static_cast<u16>((y * (UINT12_MAX / 2)) + STICK_ZERO), 0, UINT12_MAX)
|
||||
);
|
||||
}
|
||||
|
||||
void WiiController::MapMotionPlusExtension(const uint8_t ext[]) {
|
||||
void WiiController::MapMotionPlusExtension(const u8 ext[]) {
|
||||
auto extension_data = reinterpret_cast<const MotionPlusExtensionData *>(ext);
|
||||
|
||||
this->UpdateMotionPlusExtensionStatus(extension_data->extension_connected);
|
||||
|
||||
if (extension_data->motionplus_report) {
|
||||
uint16_t pitch_raw = ((extension_data->pitch_speed_hi << 8) | extension_data->pitch_speed_lo) << 2;
|
||||
uint16_t roll_raw = ((extension_data->roll_speed_hi << 8) | extension_data->roll_speed_lo) << 2;
|
||||
uint16_t yaw_raw = ((extension_data->yaw_speed_hi << 8) | extension_data->yaw_speed_lo) << 2;
|
||||
u16 pitch_raw = ((extension_data->pitch_speed_hi << 8) | extension_data->pitch_speed_lo) << 2;
|
||||
u16 roll_raw = ((extension_data->roll_speed_hi << 8) | extension_data->roll_speed_lo) << 2;
|
||||
u16 yaw_raw = ((extension_data->yaw_speed_hi << 8) | extension_data->yaw_speed_lo) << 2;
|
||||
|
||||
uint16_t pitch_0deg = (extension_data->pitch_slow_mode ? m_ext_calibration.motion_plus.slow.pitch_zero : m_ext_calibration.motion_plus.fast.pitch_zero);
|
||||
uint16_t roll_0deg = (extension_data->roll_slow_mode ? m_ext_calibration.motion_plus.slow.roll_zero : m_ext_calibration.motion_plus.fast.roll_zero);
|
||||
uint16_t yaw_0deg = (extension_data->yaw_slow_mode ? m_ext_calibration.motion_plus.slow.yaw_zero : m_ext_calibration.motion_plus.fast.yaw_zero);
|
||||
u16 pitch_0deg = (extension_data->pitch_slow_mode ? m_ext_calibration.motion_plus.slow.pitch_zero : m_ext_calibration.motion_plus.fast.pitch_zero);
|
||||
u16 roll_0deg = (extension_data->roll_slow_mode ? m_ext_calibration.motion_plus.slow.roll_zero : m_ext_calibration.motion_plus.fast.roll_zero);
|
||||
u16 yaw_0deg = (extension_data->yaw_slow_mode ? m_ext_calibration.motion_plus.slow.yaw_zero : m_ext_calibration.motion_plus.fast.yaw_zero);
|
||||
|
||||
uint16_t pitch_scale = (extension_data->pitch_slow_mode ? m_ext_calibration.motion_plus.slow.pitch_scale : m_ext_calibration.motion_plus.fast.pitch_scale);
|
||||
uint16_t roll_scale = (extension_data->roll_slow_mode ? m_ext_calibration.motion_plus.slow.roll_scale : m_ext_calibration.motion_plus.fast.roll_scale);
|
||||
uint16_t yaw_scale = (extension_data->yaw_slow_mode ? m_ext_calibration.motion_plus.slow.yaw_scale : m_ext_calibration.motion_plus.fast.yaw_scale);
|
||||
u16 pitch_scale = (extension_data->pitch_slow_mode ? m_ext_calibration.motion_plus.slow.pitch_scale : m_ext_calibration.motion_plus.fast.pitch_scale);
|
||||
u16 roll_scale = (extension_data->roll_slow_mode ? m_ext_calibration.motion_plus.slow.roll_scale : m_ext_calibration.motion_plus.fast.roll_scale);
|
||||
u16 yaw_scale = (extension_data->yaw_slow_mode ? m_ext_calibration.motion_plus.slow.yaw_scale : m_ext_calibration.motion_plus.fast.yaw_scale);
|
||||
|
||||
uint16_t scale_deg_pitch = 6 * (extension_data->pitch_slow_mode ? m_ext_calibration.motion_plus.slow.degrees_div_6 : m_ext_calibration.motion_plus.fast.degrees_div_6);
|
||||
uint16_t scale_deg_roll = 6 * (extension_data->roll_slow_mode ? m_ext_calibration.motion_plus.slow.degrees_div_6 : m_ext_calibration.motion_plus.fast.degrees_div_6);
|
||||
uint16_t scale_deg_yaw = 6 * (extension_data->yaw_slow_mode ? m_ext_calibration.motion_plus.slow.degrees_div_6 : m_ext_calibration.motion_plus.fast.degrees_div_6);
|
||||
u16 scale_deg_pitch = 6 * (extension_data->pitch_slow_mode ? m_ext_calibration.motion_plus.slow.degrees_div_6 : m_ext_calibration.motion_plus.fast.degrees_div_6);
|
||||
u16 scale_deg_roll = 6 * (extension_data->roll_slow_mode ? m_ext_calibration.motion_plus.slow.degrees_div_6 : m_ext_calibration.motion_plus.fast.degrees_div_6);
|
||||
u16 scale_deg_yaw = 6 * (extension_data->yaw_slow_mode ? m_ext_calibration.motion_plus.slow.degrees_div_6 : m_ext_calibration.motion_plus.fast.degrees_div_6);
|
||||
|
||||
int16_t pitch = static_cast<int16_t>(gyro_scale_factor * (float(pitch_raw - pitch_0deg) / (float(pitch_scale - pitch_0deg) / scale_deg_pitch)));
|
||||
int16_t roll = -static_cast<int16_t>(gyro_scale_factor * (float(roll_raw - roll_0deg) / (float(roll_scale - roll_0deg) / scale_deg_roll)));
|
||||
int16_t yaw = -static_cast<int16_t>(gyro_scale_factor * (float(yaw_raw - yaw_0deg) / (float(yaw_scale - yaw_0deg) / scale_deg_yaw)));
|
||||
s16 pitch = static_cast<s16>(gyro_scale_factor * (float(pitch_raw - pitch_0deg) / (float(pitch_scale - pitch_0deg) / scale_deg_pitch)));
|
||||
s16 roll = -static_cast<s16>(gyro_scale_factor * (float(roll_raw - roll_0deg) / (float(roll_scale - roll_0deg) / scale_deg_roll)));
|
||||
s16 yaw = -static_cast<s16>(gyro_scale_factor * (float(yaw_raw - yaw_0deg) / (float(yaw_scale - yaw_0deg) / scale_deg_yaw)));
|
||||
|
||||
if (m_orientation == WiiControllerOrientation_Horizontal) {
|
||||
m_motion_data[0].gyro_1 = pitch;
|
||||
|
@ -433,28 +432,28 @@ namespace ams::controller {
|
|||
}
|
||||
}
|
||||
|
||||
void WiiController::MapNunchuckExtensionPassthroughMode(const uint8_t ext[]) {
|
||||
void WiiController::MapNunchuckExtensionPassthroughMode(const u8 ext[]) {
|
||||
auto extension_data = reinterpret_cast<const WiiNunchuckPassthroughExtensionData *>(ext);
|
||||
|
||||
m_left_stick.SetData(
|
||||
std::clamp<uint16_t>(static_cast<uint16_t>(nunchuck_stick_scale_factor * (extension_data->stick_x - 0x80) + STICK_ZERO), 0, 0xfff),
|
||||
std::clamp<uint16_t>(static_cast<uint16_t>(nunchuck_stick_scale_factor * (extension_data->stick_y - 0x80) + STICK_ZERO), 0, 0xfff)
|
||||
std::clamp<u16>(static_cast<u16>(nunchuck_stick_scale_factor * (extension_data->stick_x - 0x80) + STICK_ZERO), 0, 0xfff),
|
||||
std::clamp<u16>(static_cast<u16>(nunchuck_stick_scale_factor * (extension_data->stick_y - 0x80) + STICK_ZERO), 0, 0xfff)
|
||||
);
|
||||
|
||||
m_buttons.L = !extension_data->C;
|
||||
m_buttons.ZL = !extension_data->Z;
|
||||
}
|
||||
|
||||
void WiiController::MapClassicControllerExtensionPassthroughMode(const uint8_t ext[]) {
|
||||
void WiiController::MapClassicControllerExtensionPassthroughMode(const u8 ext[]) {
|
||||
auto extension_data = reinterpret_cast<const WiiClassicControllerPassthroughExtensionData *>(ext);
|
||||
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(left_stick_scale_factor * ((extension_data->left_stick_x_51 << 1) - 0x20) + STICK_ZERO) & 0xfff,
|
||||
static_cast<uint16_t>(left_stick_scale_factor * ((extension_data->left_stick_y_51 << 1) - 0x20) + STICK_ZERO) & 0xfff
|
||||
static_cast<u16>(left_stick_scale_factor * ((extension_data->left_stick_x_51 << 1) - 0x20) + STICK_ZERO) & 0xfff,
|
||||
static_cast<u16>(left_stick_scale_factor * ((extension_data->left_stick_y_51 << 1) - 0x20) + STICK_ZERO) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(right_stick_scale_factor * (((extension_data->right_stick_x_43 << 3) | (extension_data->right_stick_x_21 << 1) | extension_data->right_stick_x_0) - 0x10) + STICK_ZERO) & 0xfff,
|
||||
static_cast<uint16_t>(right_stick_scale_factor * (extension_data->right_stick_y - 0x10) + STICK_ZERO) & 0xfff
|
||||
static_cast<u16>(right_stick_scale_factor * (((extension_data->right_stick_x_43 << 3) | (extension_data->right_stick_x_21 << 1) | extension_data->right_stick_x_0) - 0x10) + STICK_ZERO) & 0xfff,
|
||||
static_cast<u16>(right_stick_scale_factor * (extension_data->right_stick_y - 0x10) + STICK_ZERO) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down |= !extension_data->buttons.dpad_down;
|
||||
|
@ -493,7 +492,7 @@ namespace ams::controller {
|
|||
|
||||
R_TRY(this->ActivateMotionPlus());
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,7 +569,7 @@ namespace ams::controller {
|
|||
m_mp_state_changing = false;
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
);
|
||||
|
||||
} else {
|
||||
|
@ -590,14 +589,14 @@ namespace ams::controller {
|
|||
R_TRY(this->ActivateMotionPlus());
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WiiExtensionController WiiController::GetExtensionControllerType() {
|
||||
uint32_t extension_id = 0;
|
||||
u32 extension_id = 0;
|
||||
if (R_SUCCEEDED(this->ReadMemory(0x04a400fc, 4, &extension_id))) {
|
||||
extension_id = util::SwapEndian(extension_id);
|
||||
|
||||
|
@ -630,27 +629,27 @@ namespace ams::controller {
|
|||
|
||||
Result WiiController::GetAccelerometerCalibration(WiiAccelerometerCalibrationData *calibration) {
|
||||
struct {
|
||||
uint8_t acc_x_0g_92;
|
||||
uint8_t acc_y_0g_92;
|
||||
uint8_t acc_z_0g_92;
|
||||
u8 acc_x_0g_92;
|
||||
u8 acc_y_0g_92;
|
||||
u8 acc_z_0g_92;
|
||||
|
||||
uint8_t acc_z_0g_10 : 2;
|
||||
uint8_t acc_y_0g_10 : 2;
|
||||
uint8_t acc_x_0g_10 : 2;
|
||||
uint8_t : 0;
|
||||
u8 acc_z_0g_10 : 2;
|
||||
u8 acc_y_0g_10 : 2;
|
||||
u8 acc_x_0g_10 : 2;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t acc_x_1g_92;
|
||||
uint8_t acc_y_1g_92;
|
||||
uint8_t acc_z_1g_92;
|
||||
u8 acc_x_1g_92;
|
||||
u8 acc_y_1g_92;
|
||||
u8 acc_z_1g_92;
|
||||
|
||||
uint8_t acc_z_1g_10 : 2;
|
||||
uint8_t acc_y_1g_10 : 2;
|
||||
uint8_t acc_x_1g_10 : 2;
|
||||
uint8_t : 0;
|
||||
u8 acc_z_1g_10 : 2;
|
||||
u8 acc_y_1g_10 : 2;
|
||||
u8 acc_x_1g_10 : 2;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t unused;
|
||||
u8 unused;
|
||||
|
||||
uint8_t checksum;
|
||||
u8 checksum;
|
||||
} calibration_raw;
|
||||
|
||||
R_TRY(this->ReadMemory(0x0016, sizeof(calibration_raw), &calibration_raw));
|
||||
|
@ -662,26 +661,26 @@ namespace ams::controller {
|
|||
calibration->acc_y_1g = (calibration_raw.acc_y_1g_92 << 2) | calibration_raw.acc_y_1g_10;
|
||||
calibration->acc_z_1g = (calibration_raw.acc_z_1g_92 << 2) | calibration_raw.acc_z_1g_10;
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WiiController::GetMotionPlusCalibration(MotionPlusCalibrationData *calibration) {
|
||||
struct {
|
||||
union {
|
||||
uint8_t raw[0x20];
|
||||
u8 raw[0x20];
|
||||
|
||||
struct {
|
||||
struct {
|
||||
MotionPlusCalibration calib;
|
||||
uint8_t uid;
|
||||
u8 uid;
|
||||
} fast ;
|
||||
uint16_t crc32_msb;
|
||||
u16 crc32_msb;
|
||||
|
||||
struct {
|
||||
MotionPlusCalibration calib;
|
||||
uint8_t uid;
|
||||
u8 uid;
|
||||
} slow;
|
||||
uint16_t crc32_lsb;
|
||||
u16 crc32_lsb;
|
||||
};
|
||||
};
|
||||
} calibration_raw;
|
||||
|
@ -705,18 +704,18 @@ namespace ams::controller {
|
|||
calibration->slow.pitch_scale = util::SwapEndian(calibration_raw.slow.calib.pitch_scale);
|
||||
calibration->slow.degrees_div_6 = calibration_raw.slow.calib.degrees_div_6;
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WiiController::GetBalanceBoardCalibration(BalanceBoardCalibrationData *calibration) {
|
||||
struct {
|
||||
union {
|
||||
uint8_t raw[0x20];
|
||||
u8 raw[0x20];
|
||||
|
||||
struct {
|
||||
uint8_t _unk;
|
||||
uint8_t battery_reference;
|
||||
uint8_t pad[2];
|
||||
u8 _unk;
|
||||
u8 battery_reference;
|
||||
u8 pad[2];
|
||||
|
||||
BalanceBoardCalibrationData calib;
|
||||
};
|
||||
|
@ -739,10 +738,10 @@ namespace ams::controller {
|
|||
calibration->top_left_34kg = util::SwapEndian(calibration_raw.calib.top_left_34kg);
|
||||
calibration->bottom_left_34kg = util::SwapEndian(calibration_raw.calib.bottom_left_34kg);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WiiController::SetReportMode(uint8_t mode) {
|
||||
Result WiiController::SetReportMode(u8 mode) {
|
||||
std::scoped_lock lk(m_output_mutex);
|
||||
|
||||
m_output_report.size = sizeof(WiiOutputReport0x12) + 1;
|
||||
|
@ -751,8 +750,7 @@ namespace ams::controller {
|
|||
report_data->output0x12.rumble = m_rumble_state;
|
||||
report_data->output0x12.report_mode = mode;
|
||||
|
||||
R_TRY(this->WriteDataReport(&m_output_report));
|
||||
return ams::ResultSuccess();
|
||||
R_RETURN(this->WriteDataReport(&m_output_report));
|
||||
}
|
||||
|
||||
Result WiiController::QueryStatus() {
|
||||
|
@ -763,11 +761,10 @@ namespace ams::controller {
|
|||
report_data->id = 0x15;
|
||||
report_data->output0x15.rumble = m_rumble_state;
|
||||
|
||||
R_TRY(this->WriteDataReport(&m_output_report));
|
||||
return ams::ResultSuccess();
|
||||
R_RETURN(this->WriteDataReport(&m_output_report));
|
||||
}
|
||||
|
||||
Result WiiController::WriteMemory(uint32_t write_addr, const void *data, uint8_t size) {
|
||||
Result WiiController::WriteMemory(u32 write_addr, const void *data, u8 size) {
|
||||
os::SleepThread(ams::TimeSpan::FromMilliSeconds(30));
|
||||
|
||||
Result result;
|
||||
|
@ -780,7 +777,7 @@ namespace ams::controller {
|
|||
m_output_report.size = sizeof(WiiOutputReport0x16) + 1;
|
||||
auto report_data = reinterpret_cast<WiiReportData *>(m_output_report.data);
|
||||
report_data->id = 0x16;
|
||||
report_data->output0x16.address = ams::util::SwapEndian(write_addr);
|
||||
report_data->output0x16.address = ams::util::SwapEndian(write_addr);
|
||||
report_data->output0x16.size = size;
|
||||
std::memcpy(&report_data->output0x16.data, data, size);
|
||||
|
||||
|
@ -792,7 +789,7 @@ namespace ams::controller {
|
|||
return result;
|
||||
}
|
||||
|
||||
Result WiiController::ReadMemory(uint32_t read_addr, uint16_t size, void *out_data) {
|
||||
Result WiiController::ReadMemory(u32 read_addr, u16 size, void *out_data) {
|
||||
os::SleepThread(ams::TimeSpan::FromMilliSeconds(30));
|
||||
|
||||
Result result;
|
||||
|
@ -805,8 +802,8 @@ namespace ams::controller {
|
|||
m_output_report.size = sizeof(WiiOutputReport0x17) + 1;
|
||||
auto report_data = reinterpret_cast<WiiReportData *>(m_output_report.data);
|
||||
report_data->id = 0x17;
|
||||
report_data->output0x17.address = ams::util::SwapEndian(read_addr);
|
||||
report_data->output0x17.size = ams::util::SwapEndian(size);
|
||||
report_data->output0x17.address = ams::util::SwapEndian(read_addr);
|
||||
report_data->output0x17.size = ams::util::SwapEndian(size);
|
||||
|
||||
R_TRY(this->WriteDataReport(&m_output_report, 0x21, output.get()));
|
||||
report_data = reinterpret_cast<WiiReportData *>(&output->data);
|
||||
|
@ -824,7 +821,7 @@ namespace ams::controller {
|
|||
R_TRY(this->WriteMemory(0x04a400f0, init_data1, sizeof(init_data1)));
|
||||
R_TRY(this->WriteMemory(0x04a400fb, init_data2, sizeof(init_data2)));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WiiController::InitializeMotionPlus() {
|
||||
|
@ -833,11 +830,11 @@ namespace ams::controller {
|
|||
// Get the MotionPlus calibration
|
||||
R_TRY(this->GetMotionPlusCalibration(&m_ext_calibration.motion_plus));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
MotionPlusStatus WiiController::GetMotionPlusStatus() {
|
||||
uint16_t extension_id;
|
||||
u16 extension_id;
|
||||
|
||||
// Check for inactive motion plus addon
|
||||
if (R_SUCCEEDED(this->ReadMemory(0x04a600fe, 2, &extension_id))) {
|
||||
|
@ -873,30 +870,22 @@ namespace ams::controller {
|
|||
}
|
||||
|
||||
Result WiiController::ActivateMotionPlus() {
|
||||
uint8_t data[] = {0x04};
|
||||
R_TRY(this->WriteMemory(0x04a600fe, data, sizeof(data)));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
u8 data[] = {0x04};
|
||||
R_RETURN(this->WriteMemory(0x04a600fe, data, sizeof(data)));
|
||||
}
|
||||
|
||||
Result WiiController::ActivateMotionPlusNunchuckPassthrough() {
|
||||
uint8_t data[] = {0x05};
|
||||
R_TRY(this->WriteMemory(0x04a600fe, data, sizeof(data)));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
u8 data[] = {0x05};
|
||||
R_RETURN(this->WriteMemory(0x04a600fe, data, sizeof(data)));
|
||||
}
|
||||
|
||||
Result WiiController::ActivateMotionPlusClassicPassthrough() {
|
||||
uint8_t data[] = {0x07};
|
||||
R_TRY(this->WriteMemory(0x04a600fe, data, sizeof(data)));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
u8 data[] = {0x07};
|
||||
R_RETURN(this->WriteMemory(0x04a600fe, data, sizeof(data)));
|
||||
}
|
||||
|
||||
Result WiiController::DeactivateMotionPlus() {
|
||||
R_TRY(this->WriteMemory(0x04a400f0, init_data1, sizeof(init_data1)));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_RETURN(this->WriteMemory(0x04a400f0, init_data1, sizeof(init_data1)));
|
||||
}
|
||||
|
||||
Result WiiController::UpdateMotionPlusExtensionStatus(bool extension_connected) {
|
||||
|
@ -909,18 +898,18 @@ namespace ams::controller {
|
|||
os::SleepThread(ams::TimeSpan::FromMilliSeconds(250));
|
||||
R_TRY(this->QueryStatus());
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WiiController::SetVibration(const SwitchRumbleData *rumble_data) {
|
||||
m_rumble_state = rumble_data[0].low_band_amp > 0 ||
|
||||
m_rumble_state = rumble_data[0].low_band_amp > 0 ||
|
||||
rumble_data[0].high_band_amp > 0 ||
|
||||
rumble_data[1].low_band_amp > 0 ||
|
||||
rumble_data[1].low_band_amp > 0 ||
|
||||
rumble_data[1].high_band_amp > 0;
|
||||
|
||||
std::scoped_lock lk(m_output_mutex);
|
||||
|
@ -930,7 +919,7 @@ namespace ams::controller {
|
|||
report_data->id = 0x10;
|
||||
report_data->output0x10.rumble = m_rumble_state;
|
||||
|
||||
return this->WriteDataReport(&m_output_report);
|
||||
R_RETURN(this->WriteDataReport(&m_output_report));
|
||||
}
|
||||
|
||||
Result WiiController::CancelVibration() {
|
||||
|
@ -943,10 +932,10 @@ namespace ams::controller {
|
|||
report_data->id = 0x10;
|
||||
report_data->output0x10.rumble = m_rumble_state;
|
||||
|
||||
return this->WriteDataReport(&m_output_report);
|
||||
R_RETURN(this->WriteDataReport(&m_output_report));
|
||||
}
|
||||
|
||||
Result WiiController::SetPlayerLed(uint8_t led_mask) {
|
||||
Result WiiController::SetPlayerLed(u8 led_mask) {
|
||||
std::scoped_lock lk(m_output_mutex);
|
||||
|
||||
m_output_report.size = sizeof(WiiOutputReport0x11) + 1;
|
||||
|
@ -955,7 +944,7 @@ namespace ams::controller {
|
|||
report_data->output0x11.rumble = m_rumble_state;
|
||||
report_data->output0x11.leds = led_mask & 0xf;
|
||||
|
||||
return this->WriteDataReport(&m_output_report);
|
||||
R_RETURN(this->WriteDataReport(&m_output_report));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,228 +52,228 @@ namespace ams::controller {
|
|||
|
||||
struct WiiButtonData {
|
||||
union {
|
||||
uint8_t raw[2];
|
||||
u8 raw[2];
|
||||
|
||||
struct {
|
||||
uint8_t dpad_left : 1;
|
||||
uint8_t dpad_right : 1;
|
||||
uint8_t dpad_down : 1;
|
||||
uint8_t dpad_up : 1;
|
||||
uint8_t plus : 1;
|
||||
uint8_t : 0;
|
||||
u8 dpad_left : 1;
|
||||
u8 dpad_right : 1;
|
||||
u8 dpad_down : 1;
|
||||
u8 dpad_up : 1;
|
||||
u8 plus : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t two : 1;
|
||||
uint8_t one : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t A : 1;
|
||||
uint8_t minus : 1;
|
||||
uint8_t : 2;
|
||||
uint8_t home : 1;
|
||||
u8 two : 1;
|
||||
u8 one : 1;
|
||||
u8 B : 1;
|
||||
u8 A : 1;
|
||||
u8 minus : 1;
|
||||
u8 : 2;
|
||||
u8 home : 1;
|
||||
};
|
||||
};
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiAccelerometerData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t z;
|
||||
u8 x;
|
||||
u8 y;
|
||||
u8 z;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiAccelerometerCalibrationData {
|
||||
uint16_t acc_x_0g;
|
||||
uint16_t acc_y_0g;
|
||||
uint16_t acc_z_0g;
|
||||
u16 acc_x_0g;
|
||||
u16 acc_y_0g;
|
||||
u16 acc_z_0g;
|
||||
|
||||
uint16_t acc_x_1g;
|
||||
uint16_t acc_y_1g;
|
||||
uint16_t acc_z_1g;
|
||||
u16 acc_x_1g;
|
||||
u16 acc_y_1g;
|
||||
u16 acc_z_1g;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiClassicControllerExtensionData {
|
||||
struct {
|
||||
uint8_t left_stick_x : 6;
|
||||
uint8_t right_stick_x_43 : 2;
|
||||
u8 left_stick_x : 6;
|
||||
u8 right_stick_x_43 : 2;
|
||||
|
||||
uint8_t left_stick_y : 6;
|
||||
uint8_t right_stick_x_21 : 2;
|
||||
u8 left_stick_y : 6;
|
||||
u8 right_stick_x_21 : 2;
|
||||
|
||||
uint8_t right_stick_y : 5;
|
||||
uint8_t left_trigger_43 : 2;
|
||||
uint8_t right_stick_x_0 : 1;
|
||||
u8 right_stick_y : 5;
|
||||
u8 left_trigger_43 : 2;
|
||||
u8 right_stick_x_0 : 1;
|
||||
|
||||
uint8_t right_trigger : 5;
|
||||
uint8_t left_trigger_20 : 3;
|
||||
u8 right_trigger : 5;
|
||||
u8 left_trigger_20 : 3;
|
||||
};
|
||||
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
uint8_t R : 1;
|
||||
uint8_t plus : 1;
|
||||
uint8_t home : 1;
|
||||
uint8_t minus : 1;
|
||||
uint8_t L : 1;
|
||||
uint8_t dpad_down : 1;
|
||||
uint8_t dpad_right : 1;
|
||||
u8 : 1;
|
||||
u8 R : 1;
|
||||
u8 plus : 1;
|
||||
u8 home : 1;
|
||||
u8 minus : 1;
|
||||
u8 L : 1;
|
||||
u8 dpad_down : 1;
|
||||
u8 dpad_right : 1;
|
||||
|
||||
uint8_t dpad_up : 1;
|
||||
uint8_t dpad_left : 1;
|
||||
uint8_t ZR : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t A : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t ZL : 1;
|
||||
u8 dpad_up : 1;
|
||||
u8 dpad_left : 1;
|
||||
u8 ZR : 1;
|
||||
u8 X : 1;
|
||||
u8 A : 1;
|
||||
u8 Y : 1;
|
||||
u8 B : 1;
|
||||
u8 ZL : 1;
|
||||
} buttons;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiClassicControllerPassthroughExtensionData {
|
||||
union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
uint8_t left_stick_x_51 : 5;
|
||||
uint8_t right_stick_x_43 : 2;
|
||||
u8 : 1;
|
||||
u8 left_stick_x_51 : 5;
|
||||
u8 right_stick_x_43 : 2;
|
||||
|
||||
uint8_t : 1;
|
||||
uint8_t left_stick_y_51 : 5;
|
||||
uint8_t right_stick_x_21 : 2;
|
||||
u8 : 1;
|
||||
u8 left_stick_y_51 : 5;
|
||||
u8 right_stick_x_21 : 2;
|
||||
|
||||
uint8_t right_stick_y : 5;
|
||||
uint8_t left_trigger_43 : 2;
|
||||
uint8_t right_stick_x_0 : 1;
|
||||
u8 right_stick_y : 5;
|
||||
u8 left_trigger_43 : 2;
|
||||
u8 right_stick_x_0 : 1;
|
||||
|
||||
uint8_t right_trigger : 5;
|
||||
uint8_t left_trigger_20 : 3;
|
||||
u8 right_trigger : 5;
|
||||
u8 left_trigger_20 : 3;
|
||||
|
||||
uint8_t extension_connected : 1;
|
||||
uint8_t : 0;
|
||||
u8 extension_connected : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t : 1;
|
||||
uint8_t motionplus_report : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 1;
|
||||
u8 motionplus_report : 1;
|
||||
u8 : 0;
|
||||
};
|
||||
|
||||
struct {
|
||||
uint8_t dpad_up : 1;
|
||||
uint8_t : 0;
|
||||
u8 dpad_up : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t dpad_left : 1;
|
||||
uint8_t : 0;
|
||||
u8 dpad_left : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t pad[2];
|
||||
u8 pad[2];
|
||||
|
||||
uint8_t : 1;
|
||||
uint8_t R : 1;
|
||||
uint8_t plus : 1;
|
||||
uint8_t home : 1;
|
||||
uint8_t minus : 1;
|
||||
uint8_t L : 1;
|
||||
uint8_t dpad_down : 1;
|
||||
uint8_t dpad_right : 1;
|
||||
u8 : 1;
|
||||
u8 R : 1;
|
||||
u8 plus : 1;
|
||||
u8 home : 1;
|
||||
u8 minus : 1;
|
||||
u8 L : 1;
|
||||
u8 dpad_down : 1;
|
||||
u8 dpad_right : 1;
|
||||
|
||||
uint8_t : 2;
|
||||
uint8_t ZR : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t A : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t ZL : 1;
|
||||
u8 : 2;
|
||||
u8 ZR : 1;
|
||||
u8 X : 1;
|
||||
u8 A : 1;
|
||||
u8 Y : 1;
|
||||
u8 B : 1;
|
||||
u8 ZL : 1;
|
||||
} buttons;
|
||||
};
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiNunchuckExtensionData {
|
||||
uint8_t stick_x;
|
||||
uint8_t stick_y;
|
||||
uint8_t accel_x_92;
|
||||
uint8_t accel_y_92;
|
||||
uint8_t accel_z_92;
|
||||
u8 stick_x;
|
||||
u8 stick_y;
|
||||
u8 accel_x_92;
|
||||
u8 accel_y_92;
|
||||
u8 accel_z_92;
|
||||
|
||||
uint8_t Z : 1;
|
||||
uint8_t C : 1;
|
||||
uint8_t accel_x_10 : 2;
|
||||
uint8_t accel_y_10 : 2;
|
||||
uint8_t accel_z_10 : 2;
|
||||
u8 Z : 1;
|
||||
u8 C : 1;
|
||||
u8 accel_x_10 : 2;
|
||||
u8 accel_y_10 : 2;
|
||||
u8 accel_z_10 : 2;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiNunchuckPassthroughExtensionData {
|
||||
uint8_t stick_x;
|
||||
uint8_t stick_y;
|
||||
uint8_t accel_x_92;
|
||||
uint8_t accel_y_92;
|
||||
uint8_t extension_connected : 1;
|
||||
uint8_t accel_z_93 : 7;
|
||||
u8 stick_x;
|
||||
u8 stick_y;
|
||||
u8 accel_x_92;
|
||||
u8 accel_y_92;
|
||||
u8 extension_connected : 1;
|
||||
u8 accel_z_93 : 7;
|
||||
|
||||
uint8_t : 1;
|
||||
uint8_t motionplus_report : 1;
|
||||
uint8_t Z : 1;
|
||||
uint8_t C : 1;
|
||||
uint8_t accel_x_1 : 1;
|
||||
uint8_t accel_y_1 : 1;
|
||||
uint8_t accel_z_21 : 2;
|
||||
u8 : 1;
|
||||
u8 motionplus_report : 1;
|
||||
u8 Z : 1;
|
||||
u8 C : 1;
|
||||
u8 accel_x_1 : 1;
|
||||
u8 accel_y_1 : 1;
|
||||
u8 accel_z_21 : 2;
|
||||
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiUProButtonData {
|
||||
uint8_t : 1;
|
||||
uint8_t R : 1;
|
||||
uint8_t plus : 1;
|
||||
uint8_t home : 1;
|
||||
uint8_t minus : 1;
|
||||
uint8_t L : 1;
|
||||
uint8_t dpad_down : 1;
|
||||
uint8_t dpad_right : 1;
|
||||
u8 : 1;
|
||||
u8 R : 1;
|
||||
u8 plus : 1;
|
||||
u8 home : 1;
|
||||
u8 minus : 1;
|
||||
u8 L : 1;
|
||||
u8 dpad_down : 1;
|
||||
u8 dpad_right : 1;
|
||||
|
||||
uint8_t dpad_up : 1;
|
||||
uint8_t dpad_left : 1;
|
||||
uint8_t ZR : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t A : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t ZL : 1;
|
||||
u8 dpad_up : 1;
|
||||
u8 dpad_left : 1;
|
||||
u8 ZR : 1;
|
||||
u8 X : 1;
|
||||
u8 A : 1;
|
||||
u8 Y : 1;
|
||||
u8 B : 1;
|
||||
u8 ZL : 1;
|
||||
|
||||
uint8_t rstick_press : 1;
|
||||
uint8_t lstick_press : 1;
|
||||
uint8_t charging : 1;
|
||||
uint8_t usb_connected : 1;
|
||||
uint8_t battery : 3;
|
||||
uint8_t : 1;
|
||||
u8 rstick_press : 1;
|
||||
u8 lstick_press : 1;
|
||||
u8 charging : 1;
|
||||
u8 usb_connected : 1;
|
||||
u8 battery : 3;
|
||||
u8 : 1;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiUProExtensionData {
|
||||
uint16_t left_stick_x;
|
||||
uint16_t right_stick_x;
|
||||
uint16_t left_stick_y;
|
||||
uint16_t right_stick_y;
|
||||
u16 left_stick_x;
|
||||
u16 right_stick_x;
|
||||
u16 left_stick_y;
|
||||
u16 right_stick_y;
|
||||
WiiUProButtonData buttons;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MotionPlusExtensionData {
|
||||
uint8_t yaw_speed_lo;
|
||||
uint8_t roll_speed_lo;
|
||||
uint8_t pitch_speed_lo;
|
||||
u8 yaw_speed_lo;
|
||||
u8 roll_speed_lo;
|
||||
u8 pitch_speed_lo;
|
||||
|
||||
uint8_t pitch_slow_mode : 1;
|
||||
uint8_t yaw_slow_mode : 1;
|
||||
uint8_t yaw_speed_hi : 6;
|
||||
u8 pitch_slow_mode : 1;
|
||||
u8 yaw_slow_mode : 1;
|
||||
u8 yaw_speed_hi : 6;
|
||||
|
||||
uint8_t extension_connected : 1;
|
||||
uint8_t roll_slow_mode : 1;
|
||||
uint8_t roll_speed_hi : 6;
|
||||
u8 extension_connected : 1;
|
||||
u8 roll_slow_mode : 1;
|
||||
u8 roll_speed_hi : 6;
|
||||
|
||||
uint8_t : 1;
|
||||
uint8_t motionplus_report : 1;
|
||||
uint8_t pitch_speed_hi : 6;
|
||||
u8 : 1;
|
||||
u8 motionplus_report : 1;
|
||||
u8 pitch_speed_hi : 6;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MotionPlusCalibration {
|
||||
uint16_t yaw_zero;
|
||||
uint16_t roll_zero;
|
||||
uint16_t pitch_zero;
|
||||
uint16_t yaw_scale;
|
||||
uint16_t roll_scale;
|
||||
uint16_t pitch_scale;
|
||||
uint8_t degrees_div_6;
|
||||
u16 yaw_zero;
|
||||
u16 roll_zero;
|
||||
u16 pitch_zero;
|
||||
u16 yaw_scale;
|
||||
u16 roll_scale;
|
||||
u16 pitch_scale;
|
||||
u8 degrees_div_6;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct MotionPlusCalibrationData {
|
||||
|
@ -282,116 +282,116 @@ namespace ams::controller {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
struct TaTaConExtensionData {
|
||||
uint8_t _unk0[5];
|
||||
u8 _unk0[5];
|
||||
|
||||
uint8_t : 3;
|
||||
uint8_t R_rim : 1;
|
||||
uint8_t R_center : 1;
|
||||
uint8_t L_rim : 1;
|
||||
uint8_t L_center : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 3;
|
||||
u8 R_rim : 1;
|
||||
u8 R_center : 1;
|
||||
u8 L_rim : 1;
|
||||
u8 L_center : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct BalanceBoardExtensionData {
|
||||
uint16_t top_right;
|
||||
uint16_t bottom_right;
|
||||
uint16_t top_left;
|
||||
uint16_t bottom_left;
|
||||
uint8_t temperature;
|
||||
uint8_t _pad;
|
||||
uint8_t battery;
|
||||
u16 top_right;
|
||||
u16 bottom_right;
|
||||
u16 top_left;
|
||||
u16 bottom_left;
|
||||
u8 temperature;
|
||||
u8 _pad;
|
||||
u8 battery;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct BalanceBoardCalibrationData {
|
||||
uint16_t top_right_0kg;
|
||||
uint16_t bottom_right_0kg;
|
||||
uint16_t top_left_0kg;
|
||||
uint16_t bottom_left_0kg;
|
||||
u16 top_right_0kg;
|
||||
u16 bottom_right_0kg;
|
||||
u16 top_left_0kg;
|
||||
u16 bottom_left_0kg;
|
||||
|
||||
uint16_t top_right_17kg;
|
||||
uint16_t bottom_right_17kg;
|
||||
uint16_t top_left_17kg;
|
||||
uint16_t bottom_left_17kg;
|
||||
u16 top_right_17kg;
|
||||
u16 bottom_right_17kg;
|
||||
u16 top_left_17kg;
|
||||
u16 bottom_left_17kg;
|
||||
|
||||
uint16_t top_right_34kg;
|
||||
uint16_t bottom_right_34kg;
|
||||
uint16_t top_left_34kg;
|
||||
uint16_t bottom_left_34kg;
|
||||
u16 top_right_34kg;
|
||||
u16 bottom_right_34kg;
|
||||
u16 top_left_34kg;
|
||||
u16 bottom_left_34kg;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x10 {
|
||||
uint8_t rumble : 1;
|
||||
uint8_t : 0;
|
||||
u8 rumble : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x11 {
|
||||
uint8_t rumble : 1;
|
||||
uint8_t : 3;
|
||||
uint8_t leds : 4;
|
||||
u8 rumble : 1;
|
||||
u8 : 3;
|
||||
u8 leds : 4;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x12 {
|
||||
uint8_t rumble : 1;
|
||||
uint8_t : 0;
|
||||
uint8_t report_mode;
|
||||
u8 rumble : 1;
|
||||
u8 : 0;
|
||||
u8 report_mode;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x14 {
|
||||
uint8_t : 5;
|
||||
uint8_t speaker_enable : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 5;
|
||||
u8 speaker_enable : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x15 {
|
||||
uint8_t rumble : 1;
|
||||
uint8_t : 0;
|
||||
u8 rumble : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x16 {
|
||||
uint32_t address;
|
||||
uint8_t size;
|
||||
uint8_t data[16];
|
||||
u32 address;
|
||||
u8 size;
|
||||
u8 data[16];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x17 {
|
||||
uint32_t address;
|
||||
uint16_t size;
|
||||
u32 address;
|
||||
u16 size;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x18 {
|
||||
uint8_t size;
|
||||
uint8_t speaker_data[20];
|
||||
u8 size;
|
||||
u8 speaker_data[20];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiOutputReport0x19 {
|
||||
uint8_t : 5;
|
||||
uint8_t speaker_mute : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 5;
|
||||
u8 speaker_mute : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x20 {
|
||||
WiiButtonData buttons;
|
||||
uint8_t battery_critical : 1;
|
||||
uint8_t extension_connected : 1;
|
||||
uint8_t speaker_enabled : 1;
|
||||
uint8_t ir_enabled : 1;
|
||||
uint8_t led_state : 4;
|
||||
uint8_t _pad[2];
|
||||
uint8_t battery;
|
||||
u8 battery_critical : 1;
|
||||
u8 extension_connected : 1;
|
||||
u8 speaker_enabled : 1;
|
||||
u8 ir_enabled : 1;
|
||||
u8 led_state : 4;
|
||||
u8 _pad[2];
|
||||
u8 battery;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x21 {
|
||||
WiiButtonData buttons;
|
||||
uint8_t error : 4;
|
||||
uint8_t size : 4;
|
||||
uint16_t address;
|
||||
uint8_t data[16];
|
||||
u8 error : 4;
|
||||
u8 size : 4;
|
||||
u16 address;
|
||||
u8 data[16];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x22 {
|
||||
WiiButtonData buttons;
|
||||
uint8_t report_id;
|
||||
uint8_t error;
|
||||
u8 report_id;
|
||||
u8 error;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x30 {
|
||||
|
@ -405,57 +405,57 @@ namespace ams::controller {
|
|||
|
||||
struct WiiInputReport0x32 {
|
||||
WiiButtonData buttons;
|
||||
uint8_t extension[8];
|
||||
u8 extension[8];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x33 {
|
||||
WiiButtonData buttons;
|
||||
WiiAccelerometerData accel;
|
||||
uint8_t ir[12];
|
||||
u8 ir[12];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x34 {
|
||||
WiiButtonData buttons;
|
||||
uint8_t extension[19];
|
||||
u8 extension[19];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x35 {
|
||||
WiiButtonData buttons;
|
||||
WiiAccelerometerData accel;
|
||||
uint8_t extension[16];
|
||||
u8 extension[16];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x36 {
|
||||
WiiButtonData buttons;
|
||||
uint8_t ir[10];
|
||||
uint8_t extension[9];
|
||||
u8 ir[10];
|
||||
u8 extension[9];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x37 {
|
||||
WiiButtonData buttons;
|
||||
WiiAccelerometerData accel;
|
||||
uint8_t ir[10];
|
||||
uint8_t extension[6];
|
||||
u8 ir[10];
|
||||
u8 extension[6];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x3d {
|
||||
uint8_t extension[21];
|
||||
u8 extension[21];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x3e {
|
||||
WiiButtonData buttons;
|
||||
uint8_t accel;
|
||||
uint8_t ir[18];
|
||||
u8 accel;
|
||||
u8 ir[18];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiInputReport0x3f {
|
||||
WiiButtonData buttons;
|
||||
uint8_t accel;
|
||||
uint8_t ir[18];
|
||||
u8 accel;
|
||||
u8 ir[18];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct WiiReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
WiiOutputReport0x10 output0x10;
|
||||
WiiOutputReport0x11 output0x11;
|
||||
|
@ -483,7 +483,7 @@ namespace ams::controller {
|
|||
};
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
class WiiController : public EmulatedSwitchController {
|
||||
class WiiController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
@ -502,7 +502,7 @@ namespace ams::controller {
|
|||
Result Initialize();
|
||||
Result SetVibration(const SwitchRumbleData *rumble_data);
|
||||
Result CancelVibration();
|
||||
Result SetPlayerLed(uint8_t led_mask);
|
||||
Result SetPlayerLed(u8 led_mask);
|
||||
void ProcessInputData(const bluetooth::HidReport *report) override;
|
||||
|
||||
protected:
|
||||
|
@ -518,15 +518,15 @@ namespace ams::controller {
|
|||
|
||||
void MapCoreButtons(const WiiButtonData *buttons);
|
||||
void MapAccelerometerData(const WiiAccelerometerData *accel, const WiiButtonData *buttons);
|
||||
void MapExtensionBytes(const uint8_t ext[]);
|
||||
void MapNunchuckExtension(const uint8_t ext[]);
|
||||
void MapClassicControllerExtension(const uint8_t ext[]);
|
||||
void MapWiiUProControllerExtension(const uint8_t ext[]);
|
||||
void MapTaTaConExtension(const uint8_t ext[]);
|
||||
void MapBalanceBoardExtension(const uint8_t ext[]);
|
||||
void MapMotionPlusExtension(const uint8_t ext[]);
|
||||
void MapNunchuckExtensionPassthroughMode(const uint8_t ext[]);
|
||||
void MapClassicControllerExtensionPassthroughMode(const uint8_t ext[]);
|
||||
void MapExtensionBytes(const u8 ext[]);
|
||||
void MapNunchuckExtension(const u8 ext[]);
|
||||
void MapClassicControllerExtension(const u8 ext[]);
|
||||
void MapWiiUProControllerExtension(const u8 ext[]);
|
||||
void MapTaTaConExtension(const u8 ext[]);
|
||||
void MapBalanceBoardExtension(const u8 ext[]);
|
||||
void MapMotionPlusExtension(const u8 ext[]);
|
||||
void MapNunchuckExtensionPassthroughMode(const u8 ext[]);
|
||||
void MapClassicControllerExtensionPassthroughMode(const u8 ext[]);
|
||||
|
||||
void HandleStatusReport(const WiiReportData *wii_report);
|
||||
|
||||
|
@ -537,7 +537,7 @@ namespace ams::controller {
|
|||
Result GetMotionPlusCalibration(MotionPlusCalibrationData *calibration);
|
||||
Result GetBalanceBoardCalibration(BalanceBoardCalibrationData *calibration);
|
||||
|
||||
Result SetReportMode(uint8_t mode);
|
||||
Result SetReportMode(u8 mode);
|
||||
Result QueryStatus();
|
||||
|
||||
Result InitializeStandardExtension();
|
||||
|
@ -549,8 +549,8 @@ namespace ams::controller {
|
|||
Result DeactivateMotionPlus();
|
||||
Result UpdateMotionPlusExtensionStatus(bool extension_connected);
|
||||
|
||||
Result WriteMemory(uint32_t write_addr, const void *data, uint8_t size);
|
||||
Result ReadMemory(uint32_t read_addr, uint16_t size, void *out_data);
|
||||
Result WriteMemory(u32 write_addr, const void *data, u8 size);
|
||||
Result ReadMemory(u32 read_addr, u16 size, void *out_data);
|
||||
|
||||
WiiControllerOrientation m_orientation;
|
||||
WiiExtensionController m_extension;
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace ams::controller {
|
|||
m_output_report.size = sizeof(XboxOneOutputReport0x03) + 1;
|
||||
report->id = 0x03;
|
||||
report->output0x03.enable = 0x3;
|
||||
report->output0x03.magnitude_strong = static_cast<uint8_t>(100 * std::max(rumble_data[0].low_band_amp, rumble_data[1].low_band_amp));
|
||||
report->output0x03.magnitude_weak = static_cast<uint8_t>(100 * std::max(rumble_data[0].high_band_amp, rumble_data[1].high_band_amp));
|
||||
report->output0x03.magnitude_strong = static_cast<u8>(100 * std::max(rumble_data[0].low_band_amp, rumble_data[1].low_band_amp));
|
||||
report->output0x03.magnitude_weak = static_cast<u8>(100 * std::max(rumble_data[0].high_band_amp, rumble_data[1].high_band_amp));
|
||||
report->output0x03.pulse_sustain_10ms = 1;
|
||||
report->output0x03.pulse_release_10ms = 0;
|
||||
report->output0x03.loop_count = 0;
|
||||
|
@ -55,12 +55,12 @@ namespace ams::controller {
|
|||
|
||||
void XboxOneController::MapInputReport0x01(const XboxOneReportData *src, bool new_format) {
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT16_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x01.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT16_MAX - src->input0x01.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.ZR = src->input0x01.right_trigger > 0;
|
||||
|
@ -95,8 +95,7 @@ namespace ams::controller {
|
|||
m_buttons.rstick_press = src->input0x01.buttons.rstick_press;
|
||||
|
||||
m_buttons.home = src->input0x01.buttons.guide;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m_buttons.dpad_down = (src->input0x01.old.buttons.dpad == XboxOneDPad_S) ||
|
||||
(src->input0x01.old.buttons.dpad == XboxOneDPad_SE) ||
|
||||
(src->input0x01.old.buttons.dpad == XboxOneDPad_SW);
|
||||
|
|
|
@ -37,69 +37,68 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct XboxOneStickData {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
u16 x;
|
||||
u16 y;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
// Used on older firmware
|
||||
struct XboxOneButtonDataOld {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t LB : 1;
|
||||
uint8_t RB : 1;
|
||||
uint8_t view : 1;
|
||||
uint8_t menu : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 LB : 1;
|
||||
u8 RB : 1;
|
||||
u8 view : 1;
|
||||
u8 menu : 1;
|
||||
|
||||
uint8_t lstick_press : 1;
|
||||
uint8_t rstick_press : 1;
|
||||
uint8_t : 0;
|
||||
u8 lstick_press : 1;
|
||||
u8 rstick_press : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
// Used on latest firmwares
|
||||
struct XboxOneButtonData {
|
||||
uint8_t dpad;
|
||||
u8 dpad;
|
||||
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t LB : 1;
|
||||
uint8_t RB : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 LB : 1;
|
||||
u8 RB : 1;
|
||||
|
||||
uint8_t : 3;
|
||||
uint8_t menu : 1;
|
||||
uint8_t guide : 1;
|
||||
uint8_t lstick_press : 1;
|
||||
uint8_t rstick_press : 1;
|
||||
uint8_t : 0;
|
||||
|
||||
uint8_t view : 1;
|
||||
uint8_t : 0;
|
||||
u8 : 3;
|
||||
u8 menu : 1;
|
||||
u8 guide : 1;
|
||||
u8 lstick_press : 1;
|
||||
u8 rstick_press : 1;
|
||||
u8 : 0;
|
||||
|
||||
u8 view : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct XboxOneOutputReport0x03 {
|
||||
uint8_t enable;
|
||||
uint8_t magnitude_left;
|
||||
uint8_t magnitude_right;
|
||||
uint8_t magnitude_strong;
|
||||
uint8_t magnitude_weak;
|
||||
uint8_t pulse_sustain_10ms;
|
||||
uint8_t pulse_release_10ms;
|
||||
uint8_t loop_count;
|
||||
u8 enable;
|
||||
u8 magnitude_left;
|
||||
u8 magnitude_right;
|
||||
u8 magnitude_strong;
|
||||
u8 magnitude_weak;
|
||||
u8 pulse_sustain_10ms;
|
||||
u8 pulse_release_10ms;
|
||||
u8 loop_count;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct XboxOneInputReport0x01 {
|
||||
XboxOneStickData left_stick;
|
||||
XboxOneStickData right_stick;
|
||||
uint16_t left_trigger;
|
||||
uint16_t right_trigger;
|
||||
u16 left_trigger;
|
||||
u16 right_trigger;
|
||||
union {
|
||||
XboxOneButtonData buttons;
|
||||
|
||||
|
@ -110,29 +109,29 @@ namespace ams::controller {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
struct XboxOneInputReport0x02{
|
||||
uint8_t guide : 1;
|
||||
uint8_t : 0;
|
||||
u8 guide : 1;
|
||||
u8 : 0;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct XboxOneInputReport0x04 {
|
||||
uint8_t capacity : 2;
|
||||
uint8_t mode : 2;
|
||||
uint8_t charging : 1;
|
||||
uint8_t : 2;
|
||||
uint8_t online : 1;
|
||||
u8 capacity : 2;
|
||||
u8 mode : 2;
|
||||
u8 charging : 1;
|
||||
u8 : 2;
|
||||
u8 online : 1;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct XboxOneReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
XboxOneOutputReport0x03 output0x03;
|
||||
XboxOneInputReport0x01 input0x01;
|
||||
XboxOneInputReport0x02 input0x02;
|
||||
XboxOneInputReport0x04 input0x04;
|
||||
XboxOneInputReport0x01 input0x01;
|
||||
XboxOneInputReport0x02 input0x02;
|
||||
XboxOneInputReport0x04 input0x04;
|
||||
};
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
class XboxOneController : public EmulatedSwitchController {
|
||||
class XboxOneController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ams::controller {
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr uint8_t init_packet[] = {0x20, 0x00, 0x00}; // packet to init vibration apparently
|
||||
constexpr u8 init_packet[] = {0x20, 0x00, 0x00}; // packet to init vibration apparently
|
||||
|
||||
const constexpr float stick_scale_factor = float(UINT12_MAX) / UINT8_MAX;
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace ams::controller {
|
|||
std::memcpy(m_output_report.data, init_packet, sizeof(init_packet));
|
||||
R_TRY(this->WriteDataReport(&m_output_report));
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void XiaomiController::ProcessInputData(const bluetooth::HidReport *report) {
|
||||
|
@ -54,26 +54,26 @@ namespace ams::controller {
|
|||
m_battery = convert_battery_100(src->input0x04.battery);
|
||||
|
||||
m_left_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x04.left_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x04.left_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x04.left_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x04.left_stick.y)) & 0xfff
|
||||
);
|
||||
m_right_stick.SetData(
|
||||
static_cast<uint16_t>(stick_scale_factor * src->input0x04.right_stick.x) & 0xfff,
|
||||
static_cast<uint16_t>(stick_scale_factor * (UINT8_MAX - src->input0x04.right_stick.y)) & 0xfff
|
||||
static_cast<u16>(stick_scale_factor * src->input0x04.right_stick.x) & 0xfff,
|
||||
static_cast<u16>(stick_scale_factor * (UINT8_MAX - src->input0x04.right_stick.y)) & 0xfff
|
||||
);
|
||||
|
||||
m_buttons.dpad_down = (src->input0x04.buttons.dpad == XiaomiDPad_S) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SE) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x04.buttons.dpad == XiaomiDPad_N) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NE) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x04.buttons.dpad == XiaomiDPad_E) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NE) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x04.buttons.dpad == XiaomiDPad_W) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NW) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SW);
|
||||
m_buttons.dpad_down = (src->input0x04.buttons.dpad == XiaomiDPad_S) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SE) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SW);
|
||||
m_buttons.dpad_up = (src->input0x04.buttons.dpad == XiaomiDPad_N) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NE) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NW);
|
||||
m_buttons.dpad_right = (src->input0x04.buttons.dpad == XiaomiDPad_E) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NE) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SE);
|
||||
m_buttons.dpad_left = (src->input0x04.buttons.dpad == XiaomiDPad_W) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_NW) ||
|
||||
(src->input0x04.buttons.dpad == XiaomiDPad_SW);
|
||||
|
||||
m_buttons.A = src->input0x04.buttons.B;
|
||||
m_buttons.B = src->input0x04.buttons.A;
|
||||
|
@ -91,7 +91,7 @@ namespace ams::controller {
|
|||
m_buttons.lstick_press = src->input0x04.buttons.lstick_press;
|
||||
m_buttons.rstick_press = src->input0x04.buttons.rstick_press;
|
||||
|
||||
m_buttons.home = src->input0x04.home;
|
||||
m_buttons.home = src->input0x04.home;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,57 +31,57 @@ namespace ams::controller {
|
|||
};
|
||||
|
||||
struct XiaomiStickData {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed));
|
||||
u8 x;
|
||||
u8 y;
|
||||
} PACKED;
|
||||
|
||||
struct XiaomiButtonData {
|
||||
uint8_t A : 1;
|
||||
uint8_t B : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t X : 1;
|
||||
uint8_t Y : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t L1 : 1;
|
||||
uint8_t R1 : 1;
|
||||
u8 A : 1;
|
||||
u8 B : 1;
|
||||
u8 : 1;
|
||||
u8 X : 1;
|
||||
u8 Y : 1;
|
||||
u8 : 1;
|
||||
u8 L1 : 1;
|
||||
u8 R1 : 1;
|
||||
|
||||
uint8_t L2 : 1;
|
||||
uint8_t R2 : 1;
|
||||
uint8_t back : 1;
|
||||
uint8_t menu : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t lstick_press : 1;
|
||||
uint8_t rstick_press : 1;
|
||||
uint8_t : 0;
|
||||
u8 L2 : 1;
|
||||
u8 R2 : 1;
|
||||
u8 back : 1;
|
||||
u8 menu : 1;
|
||||
u8 : 1;
|
||||
u8 lstick_press : 1;
|
||||
u8 rstick_press : 1;
|
||||
u8 : 0;
|
||||
|
||||
uint8_t _unk;
|
||||
u8 _unk;
|
||||
|
||||
uint8_t dpad;
|
||||
} __attribute__((packed));
|
||||
u8 dpad;
|
||||
} PACKED;
|
||||
|
||||
struct XiaomiInputReport0x04 {
|
||||
XiaomiButtonData buttons;
|
||||
XiaomiStickData left_stick;
|
||||
XiaomiStickData right_stick;
|
||||
uint8_t _unk0[2];
|
||||
uint8_t left_trigger;
|
||||
uint8_t right_trigger;
|
||||
uint16_t accel_x;
|
||||
uint16_t accel_y;
|
||||
uint16_t accel_z;
|
||||
uint8_t battery;
|
||||
uint8_t home : 1;
|
||||
uint8_t : 0;
|
||||
} __attribute__((packed));
|
||||
XiaomiStickData left_stick;
|
||||
XiaomiStickData right_stick;
|
||||
u8 _unk0[2];
|
||||
u8 left_trigger;
|
||||
u8 right_trigger;
|
||||
u16 accel_x;
|
||||
u16 accel_y;
|
||||
u16 accel_z;
|
||||
u8 battery;
|
||||
u8 home : 1;
|
||||
u8 : 0;
|
||||
} PACKED;
|
||||
|
||||
struct XiaomiReportData {
|
||||
uint8_t id;
|
||||
u8 id;
|
||||
union {
|
||||
XiaomiInputReport0x04 input0x04;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
} PACKED;
|
||||
|
||||
class XiaomiController : public EmulatedSwitchController {
|
||||
class XiaomiController final : public EmulatedSwitchController {
|
||||
|
||||
public:
|
||||
static constexpr const HardwareID hardware_ids[] = {
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace ams::mitm::mc {
|
|||
os::SetThreadNamePointer(&g_thread, "mc::MissionControlThread");
|
||||
os::StartThread(&g_thread);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void WaitFinished() {
|
||||
|
|
|
@ -20,17 +20,17 @@ namespace ams::mitm::mc {
|
|||
|
||||
Result MissionControlService::GetVersion(sf::Out<u32> version) {
|
||||
version.SetValue(mc_version);
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result MissionControlService::GetBuildVersionString(sf::Out<mc::VersionString> version) {
|
||||
std::strncpy(version.GetPointer()->version, mc_build_name, sizeof(mc::VersionString));
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result MissionControlService::GetBuildDateString(sf::Out<ams::mitm::mc::DateString> date) {
|
||||
std::strncpy(date.GetPointer()->date, mc_build_date, sizeof(mc::DateString));
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,25 +46,29 @@ namespace ams::mitm {
|
|||
|
||||
void ParseInt(const char *value, int *out, int min=INT_MIN, int max=INT_MAX) {
|
||||
int tmp = std::strtol(value, nullptr, 10);
|
||||
if ((tmp >= min) && (tmp <= max))
|
||||
if ((tmp >= min) && (tmp <= max)) {
|
||||
*out = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void ParseBluetoothAddress(const char *value, bluetooth::Address *out) {
|
||||
// Check length of address string is correct
|
||||
if (std::strlen(value) != 3*sizeof(bluetooth::Address) - 1) return;
|
||||
if (std::strlen(value) != 3*sizeof(bluetooth::Address) - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse bluetooth mac address
|
||||
char buf[2 + 1];
|
||||
bluetooth::Address address = {};
|
||||
for (uint32_t i = 0; i < sizeof(bluetooth::Address); ++i) {
|
||||
for (u32 i = 0; i < sizeof(bluetooth::Address); ++i) {
|
||||
// Convert hex pair to number
|
||||
std::memcpy(buf, &value[i*3], 2);
|
||||
address.address[i] = static_cast<uint8_t>(std::strtoul(buf, nullptr, 16));
|
||||
address.address[i] = static_cast<u8>(std::strtoul(buf, nullptr, 16));
|
||||
|
||||
// Check for colon separator
|
||||
if ((i < sizeof(bluetooth::Address) - 1) && (value[i*3 + 2] != ':'))
|
||||
if ((i < sizeof(bluetooth::Address) - 1) && (value[i*3 + 2] != ':')) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*out = address;
|
||||
|
@ -74,28 +78,28 @@ namespace ams::mitm {
|
|||
auto config = reinterpret_cast<MissionControlConfig *>(user);
|
||||
|
||||
if (strcasecmp(section, "general") == 0) {
|
||||
if (strcasecmp(name, "enable_rumble") == 0)
|
||||
if (strcasecmp(name, "enable_rumble") == 0) {
|
||||
ParseBoolean(value, &config->general.enable_rumble);
|
||||
else if (strcasecmp(name, "enable_motion") == 0)
|
||||
} else if (strcasecmp(name, "enable_motion") == 0) {
|
||||
ParseBoolean(value, &config->general.enable_motion);
|
||||
}
|
||||
else if (strcasecmp(section, "bluetooth") == 0) {
|
||||
if (strcasecmp(name, "host_name") == 0)
|
||||
}
|
||||
} else if (strcasecmp(section, "bluetooth") == 0) {
|
||||
if (strcasecmp(name, "host_name") == 0) {
|
||||
std::strncpy(config->bluetooth.host_name, value, sizeof(config->bluetooth.host_name));
|
||||
else if (strcasecmp(name, "host_address") == 0)
|
||||
} else if (strcasecmp(name, "host_address") == 0) {
|
||||
ParseBluetoothAddress(value, &config->bluetooth.host_address);
|
||||
}
|
||||
else if (strcasecmp(section, "misc") == 0) {
|
||||
if (strcasecmp(name, "enable_dualshock4_lightbar") == 0)
|
||||
}
|
||||
} else if (strcasecmp(section, "misc") == 0) {
|
||||
if (strcasecmp(name, "enable_dualshock4_lightbar") == 0) {
|
||||
ParseBoolean(value, &config->misc.enable_dualshock4_lightbar);
|
||||
else if (strcasecmp(name, "enable_dualsense_lightbar") == 0)
|
||||
} else if (strcasecmp(name, "enable_dualsense_lightbar") == 0) {
|
||||
ParseBoolean(value, &config->misc.enable_dualsense_lightbar);
|
||||
else if (strcasecmp(name, "enable_dualsense_player_leds") == 0)
|
||||
} else if (strcasecmp(name, "enable_dualsense_player_leds") == 0) {
|
||||
ParseBoolean(value, &config->misc.enable_dualsense_player_leds);
|
||||
else if (strcasecmp(name, "dualsense_vibration_intensity") == 0)
|
||||
} else if (strcasecmp(name, "dualsense_vibration_intensity") == 0) {
|
||||
ParseInt(value, &config->misc.dualsense_vibration_intensity, 1, 8);
|
||||
}
|
||||
else {
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,12 @@ namespace ams::utils {
|
|||
}
|
||||
|
||||
Result BluetoothAddressToString(const bluetooth::Address *address, char *out, size_t out_size) {
|
||||
if (out_size < 2*sizeof(bluetooth::Address) + 1)
|
||||
if (out_size < 2*sizeof(bluetooth::Address) + 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char ch;
|
||||
for (uint32_t i = 0; i < sizeof(bluetooth::Address); ++i) {
|
||||
for (u32 i = 0; i < sizeof(bluetooth::Address); ++i) {
|
||||
ch = address->address[i] >> 4;
|
||||
*out++ = ch + (ch <= 9 ? '0' : 'a' - 0xa);
|
||||
ch = address->address[i] & 0x0f;
|
||||
|
@ -34,7 +35,7 @@ namespace ams::utils {
|
|||
}
|
||||
*out = '\0';
|
||||
|
||||
return ams::ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue