mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-23 00:35:37 +00:00
78 lines
2.4 KiB
C++
78 lines
2.4 KiB
C++
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
|
|
|
#pragma once
|
|
#include "common/windows_headers.h"
|
|
#include "input_source.h"
|
|
#include <Xinput.h>
|
|
#include <array>
|
|
#include <functional>
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
class SettingsInterface;
|
|
|
|
class XInputSource final : public InputSource
|
|
{
|
|
public:
|
|
enum : u32
|
|
{
|
|
NUM_CONTROLLERS = XUSER_MAX_COUNT, // 4
|
|
NUM_BUTTONS = 15,
|
|
};
|
|
|
|
enum : u32
|
|
{
|
|
AXIS_LEFTX,
|
|
AXIS_LEFTY,
|
|
AXIS_RIGHTX,
|
|
AXIS_RIGHTY,
|
|
AXIS_LEFTTRIGGER,
|
|
AXIS_RIGHTTRIGGER,
|
|
NUM_AXES,
|
|
};
|
|
|
|
XInputSource();
|
|
~XInputSource();
|
|
|
|
bool Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
|
void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override;
|
|
bool ReloadDevices() override;
|
|
void Shutdown() override;
|
|
|
|
void PollEvents() override;
|
|
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
|
std::vector<InputBindingKey> EnumerateMotors() override;
|
|
bool GetGenericBindingMapping(std::string_view device, GenericInputBindingMapping* mapping) override;
|
|
void UpdateMotorState(InputBindingKey key, float intensity) override;
|
|
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity,
|
|
float small_intensity) override;
|
|
|
|
std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) override;
|
|
TinyString ConvertKeyToString(InputBindingKey key) override;
|
|
TinyString ConvertKeyToIcon(InputBindingKey key) override;
|
|
|
|
private:
|
|
struct ControllerData
|
|
{
|
|
XINPUT_STATE last_state;
|
|
XINPUT_VIBRATION last_vibration = {};
|
|
bool connected = false;
|
|
bool has_large_motor = false;
|
|
bool has_small_motor = false;
|
|
};
|
|
|
|
using ControllerDataArray = std::array<ControllerData, NUM_CONTROLLERS>;
|
|
|
|
void CheckForStateChanges(u32 index, const XINPUT_STATE& new_state);
|
|
void HandleControllerConnection(u32 index);
|
|
void HandleControllerDisconnection(u32 index);
|
|
|
|
ControllerDataArray m_controllers;
|
|
|
|
HMODULE m_xinput_module{};
|
|
DWORD(WINAPI* m_xinput_get_state)(DWORD, XINPUT_STATE*) = nullptr;
|
|
DWORD(WINAPI* m_xinput_set_state)(DWORD, XINPUT_VIBRATION*) = nullptr;
|
|
DWORD(WINAPI* m_xinput_get_capabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*) = nullptr;
|
|
};
|