// Copyright 2021 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include #include #include #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, Settings::NativeKeyboard::NumKeyboardKeys>; using KeyboardModifierDevices = std::array, Settings::NativeKeyboard::NumKeyboardMods>; using MouseButtonDevices = std::array, Settings::NativeMouseButton::NumMouseButtons>; using MouseAnalogDevices = std::array, Settings::NativeMouseWheel::NumMouseWheels>; using MouseStickDevice = std::unique_ptr; using MouseButtonParams = std::array; using KeyboardValues = std::array; using KeyboardModifierValues = std::array; using MouseButtonValues = std::array; using MouseAnalogValues = std::array; 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 on_change; }; class EmulatedDevices { public: /** * Contains all input data related to external devices that aren't necesarily a controller * like keyboard and mouse */ EmulatedDevices(); ~EmulatedDevices(); YUZU_NON_COPYABLE(EmulatedDevices); YUZU_NON_MOVEABLE(EmulatedDevices); /// Removes all callbacks created from input devices void UnloadInput(); /// Sets the emulated console into configuring mode. Locking all HID service events from being /// moddified void EnableConfiguration(); /// Returns the emulated console to the normal behaivour void DisableConfiguration(); /// Returns true if the emulated device is on 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 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 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 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 callback_list; int last_callback_key = 0; // Stores the current status of all external device input DeviceStatus device_status; }; } // namespace Core::HID