mc.mitm: misc. code cleanup and style improvements

This commit is contained in:
ndeadly 2023-02-22 22:25:51 +01:00
parent e68f6035c4
commit 5287296cb3
74 changed files with 2044 additions and 2012 deletions

View file

@ -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() {

View file

@ -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() {
@ -57,19 +58,19 @@ namespace ams::bluetooth::ble {
}
Result GetEventInfo(bluetooth::BleEventType *type, void *buffer, size_t size) {
std::scoped_lock lk(g_event_data_lock);
std::scoped_lock lk(g_event_data_lock);
*type = g_current_event_type;
std::memcpy(buffer, &g_event_info, size);
g_data_read_event.Signal();
return ams::ResultSuccess();
R_SUCCEED();
}
void HandleEvent() {
{
std::scoped_lock lk(g_event_data_lock);
std::scoped_lock lk(g_event_data_lock);
R_ABORT_UNLESS(btdrvGetBleManagedEventInfo(&g_event_info, sizeof(bluetooth::BleEventInfo), &g_current_event_type));
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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();
}

View file

@ -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;
@ -53,7 +53,7 @@ namespace ams::bluetooth::events {
os::LinkMultiWaitHolder(&g_manager, &g_holder_bt_ble);
}
for (;;) {
for (;;) {
auto signalled_holder = os::WaitAny(&g_manager);
switch (os::GetMultiWaitHolderUserData(signalled_holder)) {
case BtdrvEventType_BluetoothCore:
@ -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() {

View file

@ -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) {

View file

@ -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();
}
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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() {

View file

@ -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) {

View file

@ -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);

View file

@ -19,6 +19,8 @@
namespace ams::btm {
using Profile = ::BtmProfile;
struct DeviceConditionV100 : public sf::LargeData {
BtmDeviceConditionV100 condition;
};

View file

@ -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();
}
}

View file

@ -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>);

View file

@ -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} },
);
}

View file

@ -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
}

View file

@ -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() {

View file

@ -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;

View file

@ -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[] = {

View file

@ -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;

View file

@ -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[] = {

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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));
}
}

View file

@ -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;

View file

@ -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) {
@ -96,14 +96,14 @@ namespace ams::controller {
}
}
void Dualshock4Controller::MapInputReport0x01(const Dualshock4ReportData *src) {
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));
}
}

View file

@ -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;

View file

@ -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));
}
}

View file

@ -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;

View file

@ -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) ||

View file

@ -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[] = {
@ -113,7 +113,7 @@ namespace ams::controller {
{0xffff, 0x046f}, // Gamesir G4s
{0xffff, 0x0450}, // Gamesir T1s
{0x05ac, 0x056b} // Gamesir T2a
};
};
GamesirController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }

View file

@ -21,7 +21,7 @@ namespace ams::controller {
namespace {
const constexpr float stick_scale_factor = float(UINT12_MAX) / UINT8_MAX;
}
void GamestickController::ProcessInputData(const bluetooth::HidReport *report) {
@ -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;

View file

@ -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[] = {

View file

@ -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;

View file

@ -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[] = {

View file

@ -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;

View file

@ -31,48 +31,48 @@ 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[] = {
static constexpr const HardwareID hardware_ids[] = {
{0x2e24, 0x200a} // Hyperkin Scout
};
};
HyperkinController(const bluetooth::Address *address, HardwareID id)
HyperkinController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }
bool SupportsSetTsiCommand() { return false; }

View file

@ -19,22 +19,22 @@
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[] = {
{0x15e4, 0x0132} // ION iCade Controller
};
};
ICadeController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }

View file

@ -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;

View file

@ -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[] = {
@ -87,7 +87,7 @@ namespace ams::controller {
{0x05ac, 0x022c} // ipega 9017S (Another fucking Apple keyboard ID. Eventually these are going to clash)
};
IpegaController(const bluetooth::Address *address, HardwareID id)
IpegaController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }
void ProcessInputData(const bluetooth::HidReport *report) override;

View file

@ -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;
@ -66,7 +66,7 @@ namespace ams::controller {
m_buttons.R = src->input0x01.buttons.R1;
m_buttons.ZR = src->input0x01.buttons.R2;
m_buttons.L = src->input0x01.buttons.L1;
m_buttons.ZL = src->input0x01.buttons.L2;
m_buttons.ZL = src->input0x01.buttons.L2;
//m_buttons.minus = src->input0x01.buttons.select;
m_buttons.plus = src->input0x01.buttons.start;

View file

@ -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[] = {

View file

@ -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;
@ -75,7 +75,7 @@ namespace ams::controller {
m_buttons.R = src->input0x01.buttons.R1;
m_buttons.ZR = src->input0x01.right_trigger > 0;
m_buttons.L = src->input0x01.buttons.L1;
m_buttons.ZL = src->input0x01.left_trigger > 0;
m_buttons.ZL = src->input0x01.left_trigger > 0;
m_buttons.minus = src->input0x01.buttons.select;
m_buttons.plus = src->input0x01.buttons.start;

View file

@ -31,47 +31,47 @@ 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;
} __attribute__ ((__packed__));
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;
} __attribute__ ((__packed__));
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 {
struct {
@ -147,7 +147,7 @@ namespace ams::controller {
} __attribute__ ((__packed__));
struct MadCatzReportData {
uint8_t id;
u8 id;
union {
MadCatzInputReport0x01 input0x01;
MadCatzInputReport0x02 input0x02;
@ -155,16 +155,16 @@ 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[] = {
{0x0738, 0x5266}, // Mad Catz C.T.R.L.R
{0x0738, 0x5250}, // Mad Catz C.T.R.L.R for Samsung
{0x0738, 0x5269} // Mad Catz L.Y.N.X. 3
};
};
MadCatzController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }

View file

@ -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;
@ -84,7 +84,7 @@ namespace ams::controller {
m_buttons.R = src->input0x01.buttons.R1;
m_buttons.ZR = src->input0x01.buttons.R2;
m_buttons.L = src->input0x01.buttons.L1;
m_buttons.ZL = src->input0x01.buttons.L2;
m_buttons.ZL = src->input0x01.buttons.L2;
m_buttons.minus = src->input0x01.buttons.select;
m_buttons.plus = src->input0x01.buttons.start;

View file

@ -43,51 +43,51 @@ 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;
} __attribute__ ((__packed__));
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[] = {
static constexpr const HardwareID hardware_ids[] = {
{0xffff, 0x0000}, // Mocute 050 Controller
{0x04e8, 0x046e} // Mocute 050 Controller
};
};
MocuteController(const bluetooth::Address *address, HardwareID id)
MocuteController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }
bool SupportsSetTsiCommand() { return false; }

View file

@ -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;

View file

@ -31,55 +31,55 @@ 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[] = {
{0x0955, 0x7214} // Nvidia Shield Controller (2017) v1.04
};
};
NvidiaShieldController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }

View file

@ -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;
}
}

