dinput_source.h (2605B)
1 // SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 #define DIRECTINPUT_VERSION 0x0800 6 #include "common/windows_headers.h" 7 #include "core/types.h" 8 #include "input_source.h" 9 #include <array> 10 #include <dinput.h> 11 #include <functional> 12 #include <mutex> 13 #include <vector> 14 #include <wrl/client.h> 15 16 class DInputSource final : public InputSource 17 { 18 public: 19 enum HAT_DIRECTION : u32 20 { 21 HAT_DIRECTION_UP = 0, 22 HAT_DIRECTION_DOWN = 1, 23 HAT_DIRECTION_LEFT = 2, 24 HAT_DIRECTION_RIGHT = 3, 25 NUM_HAT_DIRECTIONS = 4, 26 }; 27 28 enum : u32 29 { 30 MAX_NUM_BUTTONS = 32, 31 }; 32 33 DInputSource(); 34 ~DInputSource() override; 35 36 bool Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override; 37 void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override; 38 bool ReloadDevices() override; 39 void Shutdown() override; 40 41 void PollEvents() override; 42 std::vector<std::pair<std::string, std::string>> EnumerateDevices() override; 43 std::vector<InputBindingKey> EnumerateMotors() override; 44 bool GetGenericBindingMapping(std::string_view device, GenericInputBindingMapping* mapping) override; 45 void UpdateMotorState(InputBindingKey key, float intensity) override; 46 void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, 47 float small_intensity) override; 48 49 std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) override; 50 TinyString ConvertKeyToString(InputBindingKey key) override; 51 TinyString ConvertKeyToIcon(InputBindingKey key) override; 52 53 private: 54 template<typename T> 55 using ComPtr = Microsoft::WRL::ComPtr<T>; 56 57 struct ControllerData 58 { 59 ComPtr<IDirectInputDevice8W> device; 60 DIJOYSTATE last_state = {}; 61 GUID guid = {}; 62 std::vector<u32> axis_offsets; 63 u32 num_buttons = 0; 64 65 // NOTE: We expose hats as num_buttons + (hat_index * 4) + direction. 66 u32 num_hats = 0; 67 68 bool needs_poll = true; 69 }; 70 71 using ControllerDataArray = std::vector<ControllerData>; 72 73 static std::array<bool, NUM_HAT_DIRECTIONS> GetHatButtons(DWORD hat); 74 static std::string GetDeviceIdentifier(u32 index); 75 76 bool AddDevice(ControllerData& cd, const std::string& name); 77 78 void CheckForStateChanges(size_t index, const DIJOYSTATE& new_state); 79 80 ControllerDataArray m_controllers; 81 82 HMODULE m_dinput_module{}; 83 ComPtr<IDirectInput8W> m_dinput; 84 LPCDIDATAFORMAT m_joystick_data_format{}; 85 HWND m_toplevel_window = NULL; 86 };