enough palma trees

This commit is contained in:
Narr the Reg 2023-08-20 14:32:09 -06:00
parent 4f5b1fe41f
commit 600a02fe29
6 changed files with 736 additions and 20 deletions

View File

@ -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

View File

@ -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);

View File

@ -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<ResourceManager> resource)
: service_context{context}, resource_manager{resource} {
for (auto& npad : npad_state) {
npad = std::make_shared<NpadState>();
}
@ -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;

View File

@ -77,7 +77,8 @@ private:
class Npad final : public BaseResource {
public:
explicit Npad(KernelHelpers::ServiceContext& context);
explicit Npad(KernelHelpers::ServiceContext& context,
std::shared_ptr<ResourceManager> resource);
~Npad();
Result Activate(const u64 aruid);
@ -183,9 +184,11 @@ private:
std::shared_ptr<NpadState> active_npad_state = nullptr;
NpadJoyHoldType default_joy_hold_type{};
std::array<std::shared_ptr<NpadState>, ARUID_MAX> npad_state{};
std::array<std::shared_ptr<AbstractNpadState>, PLAYERS_MAX> abstract_npad_state;
KernelHelpers::ServiceContext& service_context;
std::array<std::shared_ptr<AbstractNpadState>, PLAYERS_MAX> abstract_npad_state{};
float vibration_master_volume{};
KernelHelpers::ServiceContext& service_context;
std::shared_ptr<ResourceManager> resource_manager = nullptr;
};
} // namespace Service::HID

View File

@ -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<const u8> 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<const u8> 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<u8> 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<const u8> 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<const u8> 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*)&param_1->field_0x158, *aruid, is_connectable & 1);
// if (**(long**)&param_1->field_0x158 == *aruid || *aruid == 0) {
// (**(code**)(**(long**)&param_1->field_0x168 + 0x50))(*(long**)&param_1->field_0x168,
// is_connectable & 1);
// }
}
void Palma::SetIsPalmaPairedConnectable(const u64 aruid, const bool is_connectable) const {
std::scoped_lock lock{mutex};
//(**(code**)(**(long**)&param_1->field_0x168 + 0x58))(*(long**)&param_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<u8> 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<const u8> 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

View File

@ -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<const u8> 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<const u8> 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<u8> 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<const u8> 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<PalmaState, 2> palma_state{};
};
} // namespace Service::HID