From 600a02fe29beef121be1e3b9b2b70122f294b581 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Sun, 20 Aug 2023 14:32:09 -0600 Subject: [PATCH] enough palma trees --- src/core/hle/service/hid/hid_result.h | 9 + src/core/hle/service/hid/hid_server.cpp | 4 +- .../resource_manager/npad_resource/npad.cpp | 13 +- .../hid/resource_manager/npad_resource/npad.h | 9 +- .../service/hid/resource_manager/palma.cpp | 666 +++++++++++++++++- .../hle/service/hid/resource_manager/palma.h | 55 +- 6 files changed, 736 insertions(+), 20 deletions(-) diff --git a/src/core/hle/service/hid/hid_result.h b/src/core/hle/service/hid/hid_result.h index 3b322ecda..4b68faaa9 100644 --- a/src/core/hle/service/hid/hid_result.h +++ b/src/core/hle/service/hid/hid_result.h @@ -27,6 +27,15 @@ constexpr Result ResultInvalidStyleSet{ErrorModule::HID, 717}; constexpr Result ResultUnknown108{ErrorModule::HID, 108}; +constexpr Result ResultInvalidPalmaNpadId{ErrorModule::HID, 3301}; constexpr Result ResultInvalidPalmaHandle{ErrorModule::HID, 3302}; +constexpr Result ResultOperationFailed{ErrorModule::HID, 3304}; } // namespace Service::HID + +namespace Service::XCD { + +constexpr Result ResultUnknown1{ErrorModule::XCD, 1}; +constexpr Result ResultUnknown365{ErrorModule::XCD, 365}; + +} // namespace Service::XCD diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index bbb4cb20a..1b534cfc9 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -2151,8 +2151,8 @@ void IHidServer::GetPalmaConnectionHandle(HLERequestContext& ctx) { parameters.npad_id, parameters.applet_resource_user_id); PalmaConnectionHandle handle{}; - const Result result = GetResourceManager()->GetPalma()->GetPalmaConnectionHandle( - handle, parameters.applet_resource_user_id); + const Result result = + GetResourceManager()->GetPalma()->GetPalmaConnectionHandle(handle, parameters.npad_id); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(result); diff --git a/src/core/hle/service/hid/resource_manager/npad_resource/npad.cpp b/src/core/hle/service/hid/resource_manager/npad_resource/npad.cpp index ed0e9246e..45dd11231 100644 --- a/src/core/hle/service/hid/resource_manager/npad_resource/npad.cpp +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad.cpp @@ -5,10 +5,12 @@ #include "core/hle/service/hid/hid_result.h" #include "core/hle/service/hid/hid_types.h" #include "core/hle/service/hid/hid_util.h" +#include "core/hle/service/hid/resource_manager.h" #include "core/hle/service/hid/resource_manager/npad_resource/npad.h" #include "core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.h" #include "core/hle/service/hid/resource_manager/npad_resource/npad_shared_types.h" #include "core/hle/service/hid/resource_manager/npad_resource/npad_state.h" +#include "core/hle/service/hid/resource_manager/palma.h" namespace Service::HID { @@ -76,7 +78,8 @@ void AbstractNpadState::UpdateBatteryLifoImpl(const BatteryState& battery_state, internal_state.battery_level_right = battery_state.battery_level_right; } -Npad::Npad(KernelHelpers::ServiceContext& context) : service_context{context} { +Npad::Npad(KernelHelpers::ServiceContext& context, std::shared_ptr resource) + : service_context{context}, resource_manager{resource} { for (auto& npad : npad_state) { npad = std::make_shared(); } @@ -206,7 +209,7 @@ Result Npad::SetSupportedNpadStyleSet(const u64 aruid, const NpadStyleSet suppor if (result.IsSuccess()) { UpdateSupportedStyleSet(); - // SetIsPalmaPairedConnectable(); + resource_manager->GetPalma()->SetIsPalmaPairedConnectable(aruid, true); } return ResultSuccess; @@ -680,7 +683,8 @@ Result Npad::ApplyNpadSystemCommonPolicy(const u64 aruid) { if (result.IsSuccess()) { // UpdateSystemCommonPolicy(); - // SetIsPalmaPairedConnectable(); + const bool is_connectable = true; //(*param_1 + 4) >> 6 & 1 + resource_manager->GetPalma()->SetIsPalmaPairedConnectable(aruid, is_connectable); } return result; @@ -692,7 +696,8 @@ Result Npad::ApplyNpadSystemCommonPolicyFull(const u64 aruid) { if (result.IsSuccess()) { // UpdateSystemCommonPolicy(); - // SetIsPalmaPairedConnectable(); + const bool is_connectable = true; //(*param_1 + 4) >> 6 & 1 + resource_manager->GetPalma()->SetIsPalmaPairedConnectable(aruid, is_connectable); } return result; diff --git a/src/core/hle/service/hid/resource_manager/npad_resource/npad.h b/src/core/hle/service/hid/resource_manager/npad_resource/npad.h index 43af17c11..f0f8a61ce 100644 --- a/src/core/hle/service/hid/resource_manager/npad_resource/npad.h +++ b/src/core/hle/service/hid/resource_manager/npad_resource/npad.h @@ -77,7 +77,8 @@ private: class Npad final : public BaseResource { public: - explicit Npad(KernelHelpers::ServiceContext& context); + explicit Npad(KernelHelpers::ServiceContext& context, + std::shared_ptr resource); ~Npad(); Result Activate(const u64 aruid); @@ -183,9 +184,11 @@ private: std::shared_ptr active_npad_state = nullptr; NpadJoyHoldType default_joy_hold_type{}; std::array, ARUID_MAX> npad_state{}; - std::array, PLAYERS_MAX> abstract_npad_state; - KernelHelpers::ServiceContext& service_context; + std::array, PLAYERS_MAX> abstract_npad_state{}; float vibration_master_volume{}; + + KernelHelpers::ServiceContext& service_context; + std::shared_ptr resource_manager = nullptr; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager/palma.cpp b/src/core/hle/service/hid/resource_manager/palma.cpp index 10292bcb0..b9e02bcbf 100644 --- a/src/core/hle/service/hid/resource_manager/palma.cpp +++ b/src/core/hle/service/hid/resource_manager/palma.cpp @@ -1,27 +1,681 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +#include "core/hle/kernel/k_event.h" +#include "core/hle/service/hid/hid_result.h" #include "core/hle/service/hid/hid_types.h" #include "core/hle/service/hid/hid_util.h" #include "core/hle/service/hid/resource_manager/palma.h" namespace Service::HID { +PalmaState::PalmaState() {} + +PalmaState::~PalmaState() = default; + +Result PalmaState::GetPalmaConnectionHandle(PalmaConnectionHandle& out_handle) const { + if (npad_id != NpadIdType::Invalid) { + out_handle = palma_handle; + return ResultSuccess; + } + + return ResultInvalidPalmaHandle; +} + +Result PalmaState::AcquirePalmaOperationCompleteEvent(Kernel::KReadableEvent** out_event) const { + if (npad_id != NpadIdType::Invalid) { + *out_event = &GetOperationCompleteEvent(); + return ResultSuccess; + } + return ResultInvalidPalmaHandle; +} + +Kernel::KReadableEvent& PalmaState::GetOperationCompleteEvent() const { + return operation_complete_event->GetReadableEvent(); +} + +Result PalmaState::GetPalmaOperationInfo(PalmaOperationType& out_type, + PalmaOperationData& out_data) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + // Too complicated here +} + +Result PalmaState::PlayPalmaActivity(const u32 activity) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->PlayPalmaActivity(activity); + + return XcdResultToPalma(result); +} + +Result PalmaState::SetPalmaFrModeType(const PalmaFrModeType type) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->SetPalmaFrModeType(type); + + return XcdResultToPalma(result); +} + +Result PalmaState::ReadPalmaStep() const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->ReadPalmaStep(); + + return XcdResultToPalma(result); +} + +Result PalmaState::EnablePalmaStep(const bool is_enabled) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->EnablePalmaStep(is_enabled); + + return XcdResultToPalma(result); +} + +Result PalmaState::ResetPalmaStep() const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->ResetPalmaStep(); + + return XcdResultToPalma(result); +} + +Result PalmaState::ReadPalmaApplicationSection(const u32 starting_index, u32 size) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->ReadPalmaApplicationSection(starting_index, size); + + return XcdResultToPalma(result); +} + +Result PalmaState::WritePalmaApplicationSection(const u32 starting_index, u32 size, + std::span buffer) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->WritePalmaApplicationSection(starting_index, size, buffer); + + return XcdResultToPalma(result); +} + +Result PalmaState::ReadPalmaUniqueCode() const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->ReadPalmaUniqueCode(); + + return XcdResultToPalma(result); +} + +Result PalmaState::SetPalmaUniqueCodeInvalid() const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->SetPalmaUniqueCodeInvalid(); + + return XcdResultToPalma(result); +} + +Result PalmaState::WritePalmaActivityEntry(const u16 a, const u16 b, const u8 c, + const u16 d) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + if (a > 2) { + // This should crash console + ASSERT_MSG("Unexpected palma error"); + return ResultUnknown; + } + + // TODO: Verify This one + const Result result = xcd->WritePalmaActivityEntry(a, b, c, d); + + return XcdResultToPalma(result); +} + +Result PalmaState::WritePalmaRgbLedPatternEntry(const u16 pattern_type, + std::span buffer) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + // TODO: Verify This one + const Result result = xcd->WritePalmaRgbLedPatternEntry(pattern_type, buffer); + + return XcdResultToPalma(result); +} + +Result PalmaState::WritePalmaWaveEntry(const PalmaWaveSet wave_set, + const Common::ProcessAddress t_mem, + const std::size_t size) const { + + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + if (wave_set > PalmaWaveSet::Large) { + // This should crash console + ASSERT_MSG("Invalid wave set"); + return ResultUnknown; + } + + // TODO: Verify This one + const Result result = xcd->WritePalmaRgbLedPatternEntry(wave_set, t_mem, size); + + return XcdResultToPalma(result); +} +Result PalmaState::SetPalmaDataBaseIdentificationVersion(const s32 version) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->SetPalmaDataBaseIdentificationVersion(version); + + return XcdResultToPalma(result); +} + +Result PalmaState::GetPalmaDataBaseIdentificationVersion() const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->GetPalmaDataBaseIdentificationVersion(); + + return XcdResultToPalma(result); +} + +Result PalmaState::SuspendPalmaFeature(const s32 feature) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->SuspendPalmaFeature(feature); + + return XcdResultToPalma(result); +} + +Result PalmaState::GetPalmaOperationResult() const { + return operation_result; +} + +Result PalmaState::ReadPalmaPlayLog(const u32 entries) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->ReadPalmaPlayLog(entries); + + return XcdResultToPalma(result); +} + +Result PalmaState::ResetPalmaPlayLog(const u32 entries) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->ResetPalmaPlayLog(entries); + + return XcdResultToPalma(result); +} + +Result PalmaState::PairPalma() const { + return xcd->PairPalma(); +} + +Result PalmaState::CancelWritePalmaWaveEntry() const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + xcd->CancelWritePalmaWaveEntry(); + return ResultSuccess; +} + +Result PalmaState::GetPalmaBluetoothAddress(std::span out_address) const { + if (npad_id == NpadIdType::Invalid) { + return ResultInvalidPalmaHandle; + } + + const Result result = xcd->GetPalmaBluetoothAddress(out_address); + + return XcdResultToPalma(result); +} + +Result PalmaState::XcdResultToPalma(Result result) const { + if (result.IsSuccess()) { + return result; + } + + if (result == XCD::ResultUnknown1) { + return ResultInvalidPalmaNpadId; + } + if (result == XCD::ResultUnknown365) { + return ResultOperationFailed; + } + + // This should crash console + ASSERT_MSG("Unexpected palma error"); + return ResultUnknown; +} + Palma::Palma() {} Palma::~Palma() = default; -Result Palma::Activate(const u64 aruid) { - is_activated = true; - return ResultSuccess; +Result Palma::Initialize(const NpadIdType handle) { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].Initialize(); } -Result Palma::Activate() { - is_activated = true; - return ResultSuccess; +Result Palma::GetPalmaConnectionHandle(PalmaConnectionHandle& out_handle, + const NpadIdType npad_id) const { + std::scoped_lock lock{mutex}; + + Result result = palma_state[0].GetPalmaConnectionHandle(out_handle); + if (result.IsSuccess() && out_handle.npad_id == npad_id) { + return ResultSuccess; + } + + result = palma_state[1].GetPalmaConnectionHandle(out_handle); + if (result.IsSuccess() && out_handle.npad_id == npad_id) { + return ResultSuccess; + } + + return ResultInvalidPalmaNpadId; +} + +Result Palma::AcquirePalmaOperationCompleteEvent(const NpadIdType handle, + Kernel::KReadableEvent** out_event) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].AcquirePalmaOperationCompleteEvent(out_event); +} + +Result Palma::GetPalmaOperationInfo(const NpadIdType handle, PalmaOperationType& out_type, + PalmaOperationData& out_data) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].GetPalmaOperationInfo(out_type, out_data); +} + +Result Palma::PlayPalmaActivity(const NpadIdType handle, const u32 activity) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].PlayPalmaActivity(activity); +} + +Result Palma::SetPalmaFrModeType(const NpadIdType handle, const PalmaFrModeType type) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].SetPalmaFrModeType(type); +} + +Result Palma::ReadPalmaStep(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].ReadPalmaStep(); +} + +Result Palma::EnablePalmaStep(const NpadIdType handle, const bool is_enabled) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].EnablePalmaStep(is_enabled); +} + +Result Palma::ResetPalmaStep(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].ResetPalmaStep(); +} + +Result Palma::ReadPalmaApplicationSection(const NpadIdType handle, const u32 starting_index, + u32 size) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].ReadPalmaApplicationSection(starting_index, size); +} + +Result Palma::WritePalmaApplicationSection(const NpadIdType handle, const u32 starting_index, + u32 size, std::span buffer) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].WritePalmaApplicationSection(starting_index, size, buffer); +} + +Result Palma::ReadPalmaUniqueCode(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].ReadPalmaUniqueCode(); +} + +Result Palma::SetPalmaUniqueCodeInvalid(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].SetPalmaUniqueCodeInvalid(); +} + +Result Palma::WritePalmaActivityEntry(const NpadIdType handle, const u64 a, const u64 b, + const u64 c, const u64 d) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].WritePalmaActivityEntry(a, b, c, d); +} + +Result Palma::WritePalmaRgbLedPatternEntry(const NpadIdType handle, const u16 pattern_type, + std::span buffer) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].WritePalmaRgbLedPatternEntry(pattern_type, buffer); +} + +Result Palma::WritePalmaWaveEntry(const NpadIdType handle, const PalmaWaveSet wave_set, + const Common::ProcessAddress t_mem, + const std::size_t size) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].WritePalmaWaveEntry(wave_set, t_mem, size); +} + +Result Palma::SetPalmaDataBaseIdentificationVersion(const NpadIdType handle, + const s32 version) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].SetPalmaDataBaseIdentificationVersion(version); +} + +Result Palma::GetPalmaDataBaseIdentificationVersion(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].GetPalmaDataBaseIdentificationVersion(); +} + +Result Palma::SuspendPalmaFeature(const NpadIdType handle, const s32 feature) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].SuspendPalmaFeature(feature); +} + +Result Palma::GetPalmaOperationResult(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].GetPalmaOperationResult(); +} + +Result Palma::ReadPalmaPlayLog(const NpadIdType handle, const u32 entries) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].ReadPalmaPlayLog(entries); +} + +Result Palma::ResetPalmaPlayLog(const NpadIdType handle, const u32 entries) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].ResetPalmaPlayLog(entries); +} + +void Palma::SetIsPalmaAllConnectable(const u64 aruid, const bool is_connectable) const { + // No mistake was made here. It uses two different locks + std::scoped_lock lock{mutex}; + std::scoped_lock recursive_lock{recursive_mutex}; + + // SetIsPalmaAllConnectable2(*(undefined8*)¶m_1->field_0x158, *aruid, is_connectable & 1); + // if (**(long**)¶m_1->field_0x158 == *aruid || *aruid == 0) { + // (**(code**)(**(long**)¶m_1->field_0x168 + 0x50))(*(long**)¶m_1->field_0x168, + // is_connectable & 1); + // } +} + +void Palma::SetIsPalmaPairedConnectable(const u64 aruid, const bool is_connectable) const { + std::scoped_lock lock{mutex}; + //(**(code**)(**(long**)¶m_1->field_0x168 + 0x58))(*(long**)¶m_1->field_0x168, + // param_2 & 1); +} + +Result Palma::PairPalma(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].PairPalma(); +} + +Result Palma::CancelWritePalmaWaveEntry(const NpadIdType handle) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].CancelWritePalmaWaveEntry(); } void Palma::EnablePalmaBoostMode(const u64 aruid, const bool is_enabled) { + std::scoped_lock lock{mutex}; + // if ((*(long*)(param_1 + 0x158) != 0) && (lVar1 = *(long*)(param_1 + 0x160), lVar1 != 0)) { + // nn::os::SdkRecursiveMutexType::Lock(lVar1); + // EnablePalmaBoostMode2(*(undefined8*)(param_1 + 0x158), *applet_resource, is_enabled); + // if ((**(long**)(param_1 + 0x158) == *applet_resource) || (*applet_resource == 0)) { + // (**(code**)(**(long**)(param_1 + 0x168) + 0x60))(*(long**)(param_1 + 0x168), + // is_enabled); + // } + // nn::os::SdkRecursiveMutexType::Unlock(lVar1); + // } +} + +Result Palma::GetPalmaBluetoothAddress(const NpadIdType handle, std::span out_address) const { + std::scoped_lock lock{mutex}; + + std::size_t active_index{}; + Result result = GetActiveHandleIndex(handle, active_index); + + if (result.IsError()) { + return result; + } + + return palma_state[active_index].GetPalmaBluetoothAddress(out_address); +} + +void Palma::SetDisallowedPalmaConnection(const u64 aruid, std::span address) const { + std::scoped_lock lock{mutex}; + + // if ((*(long*)(param_1 + 0x158) != 0) && (lVar1 = *(long*)(param_1 + 0x160), lVar1 != 0)) { + // nn::os::SdkRecursiveMutexType::Lock(lVar1); + // if ((**(long**)(param_1 + 0x158) == *param_2) || (*param_2 == 0)) { + // (**(code**)(**(long**)(param_1 + 0x168) + 0x68))(*(long**)(param_1 + 0x168), + // &local_40); + // } + // nn::os::SdkRecursiveMutexType::Unlock(lVar1); + // } +} + +Result Palma::GetActiveHandleIndex(const NpadIdType npad_id, std::size_t out_index) const { + PalmaConnectionHandle active_handle{}; + Result result = palma_state[0].GetPalmaConnectionHandle(active_handle); + if (result.IsSuccess() && active_handle.npad_id == npad_id) { + out_index = 0; + return ResultSuccess; + } + + result = palma_state[1].GetPalmaConnectionHandle(active_handle); + if (result.IsSuccess() && active_handle.npad_id == npad_id) { + out_index = 1; + return ResultSuccess; + } + + return ResultInvalidPalmaHandle; } } // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager/palma.h b/src/core/hle/service/hid/resource_manager/palma.h index a621998bf..45a995f8d 100644 --- a/src/core/hle/service/hid/resource_manager/palma.h +++ b/src/core/hle/service/hid/resource_manager/palma.h @@ -19,16 +19,57 @@ namespace Service::HID {} // namespace Service::HID namespace Service::HID { +class PalmaState { +public: + explicit PalmaState(); + ~PalmaState(); + + Result Initialize(); + Result GetPalmaConnectionHandle(PalmaConnectionHandle& out_handle) const; + Result AcquirePalmaOperationCompleteEvent(Kernel::KReadableEvent** out_event) const; + Result GetPalmaOperationInfo(PalmaOperationType& out_type, PalmaOperationData& out_data) const; + Result PlayPalmaActivity(const u32 activity) const; + Result SetPalmaFrModeType(const PalmaFrModeType type) const; + Result ReadPalmaStep() const; + Result EnablePalmaStep(const bool is_enabled) const; + Result ResetPalmaStep() const; + Result ReadPalmaApplicationSection(const u32 starting_index, u32 size) const; + Result WritePalmaApplicationSection(const u32 starting_index, u32 size, + std::span buffer) const; + Result ReadPalmaUniqueCode() const; + Result SetPalmaUniqueCodeInvalid() const; + Result WritePalmaActivityEntry(const u16 a, const u16 b, const u8 c, const u16 d) const; + Result WritePalmaRgbLedPatternEntry(const u16 pattern_type, std::span buffer) const; + Result WritePalmaWaveEntry(const PalmaWaveSet wave_set, const Common::ProcessAddress t_mem, + const std::size_t size) const; + Result SetPalmaDataBaseIdentificationVersion(const s32 version) const; + Result GetPalmaDataBaseIdentificationVersion() const; + Result SuspendPalmaFeature(const s32 feature) const; + Result GetPalmaOperationResult() const; + Result ReadPalmaPlayLog(const u32 entries) const; + Result ResetPalmaPlayLog(const u32 entries) const; + Result PairPalma() const; + Result CancelWritePalmaWaveEntry() const; + Result GetPalmaBluetoothAddress(std::span out_address) const; + +private: + Kernel::KReadableEvent& GetOperationCompleteEvent() const; + Result XcdResultToPalma(Result result) const; + + Kernel::KEvent* operation_complete_event = nullptr; + NpadIdType npad_id{NpadIdType::Invalid}; + PalmaConnectionHandle palma_handle{}; + Result operation_result{}; +}; + class Palma final : public BaseResource { public: explicit Palma(); ~Palma(); - Result Activate(const u64 aruid); - Result Activate(); - Result Initialize(const NpadIdType handle); - Result GetPalmaConnectionHandle(PalmaConnectionHandle& out_handle, const u64 aruid) const; + Result GetPalmaConnectionHandle(PalmaConnectionHandle& out_handle, + const NpadIdType npad_id) const; Result AcquirePalmaOperationCompleteEvent(const NpadIdType handle, Kernel::KReadableEvent** out_event) const; Result GetPalmaOperationInfo(const NpadIdType handle, PalmaOperationType& out_type, @@ -66,7 +107,11 @@ public: void SetDisallowedPalmaConnection(const u64 aruid, std::span address) const; private: - bool is_activated; + Result GetActiveHandleIndex(const NpadIdType npad_id, std::size_t out_index) const; + + mutable std::mutex mutex; + mutable std::recursive_mutex recursive_mutex; + std::array palma_state{}; }; } // namespace Service::HID