View file

@ -19,57 +19,57 @@
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[] = {
{0x2836, 0x0001}
};
};
OuyaController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }

View file

@ -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;

View file

@ -31,53 +31,53 @@ 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[] = {
static constexpr const HardwareID hardware_ids[] = {
{0x20d6, 0x89e5}, // Moga Hero Controller
{0x20d6, 0x0dad}, // Moga Pro Controller
{0x20d6, 0x6271} // Moga Pro 2 Controller
};
};
PowerAController(const bluetooth::Address *address, HardwareID id)
PowerAController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }
bool SupportsSetTsiCommand() { return false; }

View file

@ -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;
@ -72,7 +72,7 @@ namespace ams::controller {
m_buttons.plus = src->input0x01.buttons.start;
m_buttons.lstick_press = src->input0x01.buttons.L3;
m_buttons.rstick_press = src->input0x01.buttons.R3;
m_buttons.rstick_press = src->input0x01.buttons.R3;
m_buttons.capture = src->input0x01.buttons.back;
m_buttons.home = src->input0x01.buttons.home;

View file

@ -31,54 +31,53 @@ 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[] = {
static constexpr const HardwareID hardware_ids[] = {
{0x1532, 0x0900} // Razer Serval
};
};
RazerController(const bluetooth::Address *address, HardwareID id)
RazerController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }
void ProcessInputData(const bluetooth::HidReport *report) override;

View file

@ -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;

View file

@ -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[] = {

View file

@ -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);
}

View file

@ -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];
};
}

View file

@ -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(); };

View file

@ -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);

View file

@ -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();
}
}

View file

@ -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));
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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,40 +109,40 @@ 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[] = {
static constexpr const HardwareID hardware_ids[] = {
{0x045e, 0x02e0}, // Official Xbox One S Controller
{0x045e, 0x02fd}, // Official Xbox One S Controller
{0x045e, 0x0b00}, // Official Xbox One Elite 2 Controller
{0x045e, 0x0b05}, // Official Xbox One Elite 2 Controller
{0x045e, 0x0b0a} // Official Xbox Adaptive Controller
};
};
XboxOneController(const bluetooth::Address *address, HardwareID id)
XboxOneController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }
bool SupportsSetTsiCommand() { return false; }

View file

@ -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;
@ -35,10 +35,10 @@ namespace ams::controller {
m_output_report.size = sizeof(init_packet);
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) {
auto xiaomi_report = reinterpret_cast<const XiaomiReportData *>(&report->data);
@ -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;
@ -83,15 +83,15 @@ namespace ams::controller {
m_buttons.R = src->input0x04.buttons.R1;
m_buttons.ZR = src->input0x04.buttons.R2;
m_buttons.L = src->input0x04.buttons.L1;
m_buttons.ZL = src->input0x04.buttons.L2;
m_buttons.ZL = src->input0x04.buttons.L2;
m_buttons.minus = src->input0x04.buttons.back;
m_buttons.plus = src->input0x04.buttons.menu;
m_buttons.lstick_press = src->input0x04.buttons.lstick_press;
m_buttons.rstick_press = src->input0x04.buttons.rstick_press;
m_buttons.rstick_press = src->input0x04.buttons.rstick_press;
m_buttons.home = src->input0x04.home;
m_buttons.home = src->input0x04.home;
}
}

View file

@ -31,64 +31,64 @@ 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;
uint8_t dpad;
} __attribute__((packed));
u8 _unk;
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[] = {
{0x2717, 0x3144} // Xiaomi Mi Controller
};
};
XiaomiController(const bluetooth::Address *address, HardwareID id)
XiaomiController(const bluetooth::Address *address, HardwareID id)
: EmulatedSwitchController(address, id) { }
bool SupportsSetTsiCommand() { return false; }

View file

@ -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() {

View file

@ -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();
}
}

View file

@ -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)
ParseBoolean(value, &config->general.enable_rumble);
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)
if (strcasecmp(name, "enable_rumble") == 0) {
ParseBoolean(value, &config->general.enable_rumble);
} 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) {
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;
}

View file

@ -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();
}
}