enough palma trees
This commit is contained in:
parent
4f5b1fe41f
commit
600a02fe29
|
@ -27,6 +27,15 @@ constexpr Result ResultInvalidStyleSet{ErrorModule::HID, 717};
|
||||||
|
|
||||||
constexpr Result ResultUnknown108{ErrorModule::HID, 108};
|
constexpr Result ResultUnknown108{ErrorModule::HID, 108};
|
||||||
|
|
||||||
|
constexpr Result ResultInvalidPalmaNpadId{ErrorModule::HID, 3301};
|
||||||
constexpr Result ResultInvalidPalmaHandle{ErrorModule::HID, 3302};
|
constexpr Result ResultInvalidPalmaHandle{ErrorModule::HID, 3302};
|
||||||
|
constexpr Result ResultOperationFailed{ErrorModule::HID, 3304};
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
||||||
|
namespace Service::XCD {
|
||||||
|
|
||||||
|
constexpr Result ResultUnknown1{ErrorModule::XCD, 1};
|
||||||
|
constexpr Result ResultUnknown365{ErrorModule::XCD, 365};
|
||||||
|
|
||||||
|
} // namespace Service::XCD
|
||||||
|
|
|
@ -2151,8 +2151,8 @@ void IHidServer::GetPalmaConnectionHandle(HLERequestContext& ctx) {
|
||||||
parameters.npad_id, parameters.applet_resource_user_id);
|
parameters.npad_id, parameters.applet_resource_user_id);
|
||||||
|
|
||||||
PalmaConnectionHandle handle{};
|
PalmaConnectionHandle handle{};
|
||||||
const Result result = GetResourceManager()->GetPalma()->GetPalmaConnectionHandle(
|
const Result result =
|
||||||
handle, parameters.applet_resource_user_id);
|
GetResourceManager()->GetPalma()->GetPalmaConnectionHandle(handle, parameters.npad_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(result);
|
rb.Push(result);
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
#include "core/hle/service/hid/hid_result.h"
|
#include "core/hle/service/hid/hid_result.h"
|
||||||
#include "core/hle/service/hid/hid_types.h"
|
#include "core/hle/service/hid/hid_types.h"
|
||||||
#include "core/hle/service/hid/hid_util.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.h"
|
||||||
#include "core/hle/service/hid/resource_manager/npad_resource/npad_controller_state.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_shared_types.h"
|
||||||
#include "core/hle/service/hid/resource_manager/npad_resource/npad_state.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 {
|
namespace Service::HID {
|
||||||
|
|
||||||
|
@ -76,7 +78,8 @@ void AbstractNpadState::UpdateBatteryLifoImpl(const BatteryState& battery_state,
|
||||||
internal_state.battery_level_right = battery_state.battery_level_right;
|
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) {
|
for (auto& npad : npad_state) {
|
||||||
npad = std::make_shared<NpadState>();
|
npad = std::make_shared<NpadState>();
|
||||||
}
|
}
|
||||||
|
@ -206,7 +209,7 @@ Result Npad::SetSupportedNpadStyleSet(const u64 aruid, const NpadStyleSet suppor
|
||||||
|
|
||||||
if (result.IsSuccess()) {
|
if (result.IsSuccess()) {
|
||||||
UpdateSupportedStyleSet();
|
UpdateSupportedStyleSet();
|
||||||
// SetIsPalmaPairedConnectable();
|
resource_manager->GetPalma()->SetIsPalmaPairedConnectable(aruid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
|
@ -680,7 +683,8 @@ Result Npad::ApplyNpadSystemCommonPolicy(const u64 aruid) {
|
||||||
|
|
||||||
if (result.IsSuccess()) {
|
if (result.IsSuccess()) {
|
||||||
// UpdateSystemCommonPolicy();
|
// UpdateSystemCommonPolicy();
|
||||||
// SetIsPalmaPairedConnectable();
|
const bool is_connectable = true; //(*param_1 + 4) >> 6 & 1
|
||||||
|
resource_manager->GetPalma()->SetIsPalmaPairedConnectable(aruid, is_connectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -692,7 +696,8 @@ Result Npad::ApplyNpadSystemCommonPolicyFull(const u64 aruid) {
|
||||||
|
|
||||||
if (result.IsSuccess()) {
|
if (result.IsSuccess()) {
|
||||||
// UpdateSystemCommonPolicy();
|
// UpdateSystemCommonPolicy();
|
||||||
// SetIsPalmaPairedConnectable();
|
const bool is_connectable = true; //(*param_1 + 4) >> 6 & 1
|
||||||
|
resource_manager->GetPalma()->SetIsPalmaPairedConnectable(aruid, is_connectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -77,7 +77,8 @@ private:
|
||||||
|
|
||||||
class Npad final : public BaseResource {
|
class Npad final : public BaseResource {
|
||||||
public:
|
public:
|
||||||
explicit Npad(KernelHelpers::ServiceContext& context);
|
explicit Npad(KernelHelpers::ServiceContext& context,
|
||||||
|
std::shared_ptr<ResourceManager> resource);
|
||||||
~Npad();
|
~Npad();
|
||||||
|
|
||||||
Result Activate(const u64 aruid);
|
Result Activate(const u64 aruid);
|
||||||
|
@ -183,9 +184,11 @@ private:
|
||||||
std::shared_ptr<NpadState> active_npad_state = nullptr;
|
std::shared_ptr<NpadState> active_npad_state = nullptr;
|
||||||
NpadJoyHoldType default_joy_hold_type{};
|
NpadJoyHoldType default_joy_hold_type{};
|
||||||
std::array<std::shared_ptr<NpadState>, ARUID_MAX> npad_state{};
|
std::array<std::shared_ptr<NpadState>, ARUID_MAX> npad_state{};
|
||||||
std::array<std::shared_ptr<AbstractNpadState>, PLAYERS_MAX> abstract_npad_state;
|
std::array<std::shared_ptr<AbstractNpadState>, PLAYERS_MAX> abstract_npad_state{};
|
||||||
KernelHelpers::ServiceContext& service_context;
|
|
||||||
float vibration_master_volume{};
|
float vibration_master_volume{};
|
||||||
|
|
||||||
|
KernelHelpers::ServiceContext& service_context;
|
||||||
|
std::shared_ptr<ResourceManager> resource_manager = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -1,27 +1,681 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// 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_types.h"
|
||||||
#include "core/hle/service/hid/hid_util.h"
|
#include "core/hle/service/hid/hid_util.h"
|
||||||
#include "core/hle/service/hid/resource_manager/palma.h"
|
#include "core/hle/service/hid/resource_manager/palma.h"
|
||||||
|
|
||||||
namespace Service::HID {
|
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() {}
|
||||||
|
|
||||||
Palma::~Palma() = default;
|
Palma::~Palma() = default;
|
||||||
|
|
||||||
Result Palma::Activate(const u64 aruid) {
|
Result Palma::Initialize(const NpadIdType handle) {
|
||||||
is_activated = true;
|
std::scoped_lock lock{mutex};
|
||||||
return ResultSuccess;
|
|
||||||
|
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() {
|
Result Palma::GetPalmaConnectionHandle(PalmaConnectionHandle& out_handle,
|
||||||
is_activated = true;
|
const NpadIdType npad_id) const {
|
||||||
return ResultSuccess;
|
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*)¶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) {
|
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
|
} // namespace Service::HID
|
||||||
|
|
|
@ -19,16 +19,57 @@ namespace Service::HID {} // 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 {
|
class Palma final : public BaseResource {
|
||||||
public:
|
public:
|
||||||
explicit Palma();
|
explicit Palma();
|
||||||
~Palma();
|
~Palma();
|
||||||
|
|
||||||
Result Activate(const u64 aruid);
|
|
||||||
Result Activate();
|
|
||||||
|
|
||||||
Result Initialize(const NpadIdType handle);
|
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,
|
Result AcquirePalmaOperationCompleteEvent(const NpadIdType handle,
|
||||||
Kernel::KReadableEvent** out_event) const;
|
Kernel::KReadableEvent** out_event) const;
|
||||||
Result GetPalmaOperationInfo(const NpadIdType handle, PalmaOperationType& out_type,
|
Result GetPalmaOperationInfo(const NpadIdType handle, PalmaOperationType& out_type,
|
||||||
|
@ -66,7 +107,11 @@ public:
|
||||||
void SetDisallowedPalmaConnection(const u64 aruid, std::span<const u8> address) const;
|
void SetDisallowedPalmaConnection(const u64 aruid, std::span<const u8> address) const;
|
||||||
|
|
||||||
private:
|
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
|
} // namespace Service::HID
|
||||||
|
|
Loading…
Reference in New Issue