[video_core, hle] remove redundant parent references in system structs (#3908)

reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: maufeat <sahyno1996@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
lizzie 2026-06-23 06:31:25 +02:00 committed by crueter
parent f8facda35f
commit 3aa0d46259
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6
307 changed files with 4419 additions and 4477 deletions

View file

@ -29,21 +29,36 @@
namespace Service::HID {
NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
: hid_core{hid_core_}, service_context{service_context_}, npad_resource{service_context} {
: hid_core{hid_core_}
, service_context{service_context_}
, npad_resource{hid_core_.kernel, service_context}
, abstracted_pads{{
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
AbstractPad{hid_core_.kernel},
}}
{
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) {
for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
auto& controller = controller_data[aruid_index][i];
controller.device = hid_core.GetEmulatedControllerByIndex(i);
Core::HID::ControllerUpdateCallback engine_callback{
.on_change =
[this, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); },
.on_change = [this, i](Core::HID::ControllerTriggerType type) {
ControllerUpdate(hid_core.kernel, type, i);
},
.is_npad_service = true,
};
controller.callback_key = controller.device->SetCallback(engine_callback);
}
}
for (std::size_t i = 0; i < abstracted_pads.size(); ++i) {
abstracted_pads[i] = AbstractPad{};
abstracted_pads[i].SetNpadId(IndexToNpadIdType(i));
}
}
@ -123,10 +138,10 @@ void NPad::FreeAppletResourceId(u64 aruid) {
return npad_resource.FreeAppletResourceId(aruid);
}
void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) {
void NPad::ControllerUpdate(Kernel::KernelCore& kernel, Core::HID::ControllerTriggerType type, std::size_t controller_idx) {
if (type == Core::HID::ControllerTriggerType::All) {
ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
ControllerUpdate(kernel, Core::HID::ControllerTriggerType::Connected, controller_idx);
ControllerUpdate(kernel, Core::HID::ControllerTriggerType::Battery, controller_idx);
return;
}
@ -151,7 +166,7 @@ void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t c
if (is_connected == controller.is_connected) {
return;
}
UpdateControllerAt(data->aruid, npad_type, npad_id, is_connected);
UpdateControllerAt(kernel, data->aruid, npad_type, npad_id, is_connected);
break;
case Core::HID::ControllerTriggerType::Battery: {
if (!controller.device->IsConnected()) {
@ -173,7 +188,7 @@ void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t c
}
}
void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) {
void NPad::InitNewlyAddedController(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id) {
auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
if (!npad_resource.IsControllerSupported(aruid, controller.device->GetNpadStyleIndex())) {
return;
@ -188,7 +203,7 @@ void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) {
return;
}
if (controller_type == Core::HID::NpadStyleIndex::None) {
npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
npad_resource.SignalStyleSetUpdateEvent(kernel, aruid, npad_id);
return;
}
@ -372,7 +387,7 @@ void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) {
Common::Input::PollingMode::Active);
}
npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
npad_resource.SignalStyleSetUpdateEvent(kernel, aruid, npad_id);
WriteEmptyEntry(controller.shared_memory);
hid_core.SetLastActiveController(npad_id);
abstracted_pads[NpadIdTypeToIndex(npad_id)].Update();
@ -399,20 +414,20 @@ void NPad::WriteEmptyEntry(NpadInternalState* npad) {
npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
}
void NPad::RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id) {
void NPad::RequestPadStateUpdate(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id) {
std::scoped_lock lock{*applet_resource_holder.shared_mutex};
auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
const auto controller_type = controller.device->GetNpadStyleIndex();
if (!controller.device->IsConnected() && controller.is_connected) {
DisconnectNpad(aruid, npad_id);
DisconnectNpad(kernel, aruid, npad_id);
return;
}
if (!controller.device->IsConnected()) {
return;
}
if (controller.device->IsConnected() && !controller.is_connected) {
InitNewlyAddedController(aruid, npad_id);
InitNewlyAddedController(kernel, aruid, npad_id);
}
// This function is unique to yuzu for the turbo buttons and motion to work properly
@ -468,7 +483,7 @@ void NPad::RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id) {
}
}
void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
void NPad::OnUpdate(Kernel::KernelCore& kernel, const Core::Timing::CoreTiming& core_timing) {
if (ref_counter == 0) {
return;
}
@ -510,7 +525,7 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
continue;
}
RequestPadStateUpdate(aruid, controller.device->GetNpadIdType());
RequestPadStateUpdate(kernel, aruid, controller.device->GetNpadIdType());
auto& pad_state = controller.npad_pad_state;
auto& libnx_state = controller.npad_libnx_state;
auto& trigger_state = controller.npad_trigger_state;
@ -627,17 +642,17 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
}
}
Result NPad::SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set) {
Result NPad::SetSupportedNpadStyleSet(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleSet supported_style_set) {
std::scoped_lock lock{mutex};
hid_core.SetSupportedStyleTag({supported_style_set});
const Result result = npad_resource.SetSupportedNpadStyleSet(aruid, supported_style_set);
if (result.IsSuccess()) {
OnUpdate({});
OnUpdate(kernel, {});
}
return result;
}
Result NPad::GetSupportedNpadStyleSet(u64 aruid,
Result NPad::GetSupportedNpadStyleSet(Kernel::KernelCore& kernel, u64 aruid,
Core::HID::NpadStyleSet& out_supported_style_set) const {
std::scoped_lock lock{mutex};
const Result result = npad_resource.GetSupportedNpadStyleSet(out_supported_style_set, aruid);
@ -650,8 +665,7 @@ Result NPad::GetSupportedNpadStyleSet(u64 aruid,
return result;
}
Result NPad::GetMaskedSupportedNpadStyleSet(
u64 aruid, Core::HID::NpadStyleSet& out_supported_style_set) const {
Result NPad::GetMaskedSupportedNpadStyleSet(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleSet& out_supported_style_set) const {
std::scoped_lock lock{mutex};
const Result result =
npad_resource.GetMaskedSupportedNpadStyleSet(out_supported_style_set, aruid);
@ -664,8 +678,7 @@ Result NPad::GetMaskedSupportedNpadStyleSet(
return result;
}
Result NPad::SetSupportedNpadIdType(u64 aruid,
std::span<const Core::HID::NpadIdType> supported_npad_list) {
Result NPad::SetSupportedNpadIdType(Kernel::KernelCore& kernel, u64 aruid, std::span<const Core::HID::NpadIdType> supported_npad_list) {
std::scoped_lock lock{mutex};
if (supported_npad_list.size() > MaxSupportedNpadIdTypes) {
return ResultInvalidArraySize;
@ -674,7 +687,7 @@ Result NPad::SetSupportedNpadIdType(u64 aruid,
Result result = npad_resource.SetSupportedNpadIdType(aruid, supported_npad_list);
if (result.IsSuccess()) {
OnUpdate({});
OnUpdate(kernel, {});
}
return result;
@ -690,22 +703,21 @@ Result NPad::GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const
return npad_resource.GetNpadJoyHoldType(out_hold_type, aruid);
}
Result NPad::SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode) {
Result NPad::SetNpadHandheldActivationMode(Kernel::KernelCore& kernel, u64 aruid, NpadHandheldActivationMode mode) {
std::scoped_lock lock{mutex};
Result result = npad_resource.SetNpadHandheldActivationMode(aruid, mode);
if (result.IsSuccess()) {
OnUpdate({});
OnUpdate(kernel, {});
}
return result;
}
Result NPad::GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const {
Result NPad::GetNpadHandheldActivationMode(Kernel::KernelCore& kernel, u64 aruid, NpadHandheldActivationMode& out_mode) const {
std::scoped_lock lock{mutex};
return npad_resource.GetNpadHandheldActivationMode(out_mode, aruid);
}
bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) {
bool NPad::SetNpadMode(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType& new_npad_id, 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 false;
@ -727,17 +739,17 @@ bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID:
if (assignment_mode == NpadJoyAssignmentMode::Dual) {
if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) {
DisconnectNpad(aruid, npad_id);
DisconnectNpad(kernel, aruid, npad_id);
controller.is_dual_left_connected = true;
controller.is_dual_right_connected = false;
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
return false;
}
if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) {
DisconnectNpad(aruid, npad_id);
DisconnectNpad(kernel, aruid, npad_id);
controller.is_dual_left_connected = false;
controller.is_dual_right_connected = true;
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
return false;
}
return false;
@ -751,58 +763,55 @@ bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID:
}
if (controller.is_dual_left_connected && !controller.is_dual_right_connected) {
DisconnectNpad(aruid, npad_id);
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
DisconnectNpad(kernel, aruid, npad_id);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
return false;
}
if (!controller.is_dual_left_connected && controller.is_dual_right_connected) {
DisconnectNpad(aruid, npad_id);
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
DisconnectNpad(kernel, aruid, npad_id);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
return false;
}
// We have two controllers connected to the same npad_id we need to split them
new_npad_id = hid_core.GetFirstDisconnectedNpadId();
auto& controller_2 = GetControllerFromNpadIdType(aruid, new_npad_id);
DisconnectNpad(aruid, npad_id);
DisconnectNpad(kernel, aruid, npad_id);
if (npad_device_type == NpadJoyDeviceType::Left) {
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
controller_2.is_dual_left_connected = false;
controller_2.is_dual_right_connected = true;
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
} else {
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
controller_2.is_dual_left_connected = true;
controller_2.is_dual_right_connected = false;
UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
UpdateControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
}
return true;
}
Result NPad::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
Core::HID::NpadIdType npad_id) {
Result NPad::AcquireNpadStyleSetUpdateEventHandle(Kernel::KernelCore& kernel, u64 aruid, Kernel::KReadableEvent** out_event, Core::HID::NpadIdType npad_id) {
std::scoped_lock lock{mutex};
return npad_resource.AcquireNpadStyleSetUpdateEventHandle(aruid, out_event, npad_id);
return npad_resource.AcquireNpadStyleSetUpdateEventHandle(kernel, aruid, out_event, npad_id);
}
void NPad::AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
Core::HID::NpadIdType npad_id) {
UpdateControllerAt(aruid, controller, npad_id, true);
void NPad::AddNewControllerAt(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id) {
UpdateControllerAt(kernel, aruid, controller, npad_id, true);
}
void NPad::UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex type,
Core::HID::NpadIdType npad_id, bool connected) {
void NPad::UpdateControllerAt(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleIndex type, Core::HID::NpadIdType npad_id, bool connected) {
auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
if (!connected) {
DisconnectNpad(aruid, npad_id);
DisconnectNpad(kernel, aruid, npad_id);
return;
}
controller.device->SetNpadStyleIndex(type);
InitNewlyAddedController(aruid, npad_id);
InitNewlyAddedController(kernel, aruid, npad_id);
}
Result NPad::DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id) {
Result NPad::DisconnectNpad(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return ResultInvalidNpadId;
@ -845,7 +854,7 @@ Result NPad::DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id) {
controller.is_dual_right_connected = true;
controller.is_connected = false;
controller.device->Disconnect();
npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
npad_resource.SignalStyleSetUpdateEvent(kernel, aruid, npad_id);
WriteEmptyEntry(shared_memory);
return ResultSuccess;
}
@ -878,8 +887,7 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
return ResultSuccess;
}
Result NPad::MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
Result NPad::MergeSingleJoyAsDualJoy(Kernel::KernelCore& kernel, u64 aruid, 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);
@ -933,11 +941,11 @@ Result NPad::MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1,
}
// Disconnect the joycons and connect them as dual joycon at the first index.
DisconnectNpad(aruid, npad_id_1);
DisconnectNpad(aruid, npad_id_2);
DisconnectNpad(kernel, aruid, npad_id_1);
DisconnectNpad(kernel, aruid, npad_id_2);
controller_1.is_dual_left_connected = true;
controller_1.is_dual_right_connected = true;
AddNewControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
AddNewControllerAt(kernel, aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
return ResultSuccess;
}
@ -961,11 +969,9 @@ Result NPad::StopLrAssignmentMode(u64 aruid) {
return result;
}
Result NPad::SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
Result NPad::SwapNpadAssignment(Kernel::KernelCore& kernel, u64 aruid, 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);
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, npad_id_2);
return ResultInvalidNpadId;
}
if (npad_id_1 == Core::HID::NpadIdType::Handheld ||
@ -987,20 +993,17 @@ Result NPad::SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
return ResultNpadNotConnected;
}
UpdateControllerAt(aruid, type_index_2, npad_id_1, is_connected_2);
UpdateControllerAt(aruid, type_index_1, npad_id_2, is_connected_1);
UpdateControllerAt(kernel, aruid, type_index_2, npad_id_1, is_connected_2);
UpdateControllerAt(kernel, aruid, type_index_1, npad_id_2, is_connected_1);
return ResultSuccess;
}
Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
Core::HID::NpadIdType npad_id) const {
Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid, Core::HID::NpadIdType npad_id) const {
std::scoped_lock lock{mutex};
return npad_resource.GetHomeProtectionEnabled(out_is_enabled, aruid, npad_id);
}
Result NPad::EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,
bool is_enabled) {
Result NPad::EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id, bool is_enabled) {
std::scoped_lock lock{mutex};
return npad_resource.SetHomeProtectionEnabled(aruid, npad_id, is_enabled);
}
@ -1054,29 +1057,29 @@ Core::HID::NpadButton NPad::GetAndResetPressState() {
return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
}
Result NPad::ApplyNpadSystemCommonPolicy(u64 aruid) {
Result NPad::ApplyNpadSystemCommonPolicy(Kernel::KernelCore& kernel, u64 aruid) {
std::scoped_lock lock{mutex};
const Result result = npad_resource.ApplyNpadSystemCommonPolicy(aruid, false);
if (result.IsSuccess()) {
OnUpdate({});
OnUpdate(kernel, {});
}
return result;
}
Result NPad::ApplyNpadSystemCommonPolicyFull(u64 aruid) {
Result NPad::ApplyNpadSystemCommonPolicyFull(Kernel::KernelCore& kernel, u64 aruid) {
std::scoped_lock lock{mutex};
const Result result = npad_resource.ApplyNpadSystemCommonPolicy(aruid, true);
if (result.IsSuccess()) {
OnUpdate({});
OnUpdate(kernel, {});
}
return result;
}
Result NPad::ClearNpadSystemCommonPolicy(u64 aruid) {
Result NPad::ClearNpadSystemCommonPolicy(Kernel::KernelCore& kernel, u64 aruid) {
std::scoped_lock lock{mutex};
const Result result = npad_resource.ClearNpadSystemCommonPolicy(aruid);
if (result.IsSuccess()) {
OnUpdate({});
OnUpdate(kernel, {});
}
return result;
}

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -61,37 +64,31 @@ public:
void FreeAppletResourceId(u64 aruid);
// When the controller is requesting an update for the shared memory
void OnUpdate(const Core::Timing::CoreTiming& core_timing);
void OnUpdate(Kernel::KernelCore& kernel, const Core::Timing::CoreTiming& core_timing);
Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set);
Result GetSupportedNpadStyleSet(u64 aruid,
Core::HID::NpadStyleSet& out_supported_style_set) const;
Result GetMaskedSupportedNpadStyleSet(u64 aruid,
Core::HID::NpadStyleSet& out_supported_style_set) const;
Result SetSupportedNpadIdType(u64 aruid,
std::span<const Core::HID::NpadIdType> supported_npad_list);
Result SetSupportedNpadStyleSet(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleSet supported_style_set);
Result GetSupportedNpadStyleSet(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleSet& out_supported_style_set) const;
Result GetMaskedSupportedNpadStyleSet(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleSet& out_supported_style_set) const;
Result SetSupportedNpadIdType(Kernel::KernelCore& kernel, u64 aruid, std::span<const Core::HID::NpadIdType> supported_npad_list);
Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type);
Result GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const;
Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode);
Result GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const;
Result SetNpadHandheldActivationMode(Kernel::KernelCore& kernel, u64 aruid, NpadHandheldActivationMode mode);
Result GetNpadHandheldActivationMode(Kernel::KernelCore& kernel, u64 aruid, NpadHandheldActivationMode& out_mode) const;
bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
bool SetNpadMode(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
Result AcquireNpadStyleSetUpdateEventHandle(Kernel::KernelCore& kernel, u64 aruid, Kernel::KReadableEvent** out_event,
Core::HID::NpadIdType npad_id);
// Adds a new controller at an index.
void AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
Core::HID::NpadIdType npad_id);
void AddNewControllerAt(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id);
// Adds a new controller at an index with connection status.
void UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
Core::HID::NpadIdType npad_id, bool connected);
void UpdateControllerAt(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id, bool connected);
Result DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id);
Result DisconnectNpad(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id);
Result IsFirmwareUpdateAvailableForSixAxisSensor(
u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle,
@ -110,20 +107,18 @@ public:
void ConnectAllDisconnectedControllers();
void ClearAllControllers();
Result MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2);
Result MergeSingleJoyAsDualJoy(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
Result StartLrAssignmentMode(u64 aruid);
Result StopLrAssignmentMode(u64 aruid);
Result SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2);
Result SwapNpadAssignment(Kernel::KernelCore& kernel, u64 aruid, 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();
Result ApplyNpadSystemCommonPolicy(u64 aruid);
Result ApplyNpadSystemCommonPolicyFull(u64 aruid);
Result ClearNpadSystemCommonPolicy(u64 aruid);
Result ApplyNpadSystemCommonPolicy(Kernel::KernelCore& kernel, u64 aruid);
Result ApplyNpadSystemCommonPolicyFull(Kernel::KernelCore& kernel, u64 aruid);
Result ClearNpadSystemCommonPolicy(Kernel::KernelCore& kernel, u64 aruid);
void SetRevision(u64 aruid, NpadRevision revision);
NpadRevision GetRevision(u64 aruid);
@ -180,9 +175,9 @@ private:
int callback_key{};
};
void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
void InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id);
void RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id);
void ControllerUpdate(Kernel::KernelCore& kernel, Core::HID::ControllerTriggerType type, std::size_t controller_idx);
void InitNewlyAddedController(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id);
void RequestPadStateUpdate(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id);
void WriteEmptyEntry(NpadInternalState* npad);
NpadControllerData& GetControllerFromHandle(
@ -209,7 +204,6 @@ private:
NpadVibration vibration_handler{};
std::atomic<u64> press_state{};
std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax>
controller_data{};
std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax> controller_data{};
};
} // namespace Service::HID

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@ -13,7 +13,9 @@
namespace Service::HID {
NPadResource::NPadResource(KernelHelpers::ServiceContext& context) : service_context{context} {}
NPadResource::NPadResource(Kernel::KernelCore& kernel_, KernelHelpers::ServiceContext& context)
: service_context{context}
{}
NPadResource::~NPadResource() = default;
@ -505,9 +507,7 @@ Result NPadResource::IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 a
return ResultSuccess;
}
Result NPadResource::AcquireNpadStyleSetUpdateEventHandle(u64 aruid,
Kernel::KReadableEvent** out_event,
Core::HID::NpadIdType npad_id) {
Result NPadResource::AcquireNpadStyleSetUpdateEventHandle(Kernel::KernelCore& kernel, u64 aruid, Kernel::KReadableEvent** out_event, Core::HID::NpadIdType npad_id) {
const u64 aruid_index = GetIndexFromAruid(aruid);
if (aruid_index >= AruidIndexMax) {
return ResultNpadNotConnected;
@ -526,26 +526,25 @@ Result NPadResource::AcquireNpadStyleSetUpdateEventHandle(u64 aruid,
*out_event = &controller_state.style_set_update_event->GetReadableEvent();
if (controller_state.is_styleset_update_event_initialized) {
controller_state.style_set_update_event->Signal();
controller_state.style_set_update_event->Signal(kernel);
}
return ResultSuccess;
}
Result NPadResource::SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id) {
Result NPadResource::SignalStyleSetUpdateEvent(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id) {
const u64 aruid_index = GetIndexFromAruid(aruid);
if (aruid_index >= AruidIndexMax) {
return ResultNpadNotConnected;
}
auto controller = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)];
if (controller.is_styleset_update_event_initialized) {
controller.style_set_update_event->Signal();
auto& controller_state = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)];
if (controller_state.is_styleset_update_event_initialized) {
controller_state.style_set_update_event->Signal(kernel);
}
return ResultSuccess;
}
Result NPadResource::GetHomeProtectionEnabled(bool& is_enabled, u64 aruid,
Core::HID::NpadIdType npad_id) const {
Result NPadResource::GetHomeProtectionEnabled(bool& is_enabled, u64 aruid, Core::HID::NpadIdType npad_id) const {
const u64 aruid_index = GetIndexFromAruid(aruid);
if (aruid_index >= AruidIndexMax) {
return ResultNpadNotConnected;
@ -555,8 +554,7 @@ Result NPadResource::GetHomeProtectionEnabled(bool& is_enabled, u64 aruid,
return ResultSuccess;
}
Result NPadResource::SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id,
bool is_enabled) {
Result NPadResource::SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id, bool is_enabled) {
const u64 aruid_index = GetIndexFromAruid(aruid);
if (aruid_index >= AruidIndexMax) {
return ResultNpadNotConnected;

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -20,6 +23,7 @@ class System;
}
namespace Kernel {
class KernelCore;
class KReadableEvent;
}
@ -37,8 +41,7 @@ struct NpadState {
DataStatusFlag flag{};
u64 aruid{};
NPadData data{};
std::array<std::array<Core::HID::NpadButton, StyleIndexCount>, MaxSupportedNpadIdTypes>
button_config;
std::array<std::array<Core::HID::NpadButton, StyleIndexCount>, MaxSupportedNpadIdTypes> button_config;
std::array<NpadControllerState, MaxSupportedNpadIdTypes> controller_state;
NpadRevision npad_revision;
};
@ -46,7 +49,7 @@ struct NpadState {
/// Handles Npad request from HID interfaces
class NPadResource final {
public:
explicit NPadResource(KernelHelpers::ServiceContext& context);
explicit NPadResource(Kernel::KernelCore& kernel, KernelHelpers::ServiceContext& context);
~NPadResource();
NPadData* GetActiveData();
@ -81,11 +84,9 @@ public:
Result GetNpadJoyHoldType(NpadJoyHoldType& hold_type, u64 aruid) const;
Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode activation_mode);
Result GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode,
u64 aruid) const;
Result GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode, u64 aruid) const;
Result SetSupportedNpadIdType(u64 aruid,
std::span<const Core::HID::NpadIdType> supported_npad_list);
Result SetSupportedNpadIdType(u64 aruid, std::span<const Core::HID::NpadIdType> supported_npad_list);
bool IsControllerSupported(u64 aruid, Core::HID::NpadStyleIndex style_index) const;
Result SetLrAssignmentMode(u64 aruid, bool is_enabled);
@ -94,28 +95,20 @@ public:
Result SetAssigningSingleOnSlSrPress(u64 aruid, bool is_enabled);
Result IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 aruid) const;
Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
Core::HID::NpadIdType npad_id);
Result SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id);
Result GetHomeProtectionEnabled(bool& is_enabled, u64 aruid,
Core::HID::NpadIdType npad_id) const;
Result AcquireNpadStyleSetUpdateEventHandle(Kernel::KernelCore& kernel, u64 aruid, Kernel::KReadableEvent** out_event, Core::HID::NpadIdType npad_id);
Result SignalStyleSetUpdateEvent(Kernel::KernelCore& kernel, u64 aruid, Core::HID::NpadIdType npad_id);
Result GetHomeProtectionEnabled(bool& is_enabled, u64 aruid, Core::HID::NpadIdType npad_id) const;
Result SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id, bool is_enabled);
Result SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled);
Result SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index,
Core::HID::NpadButton button_config);
Core::HID::NpadButton GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id,
std::size_t index, Core::HID::NpadButton mask,
bool is_enabled);
Result SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index, Core::HID::NpadButton button_config);
Core::HID::NpadButton GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index, Core::HID::NpadButton mask, bool is_enabled);
void ResetButtonConfig();
Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set,
Core::HID::NpadButton button_assignment);
Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set, Core::HID::NpadButton button_assignment);
Result ClearNpadCaptureButtonAssignment(u64 aruid);
std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
u64 aruid) const;
std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list, u64 aruid) const;
Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled);
@ -124,9 +117,8 @@ private:
AruidRegisterList registration_list{};
std::array<NpadState, AruidIndexMax> state{};
u64 active_data_aruid{};
KernelHelpers::ServiceContext& service_context;
NpadJoyHoldType default_hold_type{};
s32 ref_counter{};
KernelHelpers::ServiceContext& service_context;
};
} // namespace Service::HID