summaryrefslogtreecommitdiffstats
path: root/src/core/hid/emulated_devices.h
blob: c6c19fae4ea624c79227e4d90dfe27da8225a10e (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <functional>
#include <mutex>
#include <unordered_map>

#include "common/input.h"
#include "common/param_package.h"
#include "common/settings.h"
#include "core/hid/hid_types.h"
#include "core/hid/motion_input.h"

namespace Core::HID {

using KeyboardDevices =
    std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeKeyboard::NumKeyboardKeys>;
using KeyboardModifierDevices =
    std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonDevices =
    std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeMouseButton::NumMouseButtons>;

using MouseButtonParams =
    std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>;

using KeyboardValues = std::array<Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>;
using KeyboardModifierValues =
    std::array<Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonValues =
    std::array<Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;

struct MousePosition {
    s32 x;
    s32 y;
    s32 delta_wheel_x;
    s32 delta_wheel_y;
};

struct DeviceStatus {
    // Data from input_common
    KeyboardValues keyboard_values{};
    KeyboardModifierValues keyboard_moddifier_values{};
    MouseButtonValues mouse_button_values{};

    // Data for HID serices
    KeyboardKey keyboard_state{};
    KeyboardModifier keyboard_moddifier_state{};
    MouseButton mouse_button_state{};
    MousePosition mouse_position_state{};
};

enum class DeviceTriggerType {
    Keyboard,
    KeyboardModdifier,
    Mouse,
};

struct InterfaceUpdateCallback {
    std::function<void(DeviceTriggerType)> on_change;
};

class EmulatedDevices {
public:
    /**
     * Contains all input data related to external devices that aren't necesarily a controller
     * like keyboard and mouse
     */
    EmulatedDevices();
    ~EmulatedDevices();

    YUZU_NON_COPYABLE(EmulatedDevices);
    YUZU_NON_MOVEABLE(EmulatedDevices);

    /// Removes all callbacks created from input devices
    void UnloadInput();

    /// Sets the emulated console into configuring mode. Locking all HID service events from being
    /// moddified
    void EnableConfiguration();

    /// Returns the emulated console to the normal behaivour
    void DisableConfiguration();

    /// Returns true if the emulated device is on configuring mode
    bool IsConfiguring() const;

    /// Reload all input devices
    void ReloadInput();

    /// Overrides current mapped devices with the stored configuration and reloads all input devices
    void ReloadFromSettings();

    /// Saves the current mapped configuration
    void SaveCurrentConfig();

    /// Reverts any mapped changes made that weren't saved
    void RestoreConfig();

    /// Returns the current mapped motion device
    Common::ParamPackage GetMouseButtonParam(std::size_t index) const;

    /**
     * Updates the current mapped mouse button device
     * @param ParamPackage with controller data to be mapped
     */
    void SetMouseButtonParam(std::size_t index, Common::ParamPackage param);

    /// Returns the latest status of button input from the keyboard with parameters
    KeyboardValues GetKeyboardValues() const;

    /// Returns the latest status of button input from the keyboard modifiers with parameters
    KeyboardModifierValues GetKeyboardModdifierValues() const;

    /// Returns the latest status of button input from the mouse with parameters
    MouseButtonValues GetMouseButtonsValues() const;

    /// Returns the latest status of button input from the keyboard
    KeyboardKey GetKeyboard() const;

    /// Returns the latest status of button input from the keyboard modifiers
    KeyboardModifier GetKeyboardModifier() const;

    /// Returns the latest status of button input from the mouse
    MouseButton GetMouseButtons() const;

    /// Returns the latest mouse coordinates
    MousePosition GetMousePosition() const;

    /**
     * Adds a callback to the list of events
     * @param ConsoleUpdateCallback that will be triggered
     * @return an unique key corresponding to the callback index in the list
     */
    int SetCallback(InterfaceUpdateCallback update_callback);

    /**
     * Removes a callback from the list stopping any future events to this object
     * @param Key corresponding to the callback index in the list
     */
    void DeleteCallback(int key);

private:
    /**
     * Updates the touch status of the console
     * @param callback: A CallbackStatus containing the key status
     * @param index: key ID to be updated
     */
    void SetKeyboardButton(Input::CallbackStatus callback, std::size_t index);

    /**
     * Updates the touch status of the console
     * @param callback: A CallbackStatus containing the modifier key status
     * @param index: modifier key ID to be updated
     */
    void SetKeyboardModifier(Input::CallbackStatus callback, std::size_t index);

    /**
     * Updates the touch status of the console
     * @param callback: A CallbackStatus containing the button status
     * @param index: Button ID of the to be updated
     */
    void SetMouseButton(Input::CallbackStatus callback, std::size_t index);

    /**
     * Triggers a callback that something has changed on the device status
     * @param Input type of the event to trigger
     */
    void TriggerOnChange(DeviceTriggerType type);

    bool is_configuring{false};

    MouseButtonParams mouse_button_params;

    KeyboardDevices keyboard_devices;
    KeyboardModifierDevices keyboard_modifier_devices;
    MouseButtonDevices mouse_button_devices;

    mutable std::mutex mutex;
    std::unordered_map<int, InterfaceUpdateCallback> callback_list;
    int last_callback_key = 0;

    // Stores the current status of all external device input
    DeviceStatus device_status;
};

} // namespace Core::HID