// Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include #include namespace Common { class ParamPackage; } namespace Settings::NativeAnalog { enum Values : int; } namespace Settings::NativeButton { enum Values : int; } namespace Settings::NativeMotion { enum Values : int; } namespace MouseInput { class Mouse; } namespace TasInput { class Tas; } namespace InputCommon { namespace Polling { enum class DeviceType { Button, AnalogPreferred, Motion }; /// Type of input desired for mapping purposes enum class InputType { None, Button, Stick, Motion, Touch }; /** * A class that can be used to get inputs from an input device like controllers without having to * poll the device's status yourself */ class DevicePoller { public: virtual ~DevicePoller() = default; /// Setup and start polling for inputs, should be called before GetNextInput /// If a device_id is provided, events should be filtered to only include events from this /// device id virtual void Start(const std::string& device_id = "") = 0; /// Stop polling virtual void Stop() = 0; /** * Every call to this function returns the next input recorded since calling Start * @return A ParamPackage of the recorded input, which can be used to create an InputDevice. * If there has been no input, the package is empty */ virtual Common::ParamPackage GetNextInput() = 0; }; } // namespace Polling /** * 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; using ButtonMapping = std::unordered_map; using MotionMapping = std::unordered_map; 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(); /** * 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 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 motion mappings for the given device. [[nodiscard]] MotionMapping GetMotionMappingForDevice(const Common::ParamPackage& device) const; /// Reloads the input devices void ReloadInputDevices(); /// Get all DevicePoller from all backends for a specific device type [[nodiscard]] std::vector> GetPollers( Polling::DeviceType type) const; private: struct Impl; std::unique_ptr 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