Merge pull request #8368 from german77/seventimes

Service: hid: Several improvements and implementations
This commit is contained in:
bunnei
2022-05-30 10:44:36 -07:00
committed by GitHub
6 changed files with 642 additions and 367 deletions

View File

@ -56,11 +56,22 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle
return npad_id && npad_type && device_index;
}
bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle) {
ResultCode Controller_NPad::VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle) {
const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
if (!npad_id) {
return InvalidNpadId;
}
const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
return npad_id && npad_type && device_index;
if (!device_index) {
return NpadDeviceIndexOutOfRange;
}
// This doesn't get validated on nnsdk
const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
if (!npad_type) {
return NpadInvalidHandle;
}
return ResultSuccess;
}
Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
@ -158,6 +169,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
shared_memory->system_properties.use_plus.Assign(1);
shared_memory->system_properties.use_minus.Assign(1);
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController;
shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1);
break;
case Core::HID::NpadStyleIndex::Handheld:
shared_memory->style_tag.handheld.Assign(1);
@ -170,16 +182,19 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
shared_memory->applet_nfc_xcd.applet_footer.type =
AppletFooterUiType::HandheldJoyConLeftJoyConRight;
shared_memory->sixaxis_handheld_properties.is_newly_assigned.Assign(1);
break;
case Core::HID::NpadStyleIndex::JoyconDual:
shared_memory->style_tag.joycon_dual.Assign(1);
if (controller.is_dual_left_connected) {
shared_memory->device_type.joycon_left.Assign(1);
shared_memory->system_properties.use_minus.Assign(1);
shared_memory->sixaxis_dual_left_properties.is_newly_assigned.Assign(1);
}
if (controller.is_dual_right_connected) {
shared_memory->device_type.joycon_right.Assign(1);
shared_memory->system_properties.use_plus.Assign(1);
shared_memory->sixaxis_dual_right_properties.is_newly_assigned.Assign(1);
}
shared_memory->system_properties.use_directional_buttons.Assign(1);
shared_memory->system_properties.is_vertical.Assign(1);
@ -198,6 +213,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
shared_memory->system_properties.is_horizontal.Assign(1);
shared_memory->system_properties.use_minus.Assign(1);
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1);
break;
case Core::HID::NpadStyleIndex::JoyconRight:
shared_memory->style_tag.joycon_right.Assign(1);
@ -205,6 +221,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
shared_memory->system_properties.is_horizontal.Assign(1);
shared_memory->system_properties.use_plus.Assign(1);
shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
shared_memory->sixaxis_right_properties.is_newly_assigned.Assign(1);
break;
case Core::HID::NpadStyleIndex::GameCube:
shared_memory->style_tag.gamecube.Assign(1);
@ -215,6 +232,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
case Core::HID::NpadStyleIndex::Pokeball:
shared_memory->style_tag.palma.Assign(1);
shared_memory->device_type.palma.Assign(1);
shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1);
break;
case Core::HID::NpadStyleIndex::NES:
shared_memory->style_tag.lark.Assign(1);
@ -582,6 +600,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
UNREACHABLE();
break;
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::Handheld:
@ -672,6 +691,12 @@ std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const {
}
void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
if (joy_hold_type != NpadJoyHoldType::Horizontal &&
joy_hold_type != NpadJoyHoldType::Vertical) {
LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}",
joy_hold_type);
return;
}
hold_type = joy_hold_type;
}
@ -695,11 +720,12 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode
return communication_mode;
}
void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
NpadJoyAssignmentMode assignment_mode) {
ResultCode Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id,
NpadJoyDeviceType npad_device_type,
NpadJoyAssignmentMode assignment_mode) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return;
return InvalidNpadId;
}
auto& controller = GetControllerFromNpadIdType(npad_id);
@ -708,7 +734,7 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy
}
if (!controller.device->IsConnected()) {
return;
return ResultSuccess;
}
if (assignment_mode == NpadJoyAssignmentMode::Dual) {
@ -717,34 +743,34 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy
controller.is_dual_left_connected = true;
controller.is_dual_right_connected = false;
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
return;
return ResultSuccess;
}
if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) {
DisconnectNpad(npad_id);
controller.is_dual_left_connected = false;
controller.is_dual_right_connected = true;
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
return;
return ResultSuccess;
}
return;
return ResultSuccess;
}
// This is for NpadJoyAssignmentMode::Single
// Only JoyconDual get affected by this function
if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) {
return;
return ResultSuccess;
}
if (controller.is_dual_left_connected && !controller.is_dual_right_connected) {
DisconnectNpad(npad_id);
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
return;
return ResultSuccess;
}
if (!controller.is_dual_left_connected && controller.is_dual_right_connected) {
DisconnectNpad(npad_id);
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
return;
return ResultSuccess;
}
// We have two controllers connected to the same npad_id we need to split them
@ -762,6 +788,7 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy
controller_2.is_dual_right_connected = false;
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true);
}
return ResultSuccess;
}
bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
@ -957,10 +984,10 @@ void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type,
InitNewlyAddedController(npad_id);
}
void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
ResultCode Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return;
return InvalidNpadId;
}
LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id);
@ -977,6 +1004,12 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
shared_memory->device_type.raw = 0;
shared_memory->system_properties.raw = 0;
shared_memory->button_properties.raw = 0;
shared_memory->sixaxis_fullkey_properties.raw = 0;
shared_memory->sixaxis_handheld_properties.raw = 0;
shared_memory->sixaxis_dual_left_properties.raw = 0;
shared_memory->sixaxis_dual_right_properties.raw = 0;
shared_memory->sixaxis_left_properties.raw = 0;
shared_memory->sixaxis_right_properties.raw = 0;
shared_memory->battery_level_dual = 0;
shared_memory->battery_level_left = 0;
shared_memory->battery_level_right = 0;
@ -997,346 +1030,268 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
controller.device->Disconnect();
SignalStyleSetChangedEvent(npad_id);
WriteEmptyEntry(shared_memory);
return ResultSuccess;
}
ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
GyroscopeZeroDriftMode drift_mode) {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
controller.sixaxis_fullkey.gyroscope_zero_drift_mode = drift_mode;
break;
case Core::HID::NpadStyleIndex::Handheld:
controller.sixaxis_handheld.gyroscope_zero_drift_mode = drift_mode;
break;
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::GameCube:
case Core::HID::NpadStyleIndex::Pokeball:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
controller.sixaxis_dual_left.gyroscope_zero_drift_mode = drift_mode;
break;
}
controller.sixaxis_dual_right.gyroscope_zero_drift_mode = drift_mode;
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
controller.sixaxis_left.gyroscope_zero_drift_mode = drift_mode;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
controller.sixaxis_right.gyroscope_zero_drift_mode = drift_mode;
break;
default:
LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
return NpadInvalidHandle;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.gyroscope_zero_drift_mode = drift_mode;
return ResultSuccess;
}
ResultCode Controller_NPad::GetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
GyroscopeZeroDriftMode& drift_mode) const {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
ResultCode Controller_NPad::GetGyroscopeZeroDriftMode(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
GyroscopeZeroDriftMode& drift_mode) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
drift_mode = controller.sixaxis_fullkey.gyroscope_zero_drift_mode;
break;
case Core::HID::NpadStyleIndex::Handheld:
drift_mode = controller.sixaxis_handheld.gyroscope_zero_drift_mode;
break;
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::GameCube:
case Core::HID::NpadStyleIndex::Pokeball:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
drift_mode = controller.sixaxis_dual_left.gyroscope_zero_drift_mode;
break;
}
drift_mode = controller.sixaxis_dual_right.gyroscope_zero_drift_mode;
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
drift_mode = controller.sixaxis_left.gyroscope_zero_drift_mode;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
drift_mode = controller.sixaxis_right.gyroscope_zero_drift_mode;
break;
default:
LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
return NpadInvalidHandle;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
drift_mode = sixaxis.gyroscope_zero_drift_mode;
return ResultSuccess;
}
ResultCode Controller_NPad::IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle,
bool& is_at_rest) const {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
ResultCode Controller_NPad::IsSixAxisSensorAtRest(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_at_rest) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& controller = GetControllerFromHandle(sixaxis_handle);
is_at_rest = controller.sixaxis_at_rest;
return ResultSuccess;
}
ResultCode Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_firmware_available) const {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
// We don't support joycon firmware updates
is_firmware_available = false;
const auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle);
is_firmware_available = sixaxis_properties.is_firmware_update_available != 0;
return ResultSuccess;
}
ResultCode Controller_NPad::SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
bool sixaxis_status) {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
ResultCode Controller_NPad::EnableSixAxisSensorUnalteredPassthrough(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.unaltered_passtrough = is_enabled;
return ResultSuccess;
}
ResultCode Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
is_enabled = sixaxis.unaltered_passtrough;
return ResultSuccess;
}
ResultCode Controller_NPad::LoadSixAxisSensorCalibrationParameter(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
// TODO: Request this data to the controller. On error return 0xd8ca
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
calibration = sixaxis.calibration;
return ResultSuccess;
}
ResultCode Controller_NPad::GetSixAxisSensorIcInformation(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorIcInformation& ic_information) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
// TODO: Request this data to the controller. On error return 0xd8ca
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
ic_information = sixaxis.ic_information;
return ResultSuccess;
}
ResultCode Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle);
sixaxis_properties.is_newly_assigned.Assign(0);
return ResultSuccess;
}
ResultCode Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool sixaxis_status) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
controller.sixaxis_sensor_enabled = sixaxis_status;
return ResultSuccess;
}
ResultCode Controller_NPad::IsSixAxisSensorFusionEnabled(
Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_fusion_enabled) const {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
is_fusion_enabled = controller.sixaxis_fullkey.is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::Handheld:
is_fusion_enabled = controller.sixaxis_handheld.is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::GameCube:
case Core::HID::NpadStyleIndex::Pokeball:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
is_fusion_enabled = controller.sixaxis_dual_left.is_fusion_enabled;
break;
}
is_fusion_enabled = controller.sixaxis_dual_right.is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
is_fusion_enabled = controller.sixaxis_left.is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
is_fusion_enabled = controller.sixaxis_right.is_fusion_enabled;
break;
default:
LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
return NpadInvalidHandle;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
is_fusion_enabled = sixaxis.is_fusion_enabled;
return ResultSuccess;
}
ResultCode Controller_NPad::SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
bool is_fusion_enabled) {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
ResultCode Controller_NPad::SetSixAxisFusionEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
controller.sixaxis_fullkey.is_fusion_enabled = is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::Handheld:
controller.sixaxis_handheld.is_fusion_enabled = is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::GameCube:
case Core::HID::NpadStyleIndex::Pokeball:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
controller.sixaxis_dual_left.is_fusion_enabled = is_fusion_enabled;
break;
}
controller.sixaxis_dual_right.is_fusion_enabled = is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
controller.sixaxis_left.is_fusion_enabled = is_fusion_enabled;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
controller.sixaxis_right.is_fusion_enabled = is_fusion_enabled;
break;
default:
LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
return NpadInvalidHandle;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.is_fusion_enabled = is_fusion_enabled;
return ResultSuccess;
}
ResultCode Controller_NPad::SetSixAxisFusionParameters(
Core::HID::SixAxisSensorHandle sixaxis_handle,
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto param1 = sixaxis_fusion_parameters.parameter1;
if (param1 < 0.0f || param1 > 1.0f) {
return InvalidSixAxisFusionRange;
}
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
controller.sixaxis_fullkey.fusion = sixaxis_fusion_parameters;
break;
case Core::HID::NpadStyleIndex::Handheld:
controller.sixaxis_handheld.fusion = sixaxis_fusion_parameters;
break;
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::GameCube:
case Core::HID::NpadStyleIndex::Pokeball:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
controller.sixaxis_dual_left.fusion = sixaxis_fusion_parameters;
break;
}
controller.sixaxis_dual_right.fusion = sixaxis_fusion_parameters;
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
controller.sixaxis_left.fusion = sixaxis_fusion_parameters;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
controller.sixaxis_right.fusion = sixaxis_fusion_parameters;
break;
default:
LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
return NpadInvalidHandle;
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
sixaxis.fusion = sixaxis_fusion_parameters;
return ResultSuccess;
}
ResultCode Controller_NPad::GetSixAxisFusionParameters(
Core::HID::SixAxisSensorHandle sixaxis_handle,
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters& parameters) const {
if (!IsDeviceHandleValid(sixaxis_handle)) {
LOG_ERROR(Service_HID, "Invalid handle");
return NpadInvalidHandle;
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
}
const auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
parameters = controller.sixaxis_fullkey.fusion;
break;
case Core::HID::NpadStyleIndex::Handheld:
parameters = controller.sixaxis_handheld.fusion;
break;
case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::GameCube:
case Core::HID::NpadStyleIndex::Pokeball:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
parameters = controller.sixaxis_dual_left.fusion;
break;
}
parameters = controller.sixaxis_dual_right.fusion;
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
parameters = controller.sixaxis_left.fusion;
break;
case Core::HID::NpadStyleIndex::JoyconRight:
parameters = controller.sixaxis_right.fusion;
break;
default:
LOG_ERROR(Service_HID, "Invalid Npad type {}", sixaxis_handle.npad_type);
return NpadInvalidHandle;
}
const auto& sixaxis = GetSixaxisState(sixaxis_handle);
parameters = sixaxis.fusion;
return ResultSuccess;
}
void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
ResultCode Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
npad_id_2);
return;
return InvalidNpadId;
}
auto& controller_1 = GetControllerFromNpadIdType(npad_id_1);
auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
const auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
const auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
bool merge_controllers = false;
auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
// If the controllers at both npad indices form a pair of left and right joycons, merge them.
// Otherwise, do nothing.
// Simplify this code by converting dualjoycon with only a side connected to single joycons
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual) {
if (controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) {
controller_style_1 = Core::HID::NpadStyleIndex::JoyconLeft;
}
if (!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) {
controller_style_1 = Core::HID::NpadStyleIndex::JoyconRight;
}
}
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) {
if (controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
controller_style_2 = Core::HID::NpadStyleIndex::JoyconLeft;
}
if (!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
controller_style_2 = Core::HID::NpadStyleIndex::JoyconRight;
}
}
// Invalid merge errors
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual ||
controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) {
return NpadIsDualJoycon;
}
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft) {
return NpadIsSameType;
}
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight &&
controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) {
merge_controllers = true;
}
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight) {
merge_controllers = true;
}
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight &&
controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) {
merge_controllers = true;
}
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) {
merge_controllers = true;
}
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight &&
controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
merge_controllers = true;
}
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
merge_controllers = true;
}
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected &&
!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
merge_controllers = true;
}
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected &&
controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
merge_controllers = true;
return NpadIsSameType;
}
if (merge_controllers) {
// Disconnect the joycon at the second id and connect the dual joycon at the first index.
DisconnectNpad(npad_id_2);
controller_1.is_dual_left_connected = true;
controller_1.is_dual_right_connected = true;
AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
return;
// These exceptions are handled as if they where dual joycon
if (controller_style_1 != Core::HID::NpadStyleIndex::JoyconLeft &&
controller_style_1 != Core::HID::NpadStyleIndex::JoyconRight) {
return NpadIsDualJoycon;
}
LOG_WARNING(Service_HID,
"Controllers can't be merged npad_id_1:{}, npad_id_2:{}, type_1:{}, type_2:{}, "
"dual_1(left/right):{}/{}, dual_2(left/right):{}/{}",
npad_id_1, npad_id_2, controller_1.device->GetNpadStyleIndex(),
controller_2.device->GetNpadStyleIndex(), controller_1.is_dual_left_connected,
controller_1.is_dual_right_connected, controller_2.is_dual_left_connected,
controller_2.is_dual_right_connected);
if (controller_style_2 != Core::HID::NpadStyleIndex::JoyconLeft &&
controller_style_2 != Core::HID::NpadStyleIndex::JoyconRight) {
return NpadIsDualJoycon;
}
// Disconnect the joycon at the second id and connect the dual joycon at the first index.
DisconnectNpad(npad_id_2);
controller_1.is_dual_left_connected = true;
controller_1.is_dual_right_connected = true;
AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
return ResultSuccess;
}
void Controller_NPad::StartLRAssignmentMode() {
@ -1349,17 +1304,17 @@ void Controller_NPad::StopLRAssignmentMode() {
is_in_lr_assignment_mode = false;
}
bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
ResultCode Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
npad_id_2);
return false;
return InvalidNpadId;
}
if (npad_id_1 == Core::HID::NpadIdType::Handheld ||
npad_id_2 == Core::HID::NpadIdType::Handheld || npad_id_1 == Core::HID::NpadIdType::Other ||
npad_id_2 == Core::HID::NpadIdType::Other) {
return true;
return ResultSuccess;
}
const auto& controller_1 = GetControllerFromNpadIdType(npad_id_1).device;
const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device;
@ -1369,46 +1324,49 @@ bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
const auto is_connected_2 = controller_2->IsConnected();
if (!IsControllerSupported(type_index_1) && is_connected_1) {
return false;
return NpadNotConnected;
}
if (!IsControllerSupported(type_index_2) && is_connected_2) {
return false;
return NpadNotConnected;
}
UpdateControllerAt(type_index_2, npad_id_1, is_connected_2);
UpdateControllerAt(type_index_1, npad_id_2, is_connected_1);
return true;
return ResultSuccess;
}
Core::HID::LedPattern Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id) {
ResultCode Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id,
Core::HID::LedPattern& pattern) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return Core::HID::LedPattern{0, 0, 0, 0};
return InvalidNpadId;
}
const auto& controller = GetControllerFromNpadIdType(npad_id).device;
return controller->GetLedPattern();
pattern = controller->GetLedPattern();
return ResultSuccess;
}
bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(
Core::HID::NpadIdType npad_id) const {
ResultCode Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(
Core::HID::NpadIdType npad_id, bool& is_valid) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
// Return the default value
return false;
return InvalidNpadId;
}
const auto& controller = GetControllerFromNpadIdType(npad_id);
return controller.unintended_home_button_input_protection;
is_valid = controller.unintended_home_button_input_protection;
return ResultSuccess;
}
void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
Core::HID::NpadIdType npad_id) {
ResultCode Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(
bool is_protection_enabled, Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return;
return InvalidNpadId;
}
auto& controller = GetControllerFromNpadIdType(npad_id);
controller.unintended_home_button_input_protection = is_protection_enabled;
return ResultSuccess;
}
void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
@ -1546,4 +1504,96 @@ const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpa
return controller_data[npad_index];
}
Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.shared_memory->sixaxis_fullkey_properties;
case Core::HID::NpadStyleIndex::Handheld:
return controller.shared_memory->sixaxis_handheld_properties;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.shared_memory->sixaxis_dual_left_properties;
}
return controller.shared_memory->sixaxis_dual_right_properties;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.shared_memory->sixaxis_left_properties;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.shared_memory->sixaxis_right_properties;
default:
return controller.shared_memory->sixaxis_fullkey_properties;
}
}
const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
const auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.shared_memory->sixaxis_fullkey_properties;
case Core::HID::NpadStyleIndex::Handheld:
return controller.shared_memory->sixaxis_handheld_properties;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.shared_memory->sixaxis_dual_left_properties;
}
return controller.shared_memory->sixaxis_dual_right_properties;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.shared_memory->sixaxis_left_properties;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.shared_memory->sixaxis_right_properties;
default:
return controller.shared_memory->sixaxis_fullkey_properties;
}
}
Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.sixaxis_fullkey;
case Core::HID::NpadStyleIndex::Handheld:
return controller.sixaxis_handheld;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.sixaxis_dual_left;
}
return controller.sixaxis_dual_right;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.sixaxis_left;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.sixaxis_right;
default:
return controller.sixaxis_unknown;
}
}
const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
const auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
case Core::HID::NpadStyleIndex::ProController:
case Core::HID::NpadStyleIndex::Pokeball:
return controller.sixaxis_fullkey;
case Core::HID::NpadStyleIndex::Handheld:
return controller.sixaxis_handheld;
case Core::HID::NpadStyleIndex::JoyconDual:
if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
return controller.sixaxis_dual_left;
}
return controller.sixaxis_dual_right;
case Core::HID::NpadStyleIndex::JoyconLeft:
return controller.sixaxis_left;
case Core::HID::NpadStyleIndex::JoyconRight:
return controller.sixaxis_right;
default:
return controller.sixaxis_unknown;
}
}
} // namespace Service::HID

