diff options
| author | Narr the Reg <juangerman-13@hotmail.com> | 2022-01-18 20:08:56 -0600 | 
|---|---|---|
| committer | german77 <juangerman-13@hotmail.com> | 2022-09-25 00:13:12 -0500 | 
| commit | 23589ad9b8a3d2e1eecd0243d592ce5c6e4138e6 (patch) | |
| tree | 382d897d920e7415064f56fd8f9dfedd07cc62fe | |
| parent | 8d4458ef24e473e57b9931d7a9d1442b51fb0b1a (diff) | |
service: hid: Partially implement palma controller
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/palma.cpp | 229 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/palma.h | 163 | ||||
| -rw-r--r-- | src/core/hle/service/hid/errors.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 444 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 29 | 
7 files changed, 842 insertions, 33 deletions
| diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 33cf470d5..c17662323 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -460,6 +460,8 @@ add_library(core STATIC      hle/service/hid/controllers/mouse.h      hle/service/hid/controllers/npad.cpp      hle/service/hid/controllers/npad.h +    hle/service/hid/controllers/palma.cpp +    hle/service/hid/controllers/palma.h      hle/service/hid/controllers/stubbed.cpp      hle/service/hid/controllers/stubbed.h      hle/service/hid/controllers/touchscreen.cpp diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index cb29004e8..f8972ec7a 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -660,7 +660,6 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing              ASSERT(false);              break;          case Core::HID::NpadStyleIndex::ProController: -        case Core::HID::NpadStyleIndex::Pokeball:              set_motion_state(sixaxis_fullkey_state, motion_state[0]);              break;          case Core::HID::NpadStyleIndex::Handheld: @@ -676,6 +675,11 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing          case Core::HID::NpadStyleIndex::JoyconRight:              set_motion_state(sixaxis_right_lifo_state, motion_state[1]);              break; +        case Core::HID::NpadStyleIndex::Pokeball: +            using namespace std::literals::chrono_literals; +            set_motion_state(sixaxis_fullkey_state, motion_state[0]); +            sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count(); +            break;          default:              break;          } diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp new file mode 100644 index 000000000..575d4e626 --- /dev/null +++ b/src/core/hle/service/hid/controllers/palma.cpp @@ -0,0 +1,229 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/core_timing.h" +#include "core/hid/emulated_controller.h" +#include "core/hid/hid_core.h" +#include "core/hid/hid_types.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_readable_event.h" +#include "core/hle/service/hid/controllers/palma.h" +#include "core/hle/service/kernel_helpers.h" + +namespace Service::HID { + +Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, +                                   KernelHelpers::ServiceContext& service_context_) +    : ControllerBase{hid_core_}, service_context{service_context_} { +    controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); +    operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); +} + +Controller_Palma::~Controller_Palma() = default; + +void Controller_Palma::OnInit() {} + +void Controller_Palma::OnRelease() {} + +void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) { +    if (!IsControllerActivated()) { +        return; +    } +} + +Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, +                                                  PalmaConnectionHandle& handle) { +    active_handle.npad_id = npad_id; +    handle = active_handle; +    return ResultSuccess; +} + +Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    ActivateController(); +    return ResultSuccess; +} + +Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent( +    const PalmaConnectionHandle& handle) const { +    if (handle.npad_id != active_handle.npad_id) { +        LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id); +    } +    return operation_complete_event->GetReadableEvent(); +} + +Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle, +                                               PalmaOperationType& operation_type, +                                               PalmaOperationData& data) const { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation_type = operation.operation; +    data = operation.data; +    return ResultSuccess; +} + +Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, +                                           u64 palma_activity) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation.operation = PalmaOperationType::PlayActivity; +    operation.result = PalmaResultSuccess; +    operation.data = {}; +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, +                                            PalmaFrModeType fr_mode_) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    fr_mode = fr_mode_; +    return ResultSuccess; +} + +Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation.operation = PalmaOperationType::ReadStep; +    operation.result = PalmaResultSuccess; +    operation.data = {}; +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    return ResultSuccess; +} + +Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    return ResultSuccess; +} + +void Controller_Palma::ReadPalmaApplicationSection() {} + +void Controller_Palma::WritePalmaApplicationSection() {} + +Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation.operation = PalmaOperationType::ReadUniqueCode; +    operation.result = PalmaResultSuccess; +    operation.data = {}; +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation.operation = PalmaOperationType::SetUniqueCodeInvalid; +    operation.result = PalmaResultSuccess; +    operation.data = {}; +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +void Controller_Palma::WritePalmaActivityEntry() {} + +Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, +                                                      u64 unknown) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation.operation = PalmaOperationType::WriteRgbLedPatternEntry; +    operation.result = PalmaResultSuccess; +    operation.data = {}; +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, +                                             u8* t_mem, u64 size) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation.operation = PalmaOperationType::WriteWaveEntry; +    operation.result = PalmaResultSuccess; +    operation.data = {}; +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, +                                                               s32 database_id_version_) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    database_id_version = database_id_version_; +    operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; +    operation.result = PalmaResultSuccess; +    operation.data[0] = {}; +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +Result Controller_Palma::GetPalmaDataBaseIdentificationVersion( +    const PalmaConnectionHandle& handle) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; +    operation.result = PalmaResultSuccess; +    operation.data = {}; +    operation.data[0] = static_cast<u8>(database_id_version); +    operation_complete_event->GetWritableEvent().Signal(); +    return ResultSuccess; +} + +void Controller_Palma::SuspendPalmaFeature() {} + +Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    return operation.result; +} +void Controller_Palma::ReadPalmaPlayLog() {} + +void Controller_Palma::ResetPalmaPlayLog() {} + +void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) { +    // If true controllers are able to be paired +    is_connectable = is_all_connectable; +} + +void Controller_Palma::SetIsPalmaPairedConnectable() {} + +Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) { +    if (handle.npad_id != active_handle.npad_id) { +        return InvalidPalmaHandle; +    } +    // TODO: Do something +    return ResultSuccess; +} + +void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {} + +void Controller_Palma::CancelWritePalmaWaveEntry() {} + +void Controller_Palma::EnablePalmaBoostMode() {} + +void Controller_Palma::GetPalmaBluetoothAddress() {} + +void Controller_Palma::SetDisallowedPalmaConnection() {} + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h new file mode 100644 index 000000000..1d7fc94e1 --- /dev/null +++ b/src/core/hle/service/hid/controllers/palma.h @@ -0,0 +1,163 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <array> +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "core/hle/service/hid/controllers/controller_base.h" +#include "core/hle/service/hid/errors.h" + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Service::KernelHelpers { +class ServiceContext; +} + +namespace Core::HID { +class EmulatedController; +} // namespace Core::HID + +namespace Service::HID { +class Controller_Palma final : public ControllerBase { +public: +    using PalmaOperationData = std::array<u8, 0x140>; + +    // This is nn::hid::PalmaOperationType +    enum class PalmaOperationType { +        PlayActivity, +        SetFrModeType, +        ReadStep, +        EnableStep, +        ResetStep, +        ReadApplicationSection, +        WriteApplicationSection, +        ReadUniqueCode, +        SetUniqueCodeInvalid, +        WriteActivityEntry, +        WriteRgbLedPatternEntry, +        WriteWaveEntry, +        ReadDataBaseIdentificationVersion, +        WriteDataBaseIdentificationVersion, +        SuspendFeature, +        ReadPlayLog, +        ResetPlayLog, +    }; + +    // This is nn::hid::PalmaWaveSet +    enum class PalmaWaveSet : u64 { +        Small, +        Medium, +        Large, +    }; + +    // This is nn::hid::PalmaFrModeType +    enum class PalmaFrModeType : u64 { +        Off, +        B01, +        B02, +        B03, +        Downloaded, +    }; + +    // This is nn::hid::PalmaFeature +    enum class PalmaFeature : u64 { +        FrMode, +        RumbleFeedback, +        Step, +        MuteSwitch, +    }; + +    // This is nn::hid::PalmaOperationInfo +    struct PalmaOperationInfo { +        PalmaOperationType operation{}; +        Result result{PalmaResultSuccess}; +        PalmaOperationData data{}; +    }; +    static_assert(sizeof(PalmaOperationInfo) == 0x148, "PalmaOperationInfo is an invalid size"); + +    // This is nn::hid::PalmaActivityEntry +    struct PalmaActivityEntry { +        u32 rgb_led_pattern_index; +        INSERT_PADDING_BYTES(2); +        PalmaWaveSet wave_set; +        u32 wave_index; +        INSERT_PADDING_BYTES(12); +    }; +    static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size"); + +    struct PalmaConnectionHandle { +        Core::HID::NpadIdType npad_id; +        INSERT_PADDING_BYTES(4); // Unknown +    }; +    static_assert(sizeof(PalmaConnectionHandle) == 0x8, +                  "PalmaConnectionHandle has incorrect size."); + +    explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, +                              KernelHelpers::ServiceContext& service_context_); +    ~Controller_Palma() override; + +    // Called when the controller is initialized +    void OnInit() override; + +    // When the controller is released +    void OnRelease() override; + +    // When the controller is requesting an update for the shared memory +    void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; + +    Result GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, PalmaConnectionHandle& handle); +    Result InitializePalma(const PalmaConnectionHandle& handle); +    Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent( +        const PalmaConnectionHandle& handle) const; +    Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle, +                                 PalmaOperationType& operation_type, +                                 PalmaOperationData& data) const; +    Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity); +    Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_); +    Result ReadPalmaStep(const PalmaConnectionHandle& handle); +    Result EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled); +    Result ResetPalmaStep(const PalmaConnectionHandle& handle); +    Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle); +    Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle); +    Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown); +    Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, u8* t_mem, +                               u64 size); +    Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, +                                                 s32 database_id_version_); +    Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle); +    Result GetPalmaOperationResult(const PalmaConnectionHandle& handle) const; +    void SetIsPalmaAllConnectable(bool is_all_connectable); +    Result PairPalma(const PalmaConnectionHandle& handle); +    void SetPalmaBoostMode(bool boost_mode); + +private: +    void ReadPalmaApplicationSection(); +    void WritePalmaApplicationSection(); +    void WritePalmaActivityEntry(); +    void SuspendPalmaFeature(); +    void ReadPalmaPlayLog(); +    void ResetPalmaPlayLog(); +    void SetIsPalmaPairedConnectable(); +    void CancelWritePalmaWaveEntry(); +    void EnablePalmaBoostMode(); +    void GetPalmaBluetoothAddress(); +    void SetDisallowedPalmaConnection(); + +    bool is_connectable{}; +    s32 database_id_version{}; +    PalmaOperationInfo operation{}; +    PalmaFrModeType fr_mode{}; +    PalmaConnectionHandle active_handle{}; + +    Core::HID::EmulatedController* controller; + +    Kernel::KEvent* operation_complete_event; +    KernelHelpers::ServiceContext& service_context; +}; + +} // namespace Service::HID diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index 4613a4e60..76208e9a4 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h @@ -7,6 +7,7 @@  namespace Service::HID { +constexpr Result PalmaResultSuccess{ErrorModule::HID, 0};  constexpr Result NpadInvalidHandle{ErrorModule::HID, 100};  constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};  constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122}; @@ -17,6 +18,7 @@ constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};  constexpr Result NpadIsSameType{ErrorModule::HID, 602};  constexpr Result InvalidNpadId{ErrorModule::HID, 709};  constexpr Result NpadNotConnected{ErrorModule::HID, 710}; +constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};  } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 3d3457160..de3fae2cb 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -27,6 +27,7 @@  #include "core/hle/service/hid/controllers/keyboard.h"  #include "core/hle/service/hid/controllers/mouse.h"  #include "core/hle/service/hid/controllers/npad.h" +#include "core/hle/service/hid/controllers/palma.h"  #include "core/hle/service/hid/controllers/stubbed.h"  #include "core/hle/service/hid/controllers/touchscreen.h"  #include "core/hle/service/hid/controllers/xpad.h" @@ -60,6 +61,7 @@ IAppletResource::IAppletResource(Core::System& system_,      MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);      MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);      MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory); +    MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory);      // Homebrew doesn't try to activate some controllers, so we activate them by default      GetController<Controller_NPad>(HidController::NPad).ActivateController(); @@ -310,36 +312,36 @@ Hid::Hid(Core::System& system_)          {406, nullptr, "GetNpadLeftRightInterfaceType"},          {407, nullptr, "GetNpadOfHighestBatteryLevel"},          {408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"}, -        {500, nullptr, "GetPalmaConnectionHandle"}, -        {501, nullptr, "InitializePalma"}, -        {502, nullptr, "AcquirePalmaOperationCompleteEvent"}, -        {503, nullptr, "GetPalmaOperationInfo"}, -        {504, nullptr, "PlayPalmaActivity"}, -        {505, nullptr, "SetPalmaFrModeType"}, -        {506, nullptr, "ReadPalmaStep"}, -        {507, nullptr, "EnablePalmaStep"}, -        {508, nullptr, "ResetPalmaStep"}, -        {509, nullptr, "ReadPalmaApplicationSection"}, -        {510, nullptr, "WritePalmaApplicationSection"}, -        {511, nullptr, "ReadPalmaUniqueCode"}, -        {512, nullptr, "SetPalmaUniqueCodeInvalid"}, -        {513, nullptr, "WritePalmaActivityEntry"}, -        {514, nullptr, "WritePalmaRgbLedPatternEntry"}, -        {515, nullptr, "WritePalmaWaveEntry"}, -        {516, nullptr, "SetPalmaDataBaseIdentificationVersion"}, -        {517, nullptr, "GetPalmaDataBaseIdentificationVersion"}, -        {518, nullptr, "SuspendPalmaFeature"}, -        {519, nullptr, "GetPalmaOperationResult"}, -        {520, nullptr, "ReadPalmaPlayLog"}, -        {521, nullptr, "ResetPalmaPlayLog"}, +        {500, &Hid::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"}, +        {501, &Hid::InitializePalma, "InitializePalma"}, +        {502, &Hid::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"}, +        {503, &Hid::GetPalmaOperationInfo, "GetPalmaOperationInfo"}, +        {504, &Hid::PlayPalmaActivity, "PlayPalmaActivity"}, +        {505, &Hid::SetPalmaFrModeType, "SetPalmaFrModeType"}, +        {506, &Hid::ReadPalmaStep, "ReadPalmaStep"}, +        {507, &Hid::EnablePalmaStep, "EnablePalmaStep"}, +        {508, &Hid::ResetPalmaStep, "ResetPalmaStep"}, +        {509, &Hid::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"}, +        {510, &Hid::WritePalmaApplicationSection, "WritePalmaApplicationSection"}, +        {511, &Hid::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"}, +        {512, &Hid::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"}, +        {513, &Hid::WritePalmaActivityEntry, "WritePalmaActivityEntry"}, +        {514, &Hid::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"}, +        {515, &Hid::WritePalmaWaveEntry, "WritePalmaWaveEntry"}, +        {516, &Hid::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"}, +        {517, &Hid::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"}, +        {518, &Hid::SuspendPalmaFeature, "SuspendPalmaFeature"}, +        {519, &Hid::GetPalmaOperationResult, "GetPalmaOperationResult"}, +        {520, &Hid::ReadPalmaPlayLog, "ReadPalmaPlayLog"}, +        {521, &Hid::ResetPalmaPlayLog, "ResetPalmaPlayLog"},          {522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"}, -        {523, nullptr, "SetIsPalmaPairedConnectable"}, -        {524, nullptr, "PairPalma"}, +        {523, &Hid::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"}, +        {524, &Hid::PairPalma, "PairPalma"},          {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"}, -        {526, nullptr, "CancelWritePalmaWaveEntry"}, -        {527, nullptr, "EnablePalmaBoostMode"}, -        {528, nullptr, "GetPalmaBluetoothAddress"}, -        {529, nullptr, "SetDisallowedPalmaConnection"}, +        {526, &Hid::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"}, +        {527, &Hid::EnablePalmaBoostMode, "EnablePalmaBoostMode"}, +        {528, &Hid::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"}, +        {529, &Hid::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"},          {1000, &Hid::SetNpadCommunicationMode, "SetNpadCommunicationMode"},          {1001, &Hid::GetNpadCommunicationMode, "GetNpadCommunicationMode"},          {1002, &Hid::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"}, @@ -1878,14 +1880,361 @@ void Hid::IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx) {      rb.Push(false);  } +void Hid::GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    struct Parameters { +        Core::HID::NpadIdType npad_id; +        INSERT_PADDING_WORDS_NOINIT(1); +        u64 applet_resource_user_id; +    }; +    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + +    const auto parameters{rp.PopRaw<Parameters>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", +                parameters.npad_id, parameters.applet_resource_user_id); + +    Controller_Palma::PalmaConnectionHandle handle; +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle); + +    IPC::ResponseBuilder rb{ctx, 4}; +    rb.Push(result); +    rb.PushRaw(handle); +} + +void Hid::InitializePalma(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = controller.InitializePalma(connection_handle); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(result); +} + +void Hid::AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); + +    IPC::ResponseBuilder rb{ctx, 2, 1}; +    rb.Push(ResultSuccess); +    rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle)); +} + +void Hid::GetPalmaOperationInfo(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    Controller_Palma::PalmaOperationType operation_type; +    Controller_Palma::PalmaOperationData data; +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data); + +    if (result.IsError()) { +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(result); +    } + +    ctx.WriteBuffer(data); +    IPC::ResponseBuilder rb{ctx, 4}; +    rb.Push(result); +    rb.Push(static_cast<u64>(operation_type)); +} + +void Hid::PlayPalmaActivity(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; +    const auto palma_activity{rp.Pop<u64>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}", +                connection_handle.npad_id, palma_activity); + +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(result); +} + +void Hid::SetPalmaFrModeType(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; +    const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}", +                connection_handle.npad_id, fr_mode); + +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(result); +} + +void Hid::ReadPalmaStep(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = controller.ReadPalmaStep(connection_handle); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(result); +} + +void Hid::EnablePalmaStep(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    struct Parameters { +        bool is_enabled; +        INSERT_PADDING_WORDS_NOINIT(1); +        Controller_Palma::PalmaConnectionHandle connection_handle; +    }; +    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + +    const auto parameters{rp.PopRaw<Parameters>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}", +                parameters.connection_handle.npad_id, parameters.is_enabled); + +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = +        controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(result); +} + +void Hid::ResetPalmaStep(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma); +    const auto result = controller.ResetPalmaStep(connection_handle); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(result); +} + +void Hid::ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::WritePalmaApplicationSection(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .ReadPalmaUniqueCode(connection_handle); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .SetPalmaUniqueCodeInvalid(connection_handle); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::WritePalmaActivityEntry(Kernel::HLERequestContext& ctx) { +    LOG_CRITICAL(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; +    const auto unknown{rp.Pop<u64>()}; + +    const auto buffer = ctx.ReadBuffer(); + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}", +                connection_handle.npad_id, unknown); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .WritePalmaRgbLedPatternEntry(connection_handle, unknown); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; +    const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()}; +    const auto unknown{rp.Pop<u64>()}; +    const auto t_mem_size{rp.Pop<u64>()}; +    const auto t_mem_handle{ctx.GetCopyHandle(0)}; +    const auto size{rp.Pop<u64>()}; + +    ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes"); + +    auto t_mem = +        system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); + +    if (t_mem.IsNull()) { +        LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle); +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(ResultUnknown); +        return; +    } + +    ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size"); + +    LOG_WARNING(Service_HID, +                "(STUBBED) called, connection_handle={}, wave_set={}, unkown={}, " +                "t_mem_handle=0x{:08X}, t_mem_size={}, size={}", +                connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .WritePalmaWaveEntry(connection_handle, wave_set, +                             system.Memory().GetPointer(t_mem->GetSourceAddress()), t_mem_size); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    struct Parameters { +        s32 database_id_version; +        INSERT_PADDING_WORDS_NOINIT(1); +        Controller_Palma::PalmaConnectionHandle connection_handle; +    }; +    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + +    const auto parameters{rp.PopRaw<Parameters>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}", +                parameters.connection_handle.npad_id, parameters.database_id_version); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .SetPalmaDataBaseIdentificationVersion(parameters.connection_handle, +                                               parameters.database_id_version); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .GetPalmaDataBaseIdentificationVersion(connection_handle); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::SuspendPalmaFeature(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::GetPalmaOperationResult(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    const auto result = applet_resource->GetController<Controller_Palma>(HidController::Palma) +                            .GetPalmaOperationResult(connection_handle); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(result); +} + +void Hid::ReadPalmaPlayLog(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::ResetPalmaPlayLog(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} +  void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {      IPC::RequestParser rp{ctx}; -    const auto applet_resource_user_id{rp.Pop<u64>()}; -    const auto is_palma_all_connectable{rp.Pop<bool>()}; +    struct Parameters { +        bool is_palma_all_connectable; +        INSERT_PADDING_BYTES_NOINIT(7); +        u64 applet_resource_user_id; +    }; +    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + +    const auto parameters{rp.PopRaw<Parameters>()};      LOG_WARNING(Service_HID, -                "(STUBBED) called, applet_resource_user_id={}, is_palma_all_connectable={}", -                applet_resource_user_id, is_palma_all_connectable); +                "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}", +                parameters.is_palma_all_connectable, parameters.applet_resource_user_id); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .SetIsPalmaAllConnectable(parameters.is_palma_all_connectable); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::PairPalma(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; + +    LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); + +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .PairPalma(connection_handle);      IPC::ResponseBuilder rb{ctx, 2};      rb.Push(ResultSuccess); @@ -1897,6 +2246,37 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode); +    applet_resource->GetController<Controller_Palma>(HidController::Palma) +        .SetPalmaBoostMode(palma_boost_mode); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::EnablePalmaBoostMode(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); + +    IPC::ResponseBuilder rb{ctx, 2}; +    rb.Push(ResultSuccess); +} + +void Hid::SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx) { +    LOG_WARNING(Service_HID, "(STUBBED) called"); +      IPC::ResponseBuilder rb{ctx, 2};      rb.Push(ResultSuccess);  } diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index ac4333022..340d26fdc 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -33,6 +33,7 @@ enum class HidController : std::size_t {      NPad,      Gesture,      ConsoleSixAxisSensor, +    Palma,      MaxControllers,  }; @@ -166,8 +167,36 @@ private:      void FinalizeSevenSixAxisSensor(Kernel::HLERequestContext& ctx);      void ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx);      void IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx); +    void GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx); +    void InitializePalma(Kernel::HLERequestContext& ctx); +    void AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx); +    void GetPalmaOperationInfo(Kernel::HLERequestContext& ctx); +    void PlayPalmaActivity(Kernel::HLERequestContext& ctx); +    void SetPalmaFrModeType(Kernel::HLERequestContext& ctx); +    void ReadPalmaStep(Kernel::HLERequestContext& ctx); +    void EnablePalmaStep(Kernel::HLERequestContext& ctx); +    void ResetPalmaStep(Kernel::HLERequestContext& ctx); +    void ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx); +    void WritePalmaApplicationSection(Kernel::HLERequestContext& ctx); +    void ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx); +    void SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx); +    void WritePalmaActivityEntry(Kernel::HLERequestContext& ctx); +    void WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx); +    void WritePalmaWaveEntry(Kernel::HLERequestContext& ctx); +    void SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx); +    void GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx); +    void SuspendPalmaFeature(Kernel::HLERequestContext& ctx); +    void GetPalmaOperationResult(Kernel::HLERequestContext& ctx); +    void ReadPalmaPlayLog(Kernel::HLERequestContext& ctx); +    void ResetPalmaPlayLog(Kernel::HLERequestContext& ctx);      void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); +    void SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx); +    void PairPalma(Kernel::HLERequestContext& ctx);      void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); +    void CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx); +    void EnablePalmaBoostMode(Kernel::HLERequestContext& ctx); +    void GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx); +    void SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx);      void SetNpadCommunicationMode(Kernel::HLERequestContext& ctx);      void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx);      void SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx); | 
