summaryrefslogtreecommitdiffstats
path: root/src/core/hid/emulated_devices.h
blob: d4f4576511538f6a0387ac96232cc17a3fb31cc8 (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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <array>
#include <functional>
#include <memory>
#include <mutex>
#include <unordered_map>

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

namespace Core::HID {
using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
                                   Settings::NativeKeyboard::NumKeyboardKeys>;
using KeyboardModifierDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
                                           Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
                                      Settings::NativeMouseButton::NumMouseButtons>;
using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
                                      Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;

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

using KeyboardValues =
    std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>;
using KeyboardModifierValues =
    std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonValues =
    std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;
using MouseAnalogValues =
    std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickValue = Common::Input::TouchStatus;

struct MousePosition {
    f32 x;
    f32 y;
};

struct DeviceStatus {
    // Data from input_common
    KeyboardValues keyboard_values{};
    KeyboardModifierValues keyboard_moddifier_values{};
    MouseButtonValues mouse_button_values{};
    MouseAnalogValues mouse_analog_values{};
    MouseStickValue mouse_stick_value{};

    // Data for HID serices
    KeyboardKey keyboard_state{};
    KeyboardModifier keyboard_moddifier_state{};
    MouseButton mouse_button_state{};
    MousePosition mouse_position_state{};
    AnalogStickState mouse_wheel_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
     * This includes devices such as the keyboard or mouse
     */
    EmulatedDevices();
    ~EmulatedDevices();

    YUZU_NON_COPYABLE(EmulatedDevices);
    YUZU_NON_MOVEABLE(EmulatedDevices);

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

    /**
     * Sets the emulated devices into configuring mode
     * This prevents the modification of the HID state of the emulated devices by input commands
     */
    void EnableConfiguration();

    /// Returns the emulated devices into normal mode, allowing the modification of the HID state
    void DisableConfiguration();

    /// Returns true if the emulated device is in 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 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;

    /// Returns the latest mouse wheel change
    AnalogStickState GetMouseWheel() const;

    /**
     * Adds a callback to the list of events
     * @param update_callback InterfaceUpdateCallback 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 Key corresponding to the callback index in the list
     */
    void DeleteCallback(int key);

private:
    /// Helps assigning a value to keyboard_state
    void UpdateKey(std::size_t key_index, bool status);

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

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

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

    /**
     * Updates the mouse wheel status of the mouse device
     * @param callback A CallbackStatus containing the wheel status
     * @param index wheel ID to be updated
     */
    void SetMouseAnalog(Common::Input::CallbackStatus callback, std::size_t index);

    /**
     * Updates the mouse position status of the mouse device
     * @param callback A CallbackStatus containing the position status
     * @param index stick ID to be updated
     */
    void SetMouseStick(Common::Input::CallbackStatus callback);

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

    bool is_configuring{false};

    KeyboardDevices keyboard_devices;
    KeyboardModifierDevices keyboard_modifier_devices;
    MouseButtonDevices mouse_button_devices;
    MouseAnalogDevices mouse_analog_devices;
    MouseStickDevice mouse_stick_device;

    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