View File

@ -107,8 +107,8 @@ public:
void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
NpadCommunicationMode GetNpadCommunicationMode() const;
void SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
NpadJoyAssignmentMode assignment_mode);
ResultCode SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
NpadJoyAssignmentMode assignment_mode);
bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
const Core::HID::VibrationValue& vibration_value);
@ -141,50 +141,65 @@ public:
void UpdateControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id,
bool connected);
void DisconnectNpad(Core::HID::NpadIdType npad_id);
ResultCode DisconnectNpad(Core::HID::NpadIdType npad_id);
ResultCode SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
ResultCode SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
GyroscopeZeroDriftMode drift_mode);
ResultCode GetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
ResultCode GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
GyroscopeZeroDriftMode& drift_mode) const;
ResultCode IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle,
ResultCode IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_at_rest) const;
ResultCode IsFirmwareUpdateAvailableForSixAxisSensor(
Core::HID::SixAxisSensorHandle sixaxis_handle, bool& is_firmware_available) const;
ResultCode SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const;
ResultCode EnableSixAxisSensorUnalteredPassthrough(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
ResultCode IsSixAxisSensorUnalteredPassthroughEnabled(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
ResultCode LoadSixAxisSensorCalibrationParameter(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
ResultCode GetSixAxisSensorIcInformation(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorIcInformation& ic_information) const;
ResultCode ResetIsSixAxisSensorDeviceNewlyAssigned(
const Core::HID::SixAxisSensorHandle& sixaxis_handle);
ResultCode SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool sixaxis_status);
ResultCode IsSixAxisSensorFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
ResultCode IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_fusion_enabled) const;
ResultCode SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
ResultCode SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool is_fusion_enabled);
ResultCode SetSixAxisFusionParameters(
Core::HID::SixAxisSensorHandle sixaxis_handle,
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
ResultCode GetSixAxisFusionParameters(
Core::HID::SixAxisSensorHandle sixaxis_handle,
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::SixAxisSensorFusionParameters& parameters) const;
Core::HID::LedPattern GetLedPattern(Core::HID::NpadIdType npad_id);
bool IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id) const;
void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
Core::HID::NpadIdType npad_id);
ResultCode GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
ResultCode IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
bool& is_enabled) const;
ResultCode SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
Core::HID::NpadIdType npad_id);
void SetAnalogStickUseCenterClamp(bool use_center_clamp);
void ClearAllConnectedControllers();
void DisconnectAllConnectedControllers();
void ConnectAllDisconnectedControllers();
void ClearAllControllers();
void MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
ResultCode MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2);
void StartLRAssignmentMode();
void StopLRAssignmentMode();
bool SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
ResultCode SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
// Logical OR for all buttons presses on all controllers
// Specifically for cheat engine and other features.
Core::HID::NpadButton GetAndResetPressState();
static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
static bool IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle);
static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
static ResultCode VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle);
private:
static constexpr std::size_t NPAD_COUNT = 10;
@ -451,9 +466,13 @@ private:
NpadLuciaType lucia_type{};
NpadLagonType lagon_type{};
NpadLagerType lager_type{};
// FW 13.x Investigate there is some sort of bitflag related to joycons
INSERT_PADDING_BYTES(0x4);
INSERT_PADDING_BYTES(0xc08); // Unknown
Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties;
Core::HID::SixAxisSensorProperties sixaxis_handheld_properties;
Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties;
Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties;
Core::HID::SixAxisSensorProperties sixaxis_left_properties;
Core::HID::SixAxisSensorProperties sixaxis_right_properties;
INSERT_PADDING_BYTES(0xc06); // Unknown
};
static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size");
@ -465,7 +484,10 @@ private:
struct SixaxisParameters {
bool is_fusion_enabled{true};
bool unaltered_passtrough{false};
Core::HID::SixAxisSensorFusionParameters fusion{};
Core::HID::SixAxisSensorCalibrationParameter calibration{};
Core::HID::SixAxisSensorIcInformation ic_information{};
GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
};
@ -491,6 +513,7 @@ private:
SixaxisParameters sixaxis_dual_right{};
SixaxisParameters sixaxis_left{};
SixaxisParameters sixaxis_right{};
SixaxisParameters sixaxis_unknown{};
// Current pad state
NPadGenericState npad_pad_state{};
@ -522,6 +545,14 @@ private:
NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& device_handle);
const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& device_handle) const;
SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
const SixaxisParameters& GetSixaxisState(
const Core::HID::SixAxisSensorHandle& device_handle) const;
std::atomic<u64> press_state{};
std::array<NpadControllerData, NPAD_COUNT> controller_data{};