aboutsummaryrefslogtreecommitdiff
path: root/src/hid_core/resources/applet_resource.h
blob: 4b7584b9623074b1884c7f87040c4861f2f08b8b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later

// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <array>
#include <mutex>
#include <memory>

#include "common/bit_field.h"
#include "common/common_types.h"
#include "core/hle/result.h"
#include "hid_core/resources/shared_memory_holder.h"

namespace Core {
class System;
} // namespace Core

namespace Kernel {
class KEvent;
class KSharedMemory;
} // namespace Kernel

namespace Service::HID {
struct SharedMemoryFormat;
class AppletResource;
class NPadResource;

static constexpr std::size_t AruidIndexMax = 0x20;
static constexpr u64 SystemAruid = 0;

enum class RegistrationStatus : u32 {
    None,
    Initialized,
    PendingDelete,
};

struct DataStatusFlag {
    union {
        u32 raw{};

        BitField<0, 1, u32> is_initialized;
        BitField<1, 1, u32> is_assigned;
        BitField<16, 1, u32> enable_pad_input;
        BitField<17, 1, u32> enable_six_axis_sensor;
        BitField<18, 1, u32> bit_18;
        BitField<19, 1, u32> is_palma_connectable;
        BitField<20, 1, u32> enable_palma_boost_mode;
        BitField<21, 1, u32> enable_touchscreen;
    };
};

struct AruidRegisterList {
    std::array<RegistrationStatus, AruidIndexMax> flag{};
    std::array<u64, AruidIndexMax> aruid{};
};
static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");

struct AruidData {
    DataStatusFlag flag{};
    u64 aruid{};
    SharedMemoryFormat* shared_memory_format{nullptr};
};

struct HandheldConfig {
    bool is_handheld_hid_enabled;
    bool is_force_handheld;
    bool is_joycon_rail_enabled;
    bool is_force_handheld_style_vibration;
};
static_assert(sizeof(HandheldConfig) == 0x4, "HandheldConfig is an invalid size");

struct AppletResourceHolder {
    std::shared_ptr<AppletResource> applet_resource{nullptr};
    std::recursive_mutex* shared_mutex{nullptr};
    NPadResource* shared_npad_resource{nullptr};
    std::shared_ptr<HandheldConfig> handheld_config{nullptr};
    Kernel::KEvent* input_event{nullptr};
    std::mutex* input_mutex{nullptr};
};

class AppletResource {
public:
    explicit AppletResource(Core::System& system_);
    ~AppletResource();

    Result CreateAppletResource(u64 aruid);

    Result RegisterAppletResourceUserId(u64 aruid, bool enable_input);
    void UnregisterAppletResourceUserId(u64 aruid);

    void FreeAppletResourceId(u64 aruid);

    u64 GetActiveAruid();
    Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
    Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid);
    AruidData* GetAruidData(u64 aruid);
    AruidData* GetAruidDataByIndex(std::size_t aruid_index);

    bool IsVibrationAruidActive(u64 aruid) const;

    u64 GetIndexFromAruid(u64 aruid);

    Result DestroySevenSixAxisTransferMemory();

    void EnableInput(u64 aruid, bool is_enabled);
    bool SetAruidValidForVibration(u64 aruid, bool is_enabled);
    void EnableSixAxisSensor(u64 aruid, bool is_enabled);
    void EnablePadInput(u64 aruid, bool is_enabled);
    void EnableTouchScreen(u64 aruid, bool is_enabled);
    void SetIsPalmaConnectable(u64 aruid, bool is_connectable);
    void EnablePalmaBoostMode(u64 aruid, bool is_enabled);

    Result RegisterCoreAppletResource();
    Result UnregisterCoreAppletResource();

private:
    u64 active_aruid{};
    AruidRegisterList registration_list{};
    std::array<AruidData, AruidIndexMax> data{};
    std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{};
    s32 ref_counter{};
    u64 active_vibration_aruid = 0;

    Core::System& system;
};
} // namespace Service::HID