diff options
Diffstat (limited to 'src/input_common/main.cpp')
| -rw-r--r-- | src/input_common/main.cpp | 290 |
1 files changed, 279 insertions, 11 deletions
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index da501b6cc..46ca6b76c 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp | |||
| @@ -4,54 +4,265 @@ | |||
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | #include <thread> | 6 | #include <thread> |
| 7 | #include "common/input.h" | ||
| 7 | #include "common/param_package.h" | 8 | #include "common/param_package.h" |
| 8 | #include "common/settings.h" | 9 | #include "input_common/drivers/gc_adapter.h" |
| 10 | #include "input_common/drivers/keyboard.h" | ||
| 11 | #include "input_common/drivers/mouse.h" | ||
| 12 | #include "input_common/drivers/tas_input.h" | ||
| 13 | #include "input_common/drivers/touch_screen.h" | ||
| 14 | #include "input_common/drivers/udp_client.h" | ||
| 15 | #include "input_common/helpers/stick_from_buttons.h" | ||
| 16 | #include "input_common/helpers/touch_from_buttons.h" | ||
| 17 | #include "input_common/input_engine.h" | ||
| 18 | #include "input_common/input_mapping.h" | ||
| 19 | #include "input_common/input_poller.h" | ||
| 9 | #include "input_common/main.h" | 20 | #include "input_common/main.h" |
| 10 | #ifdef HAVE_SDL2 | 21 | #ifdef HAVE_SDL2 |
| 11 | #include "input_common/sdl/sdl.h" | 22 | #include "input_common/drivers/sdl_driver.h" |
| 12 | #endif | 23 | #endif |
| 13 | 24 | ||
| 14 | namespace InputCommon { | 25 | namespace InputCommon { |
| 15 | 26 | ||
| 16 | struct InputSubsystem::Impl { | 27 | struct InputSubsystem::Impl { |
| 17 | void Initialize() { | 28 | void Initialize() { |
| 29 | mapping_factory = std::make_shared<MappingFactory>(); | ||
| 30 | MappingCallback mapping_callback{[this](MappingData data) { RegisterInput(data); }}; | ||
| 31 | |||
| 32 | keyboard = std::make_shared<Keyboard>("keyboard"); | ||
| 33 | keyboard->SetMappingCallback(mapping_callback); | ||
| 34 | keyboard_factory = std::make_shared<InputFactory>(keyboard); | ||
| 35 | Input::RegisterFactory<Input::InputDevice>(keyboard->GetEngineName(), keyboard_factory); | ||
| 36 | |||
| 37 | mouse = std::make_shared<Mouse>("mouse"); | ||
| 38 | mouse->SetMappingCallback(mapping_callback); | ||
| 39 | mouse_factory = std::make_shared<InputFactory>(mouse); | ||
| 40 | Input::RegisterFactory<Input::InputDevice>(mouse->GetEngineName(), mouse_factory); | ||
| 41 | |||
| 42 | touch_screen = std::make_shared<TouchScreen>("touch"); | ||
| 43 | touch_screen_factory = std::make_shared<InputFactory>(touch_screen); | ||
| 44 | Input::RegisterFactory<Input::InputDevice>(touch_screen->GetEngineName(), | ||
| 45 | touch_screen_factory); | ||
| 46 | |||
| 47 | gcadapter = std::make_shared<GCAdapter>("gcpad"); | ||
| 48 | gcadapter->SetMappingCallback(mapping_callback); | ||
| 49 | gcadapter_factory = std::make_shared<InputFactory>(gcadapter); | ||
| 50 | Input::RegisterFactory<Input::InputDevice>(gcadapter->GetEngineName(), gcadapter_factory); | ||
| 51 | |||
| 52 | udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp"); | ||
| 53 | udp_client->SetMappingCallback(mapping_callback); | ||
| 54 | udp_client_factory = std::make_shared<InputFactory>(udp_client); | ||
| 55 | Input::RegisterFactory<Input::InputDevice>(udp_client->GetEngineName(), udp_client_factory); | ||
| 56 | |||
| 57 | tas_input = std::make_shared<TasInput::Tas>("tas"); | ||
| 58 | tas_input->SetMappingCallback(mapping_callback); | ||
| 59 | tas_input_factory = std::make_shared<InputFactory>(tas_input); | ||
| 60 | Input::RegisterFactory<Input::InputDevice>(tas_input->GetEngineName(), tas_input_factory); | ||
| 61 | |||
| 62 | #ifdef HAVE_SDL2 | ||
| 63 | sdl = std::make_shared<SDLDriver>("sdl"); | ||
| 64 | sdl->SetMappingCallback(mapping_callback); | ||
| 65 | sdl_factory = std::make_shared<InputFactory>(sdl); | ||
| 66 | Input::RegisterFactory<Input::InputDevice>(sdl->GetEngineName(), sdl_factory); | ||
| 67 | #endif | ||
| 68 | |||
| 69 | Input::RegisterFactory<Input::InputDevice>("touch_from_button", | ||
| 70 | std::make_shared<TouchFromButton>()); | ||
| 71 | Input::RegisterFactory<Input::InputDevice>("analog_from_button", | ||
| 72 | std::make_shared<StickFromButton>()); | ||
| 18 | } | 73 | } |
| 19 | 74 | ||
| 20 | void Shutdown() { | 75 | void Shutdown() { |
| 76 | Input::UnregisterFactory<Input::InputDevice>(keyboard->GetEngineName()); | ||
| 77 | keyboard.reset(); | ||
| 78 | |||
| 79 | Input::UnregisterFactory<Input::InputDevice>(mouse->GetEngineName()); | ||
| 80 | mouse.reset(); | ||
| 81 | |||
| 82 | Input::UnregisterFactory<Input::InputDevice>(touch_screen->GetEngineName()); | ||
| 83 | touch_screen.reset(); | ||
| 84 | |||
| 85 | Input::UnregisterFactory<Input::InputDevice>(gcadapter->GetEngineName()); | ||
| 86 | gcadapter.reset(); | ||
| 87 | |||
| 88 | Input::UnregisterFactory<Input::InputDevice>(udp_client->GetEngineName()); | ||
| 89 | udp_client.reset(); | ||
| 90 | |||
| 91 | Input::UnregisterFactory<Input::InputDevice>(tas_input->GetEngineName()); | ||
| 92 | tas_input.reset(); | ||
| 93 | |||
| 94 | #ifdef HAVE_SDL2 | ||
| 95 | Input::UnregisterFactory<Input::InputDevice>(sdl->GetEngineName()); | ||
| 96 | sdl.reset(); | ||
| 97 | #endif | ||
| 98 | |||
| 99 | Input::UnregisterFactory<Input::InputDevice>("touch_from_button"); | ||
| 100 | Input::UnregisterFactory<Input::InputDevice>("analog_from_button"); | ||
| 21 | } | 101 | } |
| 22 | 102 | ||
| 23 | [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { | 103 | [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { |
| 24 | std::vector<Common::ParamPackage> devices = { | 104 | std::vector<Common::ParamPackage> devices = { |
| 25 | Common::ParamPackage{{"display", "Any"}, {"class", "any"}}, | 105 | Common::ParamPackage{{"display", "Any"}, {"engine", "any"}}, |
| 26 | Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "keyboard"}}, | ||
| 27 | }; | 106 | }; |
| 28 | return {}; | 107 | |
| 108 | auto keyboard_devices = keyboard->GetInputDevices(); | ||
| 109 | devices.insert(devices.end(), keyboard_devices.begin(), keyboard_devices.end()); | ||
| 110 | auto mouse_devices = mouse->GetInputDevices(); | ||
| 111 | devices.insert(devices.end(), mouse_devices.begin(), mouse_devices.end()); | ||
| 112 | auto gcadapter_devices = gcadapter->GetInputDevices(); | ||
| 113 | devices.insert(devices.end(), gcadapter_devices.begin(), gcadapter_devices.end()); | ||
| 114 | auto tas_input_devices = tas_input->GetInputDevices(); | ||
| 115 | devices.insert(devices.end(), tas_input_devices.begin(), tas_input_devices.end()); | ||
| 116 | #ifdef HAVE_SDL2 | ||
| 117 | auto sdl_devices = sdl->GetInputDevices(); | ||
| 118 | devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end()); | ||
| 119 | #endif | ||
| 120 | |||
| 121 | return devices; | ||
| 29 | } | 122 | } |
| 30 | 123 | ||
| 31 | [[nodiscard]] AnalogMapping GetAnalogMappingForDevice( | 124 | [[nodiscard]] AnalogMapping GetAnalogMappingForDevice( |
| 32 | const Common::ParamPackage& params) const { | 125 | const Common::ParamPackage& params) const { |
| 33 | if (!params.Has("class") || params.Get("class", "") == "any") { | 126 | if (!params.Has("engine") || params.Get("engine", "") == "any") { |
| 34 | return {}; | 127 | return {}; |
| 35 | } | 128 | } |
| 129 | const std::string engine = params.Get("engine", ""); | ||
| 130 | if (engine == gcadapter->GetEngineName()) { | ||
| 131 | return gcadapter->GetAnalogMappingForDevice(params); | ||
| 132 | } | ||
| 133 | if (engine == tas_input->GetEngineName()) { | ||
| 134 | return tas_input->GetAnalogMappingForDevice(params); | ||
| 135 | } | ||
| 136 | #ifdef HAVE_SDL2 | ||
| 137 | if (engine == sdl->GetEngineName()) { | ||
| 138 | return sdl->GetAnalogMappingForDevice(params); | ||
| 139 | } | ||
| 140 | #endif | ||
| 36 | return {}; | 141 | return {}; |
| 37 | } | 142 | } |
| 38 | 143 | ||
| 39 | [[nodiscard]] ButtonMapping GetButtonMappingForDevice( | 144 | [[nodiscard]] ButtonMapping GetButtonMappingForDevice( |
| 40 | const Common::ParamPackage& params) const { | 145 | const Common::ParamPackage& params) const { |
| 41 | if (!params.Has("class") || params.Get("class", "") == "any") { | 146 | if (!params.Has("engine") || params.Get("engine", "") == "any") { |
| 42 | return {}; | 147 | return {}; |
| 43 | } | 148 | } |
| 149 | const std::string engine = params.Get("engine", ""); | ||
| 150 | if (engine == gcadapter->GetEngineName()) { | ||
| 151 | return gcadapter->GetButtonMappingForDevice(params); | ||
| 152 | } | ||
| 153 | if (engine == tas_input->GetEngineName()) { | ||
| 154 | return tas_input->GetButtonMappingForDevice(params); | ||
| 155 | } | ||
| 156 | #ifdef HAVE_SDL2 | ||
| 157 | if (engine == sdl->GetEngineName()) { | ||
| 158 | return sdl->GetButtonMappingForDevice(params); | ||
| 159 | } | ||
| 160 | #endif | ||
| 44 | return {}; | 161 | return {}; |
| 45 | } | 162 | } |
| 46 | 163 | ||
| 47 | [[nodiscard]] MotionMapping GetMotionMappingForDevice( | 164 | [[nodiscard]] MotionMapping GetMotionMappingForDevice( |
| 48 | const Common::ParamPackage& params) const { | 165 | const Common::ParamPackage& params) const { |
| 49 | if (!params.Has("class") || params.Get("class", "") == "any") { | 166 | if (!params.Has("engine") || params.Get("engine", "") == "any") { |
| 50 | return {}; | 167 | return {}; |
| 51 | } | 168 | } |
| 169 | const std::string engine = params.Get("engine", ""); | ||
| 170 | if (engine == gcadapter->GetEngineName()) { | ||
| 171 | return gcadapter->GetMotionMappingForDevice(params); | ||
| 172 | } | ||
| 173 | #ifdef HAVE_SDL2 | ||
| 174 | if (engine == sdl->GetEngineName()) { | ||
| 175 | return sdl->GetMotionMappingForDevice(params); | ||
| 176 | } | ||
| 177 | #endif | ||
| 52 | return {}; | 178 | return {}; |
| 53 | } | 179 | } |
| 54 | 180 | ||
| 181 | std::string GetButtonName(const Common::ParamPackage& params) const { | ||
| 182 | if (!params.Has("engine") || params.Get("engine", "") == "any") { | ||
| 183 | return "Unknown"; | ||
| 184 | } | ||
| 185 | const std::string engine = params.Get("engine", ""); | ||
| 186 | if (engine == mouse->GetEngineName()) { | ||
| 187 | return mouse->GetUIName(params); | ||
| 188 | } | ||
| 189 | if (engine == gcadapter->GetEngineName()) { | ||
| 190 | return gcadapter->GetUIName(params); | ||
| 191 | } | ||
| 192 | if (engine == udp_client->GetEngineName()) { | ||
| 193 | return udp_client->GetUIName(params); | ||
| 194 | } | ||
| 195 | if (engine == tas_input->GetEngineName()) { | ||
| 196 | return tas_input->GetUIName(params); | ||
| 197 | } | ||
| 198 | #ifdef HAVE_SDL2 | ||
| 199 | if (engine == sdl->GetEngineName()) { | ||
| 200 | return sdl->GetUIName(params); | ||
| 201 | } | ||
| 202 | #endif | ||
| 203 | return "Bad engine"; | ||
| 204 | } | ||
| 205 | |||
| 206 | bool IsController(const Common::ParamPackage& params) { | ||
| 207 | const std::string engine = params.Get("engine", ""); | ||
| 208 | if (engine == mouse->GetEngineName()) { | ||
| 209 | return true; | ||
| 210 | } | ||
| 211 | if (engine == gcadapter->GetEngineName()) { | ||
| 212 | return true; | ||
| 213 | } | ||
| 214 | if (engine == tas_input->GetEngineName()) { | ||
| 215 | return true; | ||
| 216 | } | ||
| 217 | #ifdef HAVE_SDL2 | ||
| 218 | if (engine == sdl->GetEngineName()) { | ||
| 219 | return true; | ||
| 220 | } | ||
| 221 | #endif | ||
| 222 | return false; | ||
| 223 | } | ||
| 224 | |||
| 225 | void BeginConfiguration() { | ||
| 226 | keyboard->BeginConfiguration(); | ||
| 227 | mouse->BeginConfiguration(); | ||
| 228 | gcadapter->BeginConfiguration(); | ||
| 229 | udp_client->BeginConfiguration(); | ||
| 230 | #ifdef HAVE_SDL2 | ||
| 231 | sdl->BeginConfiguration(); | ||
| 232 | #endif | ||
| 233 | } | ||
| 234 | |||
| 235 | void EndConfiguration() { | ||
| 236 | keyboard->EndConfiguration(); | ||
| 237 | mouse->EndConfiguration(); | ||
| 238 | gcadapter->EndConfiguration(); | ||
| 239 | udp_client->EndConfiguration(); | ||
| 240 | #ifdef HAVE_SDL2 | ||
| 241 | sdl->EndConfiguration(); | ||
| 242 | #endif | ||
| 243 | } | ||
| 244 | |||
| 245 | void RegisterInput(MappingData data) { | ||
| 246 | mapping_factory->RegisterInput(data); | ||
| 247 | } | ||
| 248 | |||
| 249 | std::shared_ptr<MappingFactory> mapping_factory; | ||
| 250 | std::shared_ptr<Keyboard> keyboard; | ||
| 251 | std::shared_ptr<InputFactory> keyboard_factory; | ||
| 252 | std::shared_ptr<Mouse> mouse; | ||
| 253 | std::shared_ptr<InputFactory> mouse_factory; | ||
| 254 | std::shared_ptr<GCAdapter> gcadapter; | ||
| 255 | std::shared_ptr<InputFactory> gcadapter_factory; | ||
| 256 | std::shared_ptr<TouchScreen> touch_screen; | ||
| 257 | std::shared_ptr<InputFactory> touch_screen_factory; | ||
| 258 | std::shared_ptr<CemuhookUDP::UDPClient> udp_client; | ||
| 259 | std::shared_ptr<InputFactory> udp_client_factory; | ||
| 260 | std::shared_ptr<TasInput::Tas> tas_input; | ||
| 261 | std::shared_ptr<InputFactory> tas_input_factory; | ||
| 262 | #ifdef HAVE_SDL2 | ||
| 263 | std::shared_ptr<SDLDriver> sdl; | ||
| 264 | std::shared_ptr<InputFactory> sdl_factory; | ||
| 265 | #endif | ||
| 55 | }; | 266 | }; |
| 56 | 267 | ||
| 57 | InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {} | 268 | InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {} |
| @@ -66,6 +277,38 @@ void InputSubsystem::Shutdown() { | |||
| 66 | impl->Shutdown(); | 277 | impl->Shutdown(); |
| 67 | } | 278 | } |
| 68 | 279 | ||
| 280 | Keyboard* InputSubsystem::GetKeyboard() { | ||
| 281 | return impl->keyboard.get(); | ||
| 282 | } | ||
| 283 | |||
| 284 | const Keyboard* InputSubsystem::GetKeyboard() const { | ||
| 285 | return impl->keyboard.get(); | ||
| 286 | } | ||
| 287 | |||
| 288 | Mouse* InputSubsystem::GetMouse() { | ||
| 289 | return impl->mouse.get(); | ||
| 290 | } | ||
| 291 | |||
| 292 | const Mouse* InputSubsystem::GetMouse() const { | ||
| 293 | return impl->mouse.get(); | ||
| 294 | } | ||
| 295 | |||
| 296 | TouchScreen* InputSubsystem::GetTouchScreen() { | ||
| 297 | return impl->touch_screen.get(); | ||
| 298 | } | ||
| 299 | |||
| 300 | const TouchScreen* InputSubsystem::GetTouchScreen() const { | ||
| 301 | return impl->touch_screen.get(); | ||
| 302 | } | ||
| 303 | |||
| 304 | TasInput::Tas* InputSubsystem::GetTas() { | ||
| 305 | return impl->tas_input.get(); | ||
| 306 | } | ||
| 307 | |||
| 308 | const TasInput::Tas* InputSubsystem::GetTas() const { | ||
| 309 | return impl->tas_input.get(); | ||
| 310 | } | ||
| 311 | |||
| 69 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { | 312 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { |
| 70 | return impl->GetInputDevices(); | 313 | return impl->GetInputDevices(); |
| 71 | } | 314 | } |
| @@ -82,12 +325,37 @@ MotionMapping InputSubsystem::GetMotionMappingForDevice(const Common::ParamPacka | |||
| 82 | return impl->GetMotionMappingForDevice(device); | 325 | return impl->GetMotionMappingForDevice(device); |
| 83 | } | 326 | } |
| 84 | 327 | ||
| 328 | std::string InputSubsystem::GetButtonName(const Common::ParamPackage& params) const { | ||
| 329 | const std::string toggle = params.Get("toggle", false) ? "~" : ""; | ||
| 330 | const std::string inverted = params.Get("inverted", false) ? "!" : ""; | ||
| 331 | const std::string button_name = impl->GetButtonName(params); | ||
| 332 | std::string axis_direction = ""; | ||
| 333 | if (params.Has("axis")) { | ||
| 334 | axis_direction = params.Get("invert", "+"); | ||
| 335 | } | ||
| 336 | return fmt::format("{}{}{}{}", toggle, inverted, button_name, axis_direction); | ||
| 337 | } | ||
| 338 | |||
| 339 | bool InputSubsystem::IsController(const Common::ParamPackage& params) const { | ||
| 340 | return impl->IsController(params); | ||
| 341 | } | ||
| 342 | |||
| 85 | void InputSubsystem::ReloadInputDevices() { | 343 | void InputSubsystem::ReloadInputDevices() { |
| 344 | impl->udp_client.get()->ReloadSockets(); | ||
| 345 | } | ||
| 346 | |||
| 347 | void InputSubsystem::BeginMapping(Polling::InputType type) { | ||
| 348 | impl->BeginConfiguration(); | ||
| 349 | impl->mapping_factory->BeginMapping(type); | ||
| 350 | } | ||
| 351 | |||
| 352 | const Common::ParamPackage InputSubsystem::GetNextInput() const { | ||
| 353 | return impl->mapping_factory->GetNextInput(); | ||
| 86 | } | 354 | } |
| 87 | 355 | ||
| 88 | std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers([ | 356 | void InputSubsystem::StopMapping() const { |
| 89 | [maybe_unused]] Polling::DeviceType type) const { | 357 | impl->EndConfiguration(); |
| 90 | return {}; | 358 | impl->mapping_factory->StopMapping(); |
| 91 | } | 359 | } |
| 92 | 360 | ||
| 93 | std::string GenerateKeyboardParam(int key_code) { | 361 | std::string GenerateKeyboardParam(int key_code) { |