summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar german772021-09-20 14:56:55 -0500
committerGravatar Narr the Reg2021-11-24 20:30:21 -0600
commitad5142ac2c56aded4090ad031a9351cd188caacf (patch)
treeeaeb52b401faa303192c65e0ab994c9b61ba9b06 /src
parentRefactor menu states and shortcuts in GMainWindow. (#7419) (diff)
downloadyuzu-ad5142ac2c56aded4090ad031a9351cd188caacf.tar.gz
yuzu-ad5142ac2c56aded4090ad031a9351cd188caacf.tar.xz
yuzu-ad5142ac2c56aded4090ad031a9351cd188caacf.zip
common: Rewrite and move core/frontend/input.h to common
Diffstat (limited to '')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/input.h242
2 files changed, 243 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 23d43a394..919da4a53 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -73,6 +73,7 @@ add_library(common STATIC
73 hex_util.h 73 hex_util.h
74 host_memory.cpp 74 host_memory.cpp
75 host_memory.h 75 host_memory.h
76 input.h
76 intrusive_red_black_tree.h 77 intrusive_red_black_tree.h
77 literals.h 78 literals.h
78 logging/backend.cpp 79 logging/backend.cpp
diff --git a/src/common/input.h b/src/common/input.h
new file mode 100644
index 000000000..6eefc55f9
--- /dev/null
+++ b/src/common/input.h
@@ -0,0 +1,242 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <functional>
8#include <memory>
9#include <string>
10#include <unordered_map>
11#include <utility>
12#include "common/logging/log.h"
13#include "common/param_package.h"
14
15namespace Input {
16
17enum class InputType {
18 None,
19 Battery,
20 Button,
21 Stick,
22 Analog,
23 Trigger,
24 Motion,
25 Touch,
26 Color,
27 Vibration,
28 Nfc,
29 Ir,
30};
31
32enum class BatteryLevel {
33 Empty,
34 Critical,
35 Low,
36 Medium,
37 Full,
38 Charging,
39};
40
41struct AnalogProperties {
42 float deadzone{};
43 float range{1.0f};
44 float threshold{0.5f};
45 float offset{};
46 bool inverted{};
47};
48
49struct AnalogStatus {
50 float value{};
51 float raw_value{};
52 AnalogProperties properties{};
53};
54
55struct ButtonStatus {
56 bool value{};
57 bool inverted{};
58 bool toggle{};
59 bool locked{};
60};
61
62using BatteryStatus = BatteryLevel;
63
64struct StickStatus {
65 AnalogStatus x{};
66 AnalogStatus y{};
67 bool left{};
68 bool right{};
69 bool up{};
70 bool down{};
71};
72
73struct TriggerStatus {
74 AnalogStatus analog{};
75 bool pressed{};
76};
77
78struct MotionSensor {
79 AnalogStatus x{};
80 AnalogStatus y{};
81 AnalogStatus z{};
82};
83
84struct MotionStatus {
85 MotionSensor gyro{};
86 MotionSensor accel{};
87 u64 delta_timestamp{};
88};
89
90struct TouchStatus {
91 ButtonStatus pressed{};
92 AnalogStatus x{};
93 AnalogStatus y{};
94 u32 id{};
95};
96
97struct BodyColorStatus {
98 u32 body{};
99 u32 buttons{};
100};
101
102struct VibrationStatus {
103 f32 low_amplitude{};
104 f32 low_frequency{};
105 f32 high_amplitude{};
106 f32 high_frequency{};
107};
108
109struct LedStatus {
110 bool led_1{};
111 bool led_2{};
112 bool led_3{};
113 bool led_4{};
114};
115
116struct CallbackStatus {
117 InputType type{InputType::None};
118 ButtonStatus button_status{};
119 StickStatus stick_status{};
120 AnalogStatus analog_status{};
121 TriggerStatus trigger_status{};
122 MotionStatus motion_status{};
123 TouchStatus touch_status{};
124 BodyColorStatus color_status{};
125 BatteryStatus battery_status{};
126 VibrationStatus vibration_status{};
127};
128
129struct InputCallback {
130 std::function<void(CallbackStatus)> on_change;
131};
132
133/// An abstract class template for an input device (a button, an analog input, etc.).
134class InputDevice {
135public:
136 virtual ~InputDevice() = default;
137
138 void SetCallback(InputCallback callback_) {
139 callback = std::move(callback_);
140 }
141
142 void TriggerOnChange(CallbackStatus status) {
143 if (callback.on_change) {
144 callback.on_change(status);
145 }
146 }
147
148private:
149 InputCallback callback;
150};
151
152/// An abstract class template for a factory that can create input devices.
153template <typename InputDeviceType>
154class Factory {
155public:
156 virtual ~Factory() = default;
157 virtual std::unique_ptr<InputDeviceType> Create(const Common::ParamPackage&) = 0;
158};
159
160namespace Impl {
161
162template <typename InputDeviceType>
163using FactoryListType = std::unordered_map<std::string, std::shared_ptr<Factory<InputDeviceType>>>;
164
165template <typename InputDeviceType>
166struct FactoryList {
167 static FactoryListType<InputDeviceType> list;
168};
169
170template <typename InputDeviceType>
171FactoryListType<InputDeviceType> FactoryList<InputDeviceType>::list;
172
173} // namespace Impl
174
175/**
176 * Registers an input device factory.
177 * @tparam InputDeviceType the type of input devices the factory can create
178 * @param name the name of the factory. Will be used to match the "engine" parameter when creating
179 * a device
180 * @param factory the factory object to register
181 */
182template <typename InputDeviceType>
183void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) {
184 auto pair = std::make_pair(name, std::move(factory));
185 if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) {
186 LOG_ERROR(Input, "Factory '{}' already registered", name);
187 }
188}
189
190/**
191 * Unregisters an input device factory.
192 * @tparam InputDeviceType the type of input devices the factory can create
193 * @param name the name of the factory to unregister
194 */
195template <typename InputDeviceType>
196void UnregisterFactory(const std::string& name) {
197 if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) {
198 LOG_ERROR(Input, "Factory '{}' not registered", name);
199 }
200}
201
202/**
203 * Create an input device from given paramters.
204 * @tparam InputDeviceType the type of input devices to create
205 * @param params a serialized ParamPackage string that contains all parameters for creating the
206 * device
207 */
208template <typename InputDeviceType>
209std::unique_ptr<InputDeviceType> CreateDeviceFromString(const std::string& params) {
210 const Common::ParamPackage package(params);
211 const std::string engine = package.Get("engine", "null");
212 const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
213 const auto pair = factory_list.find(engine);
214 if (pair == factory_list.end()) {
215 if (engine != "null") {
216 LOG_ERROR(Input, "Unknown engine name: {}", engine);
217 }
218 return std::make_unique<InputDeviceType>();
219 }
220 return pair->second->Create(package);
221}
222
223/**
224 * Create an input device from given paramters.
225 * @tparam InputDeviceType the type of input devices to create
226 * @param A ParamPackage that contains all parameters for creating the device
227 */
228template <typename InputDeviceType>
229std::unique_ptr<InputDeviceType> CreateDevice(const Common::ParamPackage package) {
230 const std::string engine = package.Get("engine", "null");
231 const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
232 const auto pair = factory_list.find(engine);
233 if (pair == factory_list.end()) {
234 if (engine != "null") {
235 LOG_ERROR(Input, "Unknown engine name: {}", engine);
236 }
237 return std::make_unique<InputDeviceType>();
238 }
239 return pair->second->Create(package);
240}
241
242} // namespace Input