diff options
Diffstat (limited to '')
-rw-r--r-- | src/input_common/main.cpp | 250 | ||||
-rw-r--r-- | src/input_common/main.h | 130 |
2 files changed, 227 insertions, 153 deletions
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index 8e67a7437..57e7a25fe 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp @@ -18,66 +18,166 @@ namespace InputCommon { -static std::shared_ptr<Keyboard> keyboard; -static std::shared_ptr<MotionEmu> motion_emu; +struct InputSubsystem::Impl { + void Initialize() { + auto gcadapter = std::make_shared<GCAdapter::Adapter>(); + gcbuttons = std::make_shared<GCButtonFactory>(gcadapter); + Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons); + gcanalog = std::make_shared<GCAnalogFactory>(gcadapter); + Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog); + + keyboard = std::make_shared<Keyboard>(); + Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); + Input::RegisterFactory<Input::AnalogDevice>("analog_from_button", + std::make_shared<AnalogFromButton>()); + motion_emu = std::make_shared<MotionEmu>(); + Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu); + #ifdef HAVE_SDL2 -static std::unique_ptr<SDL::State> sdl; + sdl = SDL::Init(); #endif -static std::unique_ptr<CemuhookUDP::State> udp; -static std::shared_ptr<GCButtonFactory> gcbuttons; -static std::shared_ptr<GCAnalogFactory> gcanalog; - -void Init() { - auto gcadapter = std::make_shared<GCAdapter::Adapter>(); - gcbuttons = std::make_shared<GCButtonFactory>(gcadapter); - Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons); - gcanalog = std::make_shared<GCAnalogFactory>(gcadapter); - Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog); - - keyboard = std::make_shared<Keyboard>(); - Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); - Input::RegisterFactory<Input::AnalogDevice>("analog_from_button", - std::make_shared<AnalogFromButton>()); - motion_emu = std::make_shared<MotionEmu>(); - Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu); + udp = CemuhookUDP::Init(); + } + + void Shutdown() { + Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); + keyboard.reset(); + Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); + Input::UnregisterFactory<Input::MotionDevice>("motion_emu"); + motion_emu.reset(); #ifdef HAVE_SDL2 - sdl = SDL::Init(); + sdl.reset(); #endif - udp = CemuhookUDP::Init(); -} + udp.reset(); + Input::UnregisterFactory<Input::ButtonDevice>("gcpad"); + Input::UnregisterFactory<Input::AnalogDevice>("gcpad"); + + gcbuttons.reset(); + gcanalog.reset(); + } + + [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { + std::vector<Common::ParamPackage> devices = { + Common::ParamPackage{{"display", "Any"}, {"class", "any"}}, + Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}}, + }; +#ifdef HAVE_SDL2 + auto sdl_devices = sdl->GetInputDevices(); + devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end()); +#endif + auto udp_devices = udp->GetInputDevices(); + devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); + return devices; + } + + [[nodiscard]] AnalogMapping GetAnalogMappingForDevice( + const Common::ParamPackage& params) const { + if (!params.Has("class") || params.Get("class", "") == "any") { + return {}; + } + if (params.Get("class", "") == "key") { + // TODO consider returning the SDL key codes for the default keybindings + return {}; + } +#ifdef HAVE_SDL2 + if (params.Get("class", "") == "sdl") { + return sdl->GetAnalogMappingForDevice(params); + } +#endif + return {}; + } + + [[nodiscard]] ButtonMapping GetButtonMappingForDevice( + const Common::ParamPackage& params) const { + if (!params.Has("class") || params.Get("class", "") == "any") { + return {}; + } + if (params.Get("class", "") == "key") { + // TODO consider returning the SDL key codes for the default keybindings + return {}; + } +#ifdef HAVE_SDL2 + if (params.Get("class", "") == "sdl") { + return sdl->GetButtonMappingForDevice(params); + } +#endif + return {}; + } -void Shutdown() { - Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); - keyboard.reset(); - Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); - Input::UnregisterFactory<Input::MotionDevice>("motion_emu"); - motion_emu.reset(); + std::shared_ptr<Keyboard> keyboard; + std::shared_ptr<MotionEmu> motion_emu; #ifdef HAVE_SDL2 - sdl.reset(); + std::unique_ptr<SDL::State> sdl; #endif - udp.reset(); - Input::UnregisterFactory<Input::ButtonDevice>("gcpad"); - Input::UnregisterFactory<Input::AnalogDevice>("gcpad"); + std::unique_ptr<CemuhookUDP::State> udp; + std::shared_ptr<GCButtonFactory> gcbuttons; + std::shared_ptr<GCAnalogFactory> gcanalog; +}; + +InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {} + +InputSubsystem::~InputSubsystem() = default; + +void InputSubsystem::Initialize() { + impl->Initialize(); +} + +void InputSubsystem::Shutdown() { + impl->Shutdown(); +} + +Keyboard* InputSubsystem::GetKeyboard() { + return impl->keyboard.get(); +} + +const Keyboard* InputSubsystem::GetKeyboard() const { + return impl->keyboard.get(); +} + +MotionEmu* InputSubsystem::GetMotionEmu() { + return impl->motion_emu.get(); +} + +const MotionEmu* InputSubsystem::GetMotionEmu() const { + return impl->motion_emu.get(); +} + +std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { + return impl->GetInputDevices(); +} + +AnalogMapping InputSubsystem::GetAnalogMappingForDevice(const Common::ParamPackage& device) const { + return impl->GetAnalogMappingForDevice(device); +} - gcbuttons.reset(); - gcanalog.reset(); +ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPackage& device) const { + return impl->GetButtonMappingForDevice(device); } -Keyboard* GetKeyboard() { - return keyboard.get(); +GCAnalogFactory* InputSubsystem::GetGCAnalogs() { + return impl->gcanalog.get(); } -MotionEmu* GetMotionEmu() { - return motion_emu.get(); +const GCAnalogFactory* InputSubsystem::GetGCAnalogs() const { + return impl->gcanalog.get(); } -GCButtonFactory* GetGCButtons() { - return gcbuttons.get(); +GCButtonFactory* InputSubsystem::GetGCButtons() { + return impl->gcbuttons.get(); } -GCAnalogFactory* GetGCAnalogs() { - return gcanalog.get(); +const GCButtonFactory* InputSubsystem::GetGCButtons() const { + return impl->gcbuttons.get(); +} + +std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers( + Polling::DeviceType type) const { +#ifdef HAVE_SDL2 + return impl->sdl->GetPollers(type); +#else + return {}; +#endif } std::string GenerateKeyboardParam(int key_code) { @@ -101,68 +201,4 @@ std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, }; return circle_pad_param.Serialize(); } - -std::vector<Common::ParamPackage> GetInputDevices() { - std::vector<Common::ParamPackage> devices = { - Common::ParamPackage{{"display", "Any"}, {"class", "any"}}, - Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}}, - }; -#ifdef HAVE_SDL2 - auto sdl_devices = sdl->GetInputDevices(); - devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end()); -#endif - auto udp_devices = udp->GetInputDevices(); - devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); - return devices; -} - -std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> GetButtonMappingForDevice( - const Common::ParamPackage& params) { - std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> mappings; - if (!params.Has("class") || params.Get("class", "") == "any") { - return {}; - } - if (params.Get("class", "") == "key") { - // TODO consider returning the SDL key codes for the default keybindings - return {}; - } -#ifdef HAVE_SDL2 - if (params.Get("class", "") == "sdl") { - return sdl->GetButtonMappingForDevice(params); - } -#endif - return {}; -} - -std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> GetAnalogMappingForDevice( - const Common::ParamPackage& params) { - std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> mappings; - if (!params.Has("class") || params.Get("class", "") == "any") { - return {}; - } - if (params.Get("class", "") == "key") { - // TODO consider returning the SDL key codes for the default keybindings - return {}; - } -#ifdef HAVE_SDL2 - if (params.Get("class", "") == "sdl") { - return sdl->GetAnalogMappingForDevice(params); - } -#endif - return {}; -} - -namespace Polling { - -std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type) { - std::vector<std::unique_ptr<DevicePoller>> pollers; - -#ifdef HAVE_SDL2 - pollers = sdl->GetPollers(type); -#endif - - return pollers; -} - -} // namespace Polling } // namespace InputCommon diff --git a/src/input_common/main.h b/src/input_common/main.h index e706c3750..f66308163 100644 --- a/src/input_common/main.h +++ b/src/input_common/main.h @@ -16,52 +16,6 @@ class ParamPackage; } namespace InputCommon { - -/// Initializes and registers all built-in input device factories. -void Init(); - -/// Deregisters all built-in input device factories and shuts them down. -void Shutdown(); - -class Keyboard; - -/// Gets the keyboard button device factory. -Keyboard* GetKeyboard(); - -class MotionEmu; - -/// Gets the motion emulation factory. -MotionEmu* GetMotionEmu(); - -GCButtonFactory* GetGCButtons(); - -GCAnalogFactory* GetGCAnalogs(); - -/// Generates a serialized param package for creating a keyboard button device -std::string GenerateKeyboardParam(int key_code); - -/// Generates a serialized param package for creating an analog device taking input from keyboard -std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right, - int key_modifier, float modifier_scale); - -/** - * Return a list of available input devices that this Factory can create a new device with. - * Each returned Parampackage should have a `display` field used for display, a class field for - * backends to determine if this backend is meant to service the request and any other information - * needed to identify this in the backend later. - */ -std::vector<Common::ParamPackage> GetInputDevices(); - -/** - * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default - * mapping for the device. This is currently only implemented for the sdl backend devices. - */ -using ButtonMapping = std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage>; -using AnalogMapping = std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage>; - -ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage&); -AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage&); - namespace Polling { enum class DeviceType { Button, AnalogPreferred }; @@ -90,4 +44,88 @@ public: // Get all DevicePoller from all backends for a specific device type std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type); } // namespace Polling + +class GCAnalogFactory; +class GCButtonFactory; +class Keyboard; +class MotionEmu; + +/** + * Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default + * mapping for the device. This is currently only implemented for the SDL backend devices. + */ +using AnalogMapping = std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage>; +using ButtonMapping = std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage>; + +class InputSubsystem { +public: + explicit InputSubsystem(); + ~InputSubsystem(); + + InputSubsystem(const InputSubsystem&) = delete; + InputSubsystem& operator=(const InputSubsystem&) = delete; + + InputSubsystem(InputSubsystem&&) = delete; + InputSubsystem& operator=(InputSubsystem&&) = delete; + + /// Initializes and registers all built-in input device factories. + void Initialize(); + + /// Unregisters all built-in input device factories and shuts them down. + void Shutdown(); + + /// Retrieves the underlying keyboard device. + [[nodiscard]] Keyboard* GetKeyboard(); + + /// Retrieves the underlying keyboard device. + [[nodiscard]] const Keyboard* GetKeyboard() const; + + /// Retrieves the underlying motion emulation factory. + [[nodiscard]] MotionEmu* GetMotionEmu(); + + /// Retrieves the underlying motion emulation factory. + [[nodiscard]] const MotionEmu* GetMotionEmu() const; + + /** + * Returns all available input devices that this Factory can create a new device with. + * Each returned ParamPackage should have a `display` field used for display, a class field for + * backends to determine if this backend is meant to service the request and any other + * information needed to identify this in the backend later. + */ + [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const; + + /// Retrieves the analog mappings for the given device. + [[nodiscard]] AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& device) const; + + /// Retrieves the button mappings for the given device. + [[nodiscard]] ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& device) const; + + /// Retrieves the underlying GameCube analog handler. + [[nodiscard]] GCAnalogFactory* GetGCAnalogs(); + + /// Retrieves the underlying GameCube analog handler. + [[nodiscard]] const GCAnalogFactory* GetGCAnalogs() const; + + /// Retrieves the underlying GameCube button handler. + [[nodiscard]] GCButtonFactory* GetGCButtons(); + + /// Retrieves the underlying GameCube button handler. + [[nodiscard]] const GCButtonFactory* GetGCButtons() const; + + /// Get all DevicePoller from all backends for a specific device type + [[nodiscard]] std::vector<std::unique_ptr<Polling::DevicePoller>> GetPollers( + Polling::DeviceType type) const; + +private: + struct Impl; + std::unique_ptr<Impl> impl; +}; + +/// Generates a serialized param package for creating a keyboard button device +std::string GenerateKeyboardParam(int key_code); + +/// Generates a serialized param package for creating an analog device taking input from keyboard +std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right, + int key_modifier, float modifier_scale); + } // namespace InputCommon |