summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/kernel/k_process.cpp4
-rw-r--r--src/core/hle/kernel/k_thread.cpp4
-rw-r--r--src/core/hle/kernel/k_thread.h25
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp648
-rw-r--r--src/core/hle/service/hid/controllers/npad.h75
-rw-r--r--src/core/hle/service/hid/errors.h4
-rw-r--r--src/core/hle/service/hid/hid.cpp236
-rw-r--r--src/core/hle/service/hid/hid.h5
-rw-r--r--src/core/hle/service/hid/irs.cpp249
-rw-r--r--src/core/hle/service/hid/irs.h232
-rw-r--r--src/core/hle/service/jit/jit_context.cpp32
-rw-r--r--src/core/hle/service/time/time_zone_manager.cpp7
12 files changed, 1104 insertions, 417 deletions
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 490e31fc7..dcfeacccd 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -64,6 +64,10 @@ void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority
{
KScopedSchedulerLock lock{kernel};
thread->SetState(ThreadState::Runnable);
+
+ if (system.DebuggerEnabled()) {
+ thread->RequestSuspend(SuspendType::Debug);
+ }
}
}
} // Anonymous namespace
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index ab9ce6a86..940334f59 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -198,6 +198,10 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s
resource_limit_release_hint = false;
cpu_time = 0;
+ // Set debug context.
+ stack_top = user_stack_top;
+ argument = arg;
+
// Clear our stack parameters.
std::memset(static_cast<void*>(std::addressof(GetStackParameters())), 0,
sizeof(StackParameters));
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index b55a922ab..f4d83f99a 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -100,6 +100,12 @@ enum class ThreadWaitReasonForDebugging : u32 {
Suspended, ///< Thread is waiting due to process suspension
};
+enum class StepState : u32 {
+ NotStepping, ///< Thread is not currently stepping
+ StepPending, ///< Thread will step when next scheduled
+ StepPerformed, ///< Thread has stepped, waiting to be scheduled again
+};
+
[[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel);
[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);
[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
@@ -267,6 +273,14 @@ public:
void SetState(ThreadState state);
+ [[nodiscard]] StepState GetStepState() const {
+ return step_state;
+ }
+
+ void SetStepState(StepState state) {
+ step_state = state;
+ }
+
[[nodiscard]] s64 GetLastScheduledTick() const {
return last_scheduled_tick;
}
@@ -646,6 +660,14 @@ public:
void IfDummyThreadTryWait();
void IfDummyThreadEndWait();
+ [[nodiscard]] uintptr_t GetArgument() const {
+ return argument;
+ }
+
+ [[nodiscard]] VAddr GetUserStackTop() const {
+ return stack_top;
+ }
+
private:
static constexpr size_t PriorityInheritanceCountMax = 10;
union SyncObjectBuffer {
@@ -769,6 +791,7 @@ private:
std::shared_ptr<Common::Fiber> host_context{};
bool is_single_core{};
ThreadType thread_type{};
+ StepState step_state{};
std::mutex dummy_wait_lock;
std::condition_variable dummy_wait_cv;
@@ -776,6 +799,8 @@ private:
std::vector<KSynchronizationObject*> wait_objects_for_debugging;
VAddr mutex_wait_address_for_debugging{};
ThreadWaitReasonForDebugging wait_reason_for_debugging{};
+ uintptr_t argument;
+ VAddr stack_top;
public:
using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index de06e1735..1e04ee3f2 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -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;
+ }
+
+ const auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle);
+ is_firmware_available = sixaxis_properties.is_firmware_update_available != 0;
+ return ResultSuccess;
+}
+
+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;
}
- // We don't support joycon firmware updates
- is_firmware_available = false;
+ // 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::SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
+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) {
- 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;
}
+
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;
- }
-
- 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;
+ return NpadIsSameType;
+ }
+
+ // 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
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 0a96825a5..0b662b7f8 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -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{};
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h
index b31834074..6c8ad04af 100644
--- a/src/core/hle/service/hid/errors.h
+++ b/src/core/hle/service/hid/errors.h
@@ -8,7 +8,11 @@
namespace Service::HID {
constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100};
+constexpr ResultCode NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423};
+constexpr ResultCode NpadIsDualJoycon{ErrorModule::HID, 601};
+constexpr ResultCode NpadIsSameType{ErrorModule::HID, 602};
+constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709};
constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 44f892da9..8a496c38c 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -257,12 +257,12 @@ Hid::Hid(Core::System& system_)
{81, &Hid::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"},
{82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
{83, &Hid::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"},
- {84, nullptr, "EnableSixAxisSensorUnalteredPassthrough"},
- {85, nullptr, "IsSixAxisSensorUnalteredPassthroughEnabled"},
+ {84, &Hid::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"},
+ {85, &Hid::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"},
{86, nullptr, "StoreSixAxisSensorCalibrationParameter"},
- {87, nullptr, "LoadSixAxisSensorCalibrationParameter"},
- {88, nullptr, "GetSixAxisSensorIcInformation"},
- {89, nullptr, "ResetIsSixAxisSensorDeviceNewlyAssigned"},
+ {87, &Hid::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"},
+ {88, &Hid::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"},
+ {89, &Hid::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"},
{91, &Hid::ActivateGesture, "ActivateGesture"},
{100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
{101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
@@ -694,11 +694,7 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
rb.Push(result1);
return;
}
- if (result2.IsError()) {
- rb.Push(result2);
- return;
- }
- rb.Push(ResultSuccess);
+ rb.Push(result2);
}
void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
@@ -821,6 +817,144 @@ void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& c
rb.Push(is_firmware_available);
}
+void Hid::EnableSixAxisSensorUnalteredPassthrough(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool enabled;
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.EnableSixAxisSensorUnalteredPassthrough(
+ parameters.sixaxis_handle, parameters.enabled);
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, "
+ "applet_resource_user_id={}",
+ parameters.enabled, parameters.sixaxis_handle.npad_type,
+ parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
+ parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ bool is_unaltered_sisxaxis_enabled{};
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.IsSixAxisSensorUnalteredPassthroughEnabled(
+ parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.Push(is_unaltered_sisxaxis_enabled);
+}
+
+void Hid::LoadSixAxisSensorCalibrationParameter(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::SixAxisSensorCalibrationParameter calibration{};
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result =
+ controller.LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ if (result.IsSuccess()) {
+ ctx.WriteBuffer(calibration);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::GetSixAxisSensorIcInformation(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::SixAxisSensorIcInformation ic_information{};
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result =
+ controller.GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ if (result.IsSuccess()) {
+ ctx.WriteBuffer(ic_information);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result =
+ controller.ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
@@ -948,27 +1082,29 @@ void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .DisconnectNpad(parameters.npad_id);
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.DisconnectNpad(parameters.npad_id);
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
+ Core::HID::LedPattern pattern{0, 0, 0, 0};
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.GetLedPattern(npad_id, pattern);
+
LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetLedPattern(npad_id)
- .raw);
+ rb.Push(result);
+ rb.Push(pattern.raw);
}
void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
@@ -1028,15 +1164,16 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
const auto parameters{rp.PopRaw<Parameters>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left,
- Controller_NPad::NpadJoyAssignmentMode::Single);
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result =
+ controller.SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left,
+ Controller_NPad::NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
@@ -1051,16 +1188,16 @@ void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type,
- Controller_NPad::NpadJoyAssignmentMode::Single);
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type,
+ Controller_NPad::NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
parameters.npad_id, parameters.applet_resource_user_id,
parameters.npad_joy_device_type);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
@@ -1074,14 +1211,15 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual);
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.SetNpadMode(parameters.npad_id, {},
+ Controller_NPad::NpadJoyAssignmentMode::Dual);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
@@ -1090,14 +1228,14 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
npad_id_1, npad_id_2, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
@@ -1157,19 +1295,14 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- const bool res = applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SwapNpadAssignment(npad_id_1, npad_id_2);
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.SwapNpadAssignment(npad_id_1, npad_id_2);
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
npad_id_1, npad_id_2, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- if (res) {
- rb.Push(ResultSuccess);
- } else {
- LOG_ERROR(Service_HID, "Npads are not connected!");
- rb.Push(NpadNotConnected);
- }
+ rb.Push(result);
}
void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx) {
@@ -1183,13 +1316,17 @@ void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext
const auto parameters{rp.PopRaw<Parameters>()};
+ bool is_enabled = false;
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result =
+ controller.IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
+
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
parameters.npad_id, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id));
+ rb.Push(result);
+ rb.Push(is_enabled);
}
void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx) {
@@ -1204,9 +1341,9 @@ void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& c
const auto parameters{rp.PopRaw<Parameters>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetUnintendedHomeButtonInputProtectionEnabled(
- parameters.unintended_home_button_input_protection, parameters.npad_id);
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled(
+ parameters.unintended_home_button_input_protection, parameters.npad_id);
LOG_WARNING(Service_HID,
"(STUBBED) called, unintended_home_button_input_protection={}, npad_id={},"
@@ -1215,7 +1352,7 @@ void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& c
parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void Hid::SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx) {
@@ -1377,6 +1514,8 @@ void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_vibrate{rp.Pop<bool>()};
+ // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value
+ // by converting it to a bool
Settings::values.vibration_enabled.SetValue(can_vibrate);
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
@@ -1388,9 +1527,12 @@ void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
+ // nnSDK checks if a float is greater than zero. We return the bool we stored earlier
+ const auto is_enabled = Settings::values.vibration_enabled.GetValue();
+
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.Push(Settings::values.vibration_enabled.GetValue());
+ rb.Push(is_enabled);
}
void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 1be04c22b..ac4333022 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -113,6 +113,11 @@ private:
void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx);
void IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx);
+ void EnableSixAxisSensorUnalteredPassthrough(Kernel::HLERequestContext& ctx);
+ void IsSixAxisSensorUnalteredPassthroughEnabled(Kernel::HLERequestContext& ctx);
+ void LoadSixAxisSensorCalibrationParameter(Kernel::HLERequestContext& ctx);
+ void GetSixAxisSensorIcInformation(Kernel::HLERequestContext& ctx);
+ void ResetIsSixAxisSensorDeviceNewlyAssigned(Kernel::HLERequestContext& ctx);
void ActivateGesture(Kernel::HLERequestContext& ctx);
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 9e32f3e60..d2a91d913 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -5,7 +5,9 @@
#include "core/core_timing.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_shared_memory.h"
+#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/irs.h"
namespace Service::HID {
@@ -38,21 +40,32 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
}
void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
+ applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::DeactivateIrsensor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
+ applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_IRS, "called");
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
@@ -60,35 +73,109 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
}
void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ PackedMomentProcessorConfig processor_config;
+ };
+ static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ PackedClusteringProcessorConfig processor_config;
+ };
+ static_assert(sizeof(Parameters) == 0x40, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ PackedImageTransferProcessorConfig processor_config;
+ u32 transfer_memory_size;
+ };
+ static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+ const auto t_mem_handle{ctx.GetCopyHandle(0)};
+
+ auto t_mem =
+ system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, "
+ "applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.transfer_memory_size, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 5};
rb.Push(ResultSuccess);
@@ -97,71 +184,195 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
}
void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
+ const auto processor_config{rp.PopRaw<PackedTeraPluginProcessorConfig>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, "
+ "applet_resource_user_id={}",
+ camera_handle.npad_type, camera_handle.npad_id, processor_config.mode,
+ processor_config.required_mcu_version.major,
+ processor_config.required_mcu_version.minor, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid &&
+ npad_id != Core::HID::NpadIdType::Handheld) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(InvalidNpadId);
+ return;
+ }
+
+ IrCameraHandle camera_handle{
+ .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)),
+ .npad_type = Core::HID::NpadStyleIndex::None,
+ };
+
+ LOG_WARNING(Service_IRS, "(STUBBED) called, npad_id={}, camera_npad_id={}, camera_npad_type={}",
+ npad_id, camera_handle.npad_id, camera_handle.npad_type);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.PushRaw<u32>(device_handle);
+ rb.PushRaw(camera_handle);
}
void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
+ const auto processor_config{rp.PopRaw<PackedPointingProcessorConfig>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(
+ Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}",
+ camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major,
+ processor_config.required_mcu_version.minor, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
+ const auto mcu_version{rp.PopRaw<PackedMcuVersion>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(
+ Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}",
+ camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major,
+ mcu_version.minor);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ PackedFunctionLevel function_level;
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ PackedImageTransferProcessorExConfig processor_config;
+ u64 transfer_memory_size;
+ };
+ static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+ const auto t_mem_handle{ctx.GetCopyHandle(0)};
+
+ auto t_mem =
+ system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, "
+ "applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.transfer_memory_size, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
+ const auto processor_config{rp.PopRaw<PackedIrLedProcessorConfig>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} "
+ "applet_resource_user_id={}",
+ camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target,
+ processor_config.required_mcu_version.major,
+ processor_config.required_mcu_version.minor, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ IrCameraHandle camera_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS,
+ "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
+ parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_IRS, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ PackedFunctionLevel function_level;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}",
+ parameters.function_level.function_level, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index efb29d3fd..361dc2213 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -3,6 +3,7 @@
#pragma once
+#include "core/hid/hid_types.h"
#include "core/hle/service/service.h"
namespace Core {
@@ -17,6 +18,235 @@ public:
~IRS() override;
private:
+ // This is nn::irsensor::IrCameraStatus
+ enum IrCameraStatus : u32 {
+ Available,
+ Unsupported,
+ Unconnected,
+ };
+
+ // This is nn::irsensor::IrCameraInternalStatus
+ enum IrCameraInternalStatus : u32 {
+ Stopped,
+ FirmwareUpdateNeeded,
+ Unkown2,
+ Unkown3,
+ Unkown4,
+ FirmwareVersionRequested,
+ FirmwareVersionIsInvalid,
+ Ready,
+ Setting,
+ };
+
+ // This is nn::irsensor::detail::StatusManager::IrSensorMode
+ enum IrSensorMode : u64 {
+ None,
+ MomentProcessor,
+ ClusteringProcessor,
+ ImageTransferProcessor,
+ PointingProcessorMarker,
+ TeraPluginProcessor,
+ IrLedProcessor,
+ };
+
+ // This is nn::irsensor::ImageProcessorStatus
+ enum ImageProcessorStatus : u8 {
+ stopped,
+ running,
+ };
+
+ // This is nn::irsensor::ImageTransferProcessorFormat
+ enum ImageTransferProcessorFormat : u8 {
+ Size320x240,
+ Size160x120,
+ Size80x60,
+ Size40x30,
+ Size20x15,
+ };
+
+ // This is nn::irsensor::AdaptiveClusteringMode
+ enum AdaptiveClusteringMode : u8 {
+ StaticFov,
+ DynamicFov,
+ };
+
+ // This is nn::irsensor::AdaptiveClusteringTargetDistance
+ enum AdaptiveClusteringTargetDistance : u8 {
+ Near,
+ Middle,
+ Far,
+ };
+
+ // This is nn::irsensor::IrsHandAnalysisMode
+ enum IrsHandAnalysisMode : u8 {
+ Silhouette,
+ Image,
+ SilhoueteAndImage,
+ SilhuetteOnly,
+ };
+
+ // This is nn::irsensor::IrSensorFunctionLevel
+ enum IrSensorFunctionLevel : u8 {
+ unknown0,
+ unknown1,
+ unknown2,
+ unknown3,
+ unknown4,
+ };
+
+ // This is nn::irsensor::IrCameraHandle
+ struct IrCameraHandle {
+ u8 npad_id{};
+ Core::HID::NpadStyleIndex npad_type{Core::HID::NpadStyleIndex::None};
+ INSERT_PADDING_BYTES(2);
+ };
+ static_assert(sizeof(IrCameraHandle) == 4, "IrCameraHandle is an invalid size");
+
+ struct IrsRect {
+ s16 x;
+ s16 y;
+ s16 width;
+ s16 height;
+ };
+
+ // This is nn::irsensor::PackedMcuVersion
+ struct PackedMcuVersion {
+ u16 major;
+ u16 minor;
+ };
+ static_assert(sizeof(PackedMcuVersion) == 4, "PackedMcuVersion is an invalid size");
+
+ // This is nn::irsensor::MomentProcessorConfig
+ struct MomentProcessorConfig {
+ u64 exposire_time;
+ u8 light_target;
+ u8 gain;
+ u8 is_negative_used;
+ INSERT_PADDING_BYTES(7);
+ IrsRect window_of_interest;
+ u8 preprocess;
+ u8 preprocess_intensity_threshold;
+ INSERT_PADDING_BYTES(5);
+ };
+ static_assert(sizeof(MomentProcessorConfig) == 0x28,
+ "MomentProcessorConfig is an invalid size");
+
+ // This is nn::irsensor::PackedMomentProcessorConfig
+ struct PackedMomentProcessorConfig {
+ u64 exposire_time;
+ u8 light_target;
+ u8 gain;
+ u8 is_negative_used;
+ INSERT_PADDING_BYTES(5);
+ IrsRect window_of_interest;
+ PackedMcuVersion required_mcu_version;
+ u8 preprocess;
+ u8 preprocess_intensity_threshold;
+ INSERT_PADDING_BYTES(2);
+ };
+ static_assert(sizeof(PackedMomentProcessorConfig) == 0x20,
+ "PackedMomentProcessorConfig is an invalid size");
+
+ // This is nn::irsensor::ClusteringProcessorConfig
+ struct ClusteringProcessorConfig {
+ u64 exposire_time;
+ u32 light_target;
+ u32 gain;
+ u8 is_negative_used;
+ INSERT_PADDING_BYTES(7);
+ IrsRect window_of_interest;
+ u32 pixel_count_min;
+ u32 pixel_count_max;
+ u32 object_intensity_min;
+ u8 is_external_light_filter_enabled;
+ INSERT_PADDING_BYTES(3);
+ };
+ static_assert(sizeof(ClusteringProcessorConfig) == 0x30,
+ "ClusteringProcessorConfig is an invalid size");
+
+ // This is nn::irsensor::PackedClusteringProcessorConfig
+ struct PackedClusteringProcessorConfig {
+ u64 exposire_time;
+ u8 light_target;
+ u8 gain;
+ u8 is_negative_used;
+ INSERT_PADDING_BYTES(5);
+ IrsRect window_of_interest;
+ PackedMcuVersion required_mcu_version;
+ u32 pixel_count_min;
+ u32 pixel_count_max;
+ u32 object_intensity_min;
+ u8 is_external_light_filter_enabled;
+ INSERT_PADDING_BYTES(2);
+ };
+ static_assert(sizeof(PackedClusteringProcessorConfig) == 0x30,
+ "PackedClusteringProcessorConfig is an invalid size");
+
+ // This is nn::irsensor::PackedImageTransferProcessorConfig
+ struct PackedImageTransferProcessorConfig {
+ u64 exposire_time;
+ u8 light_target;
+ u8 gain;
+ u8 is_negative_used;
+ INSERT_PADDING_BYTES(5);
+ PackedMcuVersion required_mcu_version;
+ u8 format;
+ INSERT_PADDING_BYTES(3);
+ };
+ static_assert(sizeof(PackedImageTransferProcessorConfig) == 0x18,
+ "PackedImageTransferProcessorConfig is an invalid size");
+
+ // This is nn::irsensor::PackedTeraPluginProcessorConfig
+ struct PackedTeraPluginProcessorConfig {
+ PackedMcuVersion required_mcu_version;
+ u8 mode;
+ INSERT_PADDING_BYTES(3);
+ };
+ static_assert(sizeof(PackedTeraPluginProcessorConfig) == 0x8,
+ "PackedTeraPluginProcessorConfig is an invalid size");
+
+ // This is nn::irsensor::PackedPointingProcessorConfig
+ struct PackedPointingProcessorConfig {
+ IrsRect window_of_interest;
+ PackedMcuVersion required_mcu_version;
+ };
+ static_assert(sizeof(PackedPointingProcessorConfig) == 0xC,
+ "PackedPointingProcessorConfig is an invalid size");
+
+ // This is nn::irsensor::PackedFunctionLevel
+ struct PackedFunctionLevel {
+ IrSensorFunctionLevel function_level;
+ INSERT_PADDING_BYTES(3);
+ };
+ static_assert(sizeof(PackedFunctionLevel) == 0x4, "PackedFunctionLevel is an invalid size");
+
+ // This is nn::irsensor::PackedImageTransferProcessorExConfig
+ struct PackedImageTransferProcessorExConfig {
+ u64 exposire_time;
+ u8 light_target;
+ u8 gain;
+ u8 is_negative_used;
+ INSERT_PADDING_BYTES(5);
+ PackedMcuVersion required_mcu_version;
+ ImageTransferProcessorFormat origin_format;
+ ImageTransferProcessorFormat trimming_format;
+ u16 trimming_start_x;
+ u16 trimming_start_y;
+ u8 is_external_light_filter_enabled;
+ INSERT_PADDING_BYTES(3);
+ };
+ static_assert(sizeof(PackedImageTransferProcessorExConfig) == 0x20,
+ "PackedImageTransferProcessorExConfig is an invalid size");
+
+ // This is nn::irsensor::PackedIrLedProcessorConfig
+ struct PackedIrLedProcessorConfig {
+ PackedMcuVersion required_mcu_version;
+ u8 light_target;
+ INSERT_PADDING_BYTES(3);
+ };
+ static_assert(sizeof(PackedIrLedProcessorConfig) == 0x8,
+ "PackedIrLedProcessorConfig is an invalid size");
+
void ActivateIrsensor(Kernel::HLERequestContext& ctx);
void DeactivateIrsensor(Kernel::HLERequestContext& ctx);
void GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx);
@@ -35,8 +265,6 @@ private:
void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
-
- const u32 device_handle{0xABCD};
};
class IRS_SYS final : public ServiceFramework<IRS_SYS> {
diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp
index 19bd85b6c..4ed3f02e2 100644
--- a/src/core/hle/service/jit/jit_context.cpp
+++ b/src/core/hle/service/jit/jit_context.cpp
@@ -11,10 +11,13 @@
#include "common/alignment.h"
#include "common/common_funcs.h"
#include "common/div_ceil.h"
+#include "common/elf.h"
#include "common/logging/log.h"
#include "core/hle/service/jit/jit_context.h"
#include "core/memory.h"
+using namespace Common::ELF;
+
namespace Service::JIT {
constexpr std::array<u8, 8> SVC0_ARM64 = {
@@ -26,25 +29,6 @@ constexpr std::array HELPER_FUNCTIONS{
"_stop", "_resolve", "_panic", "memcpy", "memmove", "memset",
};
-struct Elf64_Dyn {
- u64 d_tag;
- u64 d_un;
-};
-
-struct Elf64_Rela {
- u64 r_offset;
- u64 r_info;
- s64 r_addend;
-};
-
-static constexpr u32 Elf64_RelaType(const Elf64_Rela* rela) {
- return static_cast<u32>(rela->r_info);
-}
-
-constexpr int DT_RELA = 7; /* Address of Rela relocs */
-constexpr int DT_RELASZ = 8; /* Total size of Rela relocs */
-constexpr int R_AARCH64_RELATIVE = 1027; /* Adjust by program base. */
-
constexpr size_t STACK_ALIGN = 16;
class JITContextImpl;
@@ -206,17 +190,17 @@ public:
if (!dyn.d_tag) {
break;
}
- if (dyn.d_tag == DT_RELA) {
- rela_dyn = dyn.d_un;
+ if (dyn.d_tag == ElfDtRela) {
+ rela_dyn = dyn.d_un.d_ptr;
}
- if (dyn.d_tag == DT_RELASZ) {
- num_rela = dyn.d_un / sizeof(Elf64_Rela);
+ if (dyn.d_tag == ElfDtRelasz) {
+ num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela);
}
}
for (size_t i = 0; i < num_rela; i++) {
const auto rela{callbacks->ReadMemory<Elf64_Rela>(rela_dyn + i * sizeof(Elf64_Rela))};
- if (Elf64_RelaType(&rela) != R_AARCH64_RELATIVE) {
+ if (Elf64RelType(rela.r_info) != ElfAArch64Relative) {
continue;
}
const VAddr contents{callbacks->MemoryRead64(rela.r_offset)};
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp
index 449a5ac96..eeec34436 100644
--- a/src/core/hle/service/time/time_zone_manager.cpp
+++ b/src/core/hle/service/time/time_zone_manager.cpp
@@ -110,10 +110,9 @@ static constexpr s64 GetLeapDaysFromYear(s64 year) {
}
}
-static constexpr int GetMonthLength(bool is_leap_year, int month) {
- constexpr std::array<int, 12> month_lengths{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- constexpr std::array<int, 12> month_lengths_leap{31, 29, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31};
+static constexpr s8 GetMonthLength(bool is_leap_year, int month) {
+ constexpr std::array<s8, 12> month_lengths{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ constexpr std::array<s8, 12> month_lengths_leap{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
return is_leap_year ? month_lengths_leap[month] : month_lengths[month];
}