diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index 7e640a030..e3f600ed1 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -42,8 +42,8 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + + const auto& npad = GetResourceManager()->GetNpad(); + const auto result = npad->SetSupportedNpadStyleSet(applet_resource_user_id, NpadStyleSet::All); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidSystemServer::GetNpadCaptureButtonAssignment(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + + const auto size = ctx.GetWriteBufferNumElements(); + std::vector button_assignment(size); + const auto& npad = GetResourceManager()->GetNpad(); + const auto reply_size = + npad->GetNpadCaptureButtonAssignment(applet_resource_user_id, button_assignment); + + ctx.WriteBuffer(button_assignment); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(reply_size); } std::shared_ptr IHidSystemServer::GetResourceManager() { diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h index 429cba5ac..2bd18e979 100644 --- a/src/core/hle/service/hid/hid_system_server.h +++ b/src/core/hle/service/hid/hid_system_server.h @@ -22,6 +22,9 @@ private: void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx); void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx); void ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx); + void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx); + void SetSupportedNpadStyleSetAll(HLERequestContext& ctx); + void GetNpadCaptureButtonAssignment(HLERequestContext& ctx); std::shared_ptr GetResourceManager(); diff --git a/src/core/hle/service/hid/hid_types.h b/src/core/hle/service/hid/hid_types.h index d62186d92..491784be2 100644 --- a/src/core/hle/service/hid/hid_types.h +++ b/src/core/hle/service/hid/hid_types.h @@ -220,7 +220,15 @@ enum class NpadIdType : u32 { Invalid = 0xFFFFFFFF, }; -// This is nn::hid::NpadStyleIndex +enum class MaskIndex : u32 { + Normal = 0, + GC = 1, + Extended = 2, + Full = 3, +}; +static_assert(sizeof(MaskIndex) == 4, "MaskIndex is an invalid size"); + + // This is nn::hid::NpadStyleIndex enum class NpadStyleIndex : u8 { None = 0, FullKey = 3, @@ -260,8 +268,10 @@ enum class NpadStyleSet : u32 { All = 0xFFFFFFFFU, }; +DECLARE_ENUM_FLAG_OPERATORS(NpadStyleSet); static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); + // This is nn::hid::VibrationDevicePosition enum class VibrationDevicePosition : u32 { None = 0, diff --git a/src/core/hle/service/hid/resource_manager/npad.cpp b/src/core/hle/service/hid/resource_manager/npad.cpp index 05123dd73..ebc7a014e 100644 --- a/src/core/hle/service/hid/resource_manager/npad.cpp +++ b/src/core/hle/service/hid/resource_manager/npad.cpp @@ -141,10 +141,30 @@ void NpadState::SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled) { data.status.use_center_clamp.Assign(is_enabled); } -void NpadState::SetCaptureButtonAssignment(std::size_t index, NpadButton npad_button_set) { +void NpadState::SetCaptureButtonAssignment(const std::size_t index, + const NpadButton npad_button_set) { data.npad_button_assignment[index] = npad_button_set; } +std::size_t NpadState::GetCaptureButtonAssignment( + std::span out_button_assignment) const { + if (out_button_assignment.size() < 1) { + return 0; + } + + std::size_t out_size{}; + for (std::size_t index = 0; index < 6 && out_size < out_button_assignment.size(); ++index) { + const bool is_defined = + (data.supported_npad_style_set & GetStylesetByIndex(index)) != NpadStyleSet::None; + if (is_defined && data.npad_button_assignment[index] != NpadButton::None) { + out_button_assignment[out_size] = data.npad_button_assignment[index]; + out_size++; + } + } + + return out_size; +} + void NpadState::ClearNpadSystemCommonPolicy() { data.status.raw = 0; data.supported_npad_style_set = NpadStyleSet::All; @@ -190,7 +210,8 @@ void NpadState::ClearNpadSystemCommonPolicy() { } void NpadState::ApplyNpadSystemCommonPolicy(const bool is_full_policy) { - data.supported_npad_style_set = NpadStyleSet::All; + data.supported_npad_style_set = NpadStyleSet::Fullkey | NpadStyleSet::JoyDual | + NpadStyleSet::SystemExt | NpadStyleSet::System; data.handheld_activation_mode = static_cast(NpadHandheldActivationMode::Dual); data.status.is_supported_style_set.Assign(1); @@ -233,6 +254,10 @@ void NpadState::SetAssigningSingleOnSlSrPress(const bool is_enabled) { data.status.assigning_single_on_sl_sr_press.Assign(is_enabled); } +MaskIndex NpadState::GetMaskIndex() const { + return mask_index; +} + Npad::Npad(KernelHelpers::ServiceContext& context) : service_context{context} { for (auto& npad : npad_state) { npad = std::make_shared(); @@ -743,6 +768,18 @@ Result Npad::ClearNpadCaptureButtonAssignment(const u64 aruid) { return ResultSuccess; } +std::size_t Npad::GetNpadCaptureButtonAssignment( + const u64 aruid, std::span out_button_assignment) const { + std::scoped_lock lock{mutex}; + const auto index = GetIndexFromAruid(aruid); + + if (index >= ARUID_MAX) { + return 0; + } + + return npad_state[index]->GetCaptureButtonAssignment(out_button_assignment); +} + Result Npad::AcquireNpadStyleSetUpdateEventHandle(const u64 aruid, Kernel::KReadableEvent** out_event, const NpadIdType npad_id) { @@ -899,7 +936,9 @@ Result Npad::GetMaskedSupportedNpadStyleSet(const u64 aruid, Result Npad::GetMaskedSupportedNpadStyleSetImpl(const u64 aruid, NpadStyleSet& out_npad_styleset) const { if (aruid == 0) { - out_npad_styleset = static_cast(0x6000005f); + out_npad_styleset = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual | + NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::Palma | + NpadStyleSet::SystemExt | NpadStyleSet::System; return ResultSuccess; } @@ -913,20 +952,34 @@ Result Npad::GetMaskedSupportedNpadStyleSetImpl(const u64 aruid, return ResultUndefinedStyleSet; } - NpadStyleTag mask{0x6000001f}; + NpadStyleTag mask = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual | + NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::SystemExt | + NpadStyleSet::System; out_npad_styleset = npad_state[index]->GetSupportedNpadStyleSet(); if (index < ARUID_MAX) { switch (npad_state[index]->GetMaskIndex()) { - case 1: - mask = static_cast(0x6000003f); + case MaskIndex::GC: + mask = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual | + NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::Gc | + NpadStyleSet::SystemExt | NpadStyleSet::System; break; - case 2: - mask = static_cast(0x600001bf); + case MaskIndex::Extended: + mask = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual | + NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::Gc | + NpadStyleSet::Palma | NpadStyleSet::Lark | NpadStyleSet::SystemExt | + NpadStyleSet::System; break; - case 3: - mask = static_cast(0x60000fbf); + case MaskIndex::Full: + mask = NpadStyleSet::Fullkey | NpadStyleSet::Handheld | NpadStyleSet::JoyDual | + NpadStyleSet::JoyLeft | NpadStyleSet::JoyRight | NpadStyleSet::Gc | + NpadStyleSet::Palma | NpadStyleSet::Lark | NpadStyleSet::HandheldLark | + NpadStyleSet::Lucia | NpadStyleSet::Lagoon | NpadStyleSet::Lager | + NpadStyleSet::SystemExt | NpadStyleSet::System; break; + default: + out_npad_styleset = out_npad_styleset & mask.raw; + return ResultSuccess; } mask.palma.Assign(1); } diff --git a/src/core/hle/service/hid/resource_manager/npad.h b/src/core/hle/service/hid/resource_manager/npad.h index 2bd09fea2..52fd3ffa2 100644 --- a/src/core/hle/service/hid/resource_manager/npad.h +++ b/src/core/hle/service/hid/resource_manager/npad.h @@ -26,6 +26,7 @@ enum class NpadJoyDeviceType : s64; enum class NpadStyleSet : u32; enum class NpadJoyHoldType : u64; enum class NpadButton : u64; +enum class MaskIndex : u32; struct SixAxisSensorHandle; } // namespace Service::HID @@ -99,7 +100,8 @@ public: bool IsUnintendedHomeButtonInputProtectionEnabled(const NpadIdType npad_id) const; void SetNpadAnalogStickUseCenterClampImpl(const bool is_enabled); - void SetCaptureButtonAssignment(std::size_t index, NpadButton npad_button_set); + void SetCaptureButtonAssignment(const std::size_t index, const NpadButton npad_button_set); + std::size_t GetCaptureButtonAssignment(std::span out_button_assignment) const; void ClearNpadSystemCommonPolicy(); void ApplyNpadSystemCommonPolicy(const bool is_full_policy); @@ -107,6 +109,8 @@ public: bool GetAssigningSingleOnSlSrPress() const; void SetAssigningSingleOnSlSrPress(const bool is_enabled); + MaskIndex GetMaskIndex() const; + private: struct DataStructure { NpadStatus status{}; @@ -125,6 +129,7 @@ private: DataStructure data{}; std::array, PLAYERS_MAX> state; + MaskIndex mask_index{}; }; class Npad final : public BaseResource { @@ -177,6 +182,7 @@ public: Result SetNpadCaptureButtonAssignment(const u64 aruid, const NpadStyleSet npad_styleset, const NpadButton npad_button_set); Result ClearNpadCaptureButtonAssignment(const u64 aruid); + std::size_t GetNpadCaptureButtonAssignment(const u64 aruid, std::span out_button_assignment) const; // Events Result AcquireNpadStyleSetUpdateEventHandle(const u64 aruid, Kernel::KReadableEvent** out_event, @@ -215,6 +221,8 @@ private: Result GetAssigningSingleOnSlSrPress(const u64 aruid, bool out_is_enabled) const; Result SetAssigningSingleOnSlSrPress(const u64 aruid, const bool is_enabled); + Result GetMaskedSupportedNpadStyleSetImpl(const u64 aruid, + NpadStyleSet& out_npad_styleset) const; // Update state void UpdateSupportedNpadIdType(); void UpdateSupportedStyleSet();