2020-03-21 14:49:46 +00:00
|
|
|
#pragma once
|
|
|
|
#include "common_host_interface.h"
|
|
|
|
#include "core/types.h"
|
|
|
|
#include <array>
|
|
|
|
#include <functional>
|
|
|
|
#include <map>
|
|
|
|
#include <mutex>
|
2020-08-29 12:19:28 +00:00
|
|
|
#include <optional>
|
2021-03-14 06:18:56 +00:00
|
|
|
#include <string_view>
|
2020-11-15 13:56:52 +00:00
|
|
|
#include <variant>
|
2020-03-21 14:49:46 +00:00
|
|
|
|
|
|
|
class HostInterface;
|
|
|
|
class Controller;
|
|
|
|
|
|
|
|
class ControllerInterface
|
|
|
|
{
|
|
|
|
public:
|
2020-08-22 06:44:06 +00:00
|
|
|
enum class Backend
|
|
|
|
{
|
|
|
|
None,
|
|
|
|
#ifdef WITH_SDL2
|
|
|
|
SDL,
|
|
|
|
#endif
|
2021-06-28 10:16:48 +00:00
|
|
|
#ifdef _WIN32
|
2020-08-22 06:44:06 +00:00
|
|
|
XInput,
|
2021-07-04 09:14:28 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WITH_DINPUT
|
2020-12-29 06:29:30 +00:00
|
|
|
DInput,
|
2020-12-27 07:50:29 +00:00
|
|
|
#endif
|
|
|
|
#ifdef ANDROID
|
|
|
|
Android,
|
2021-02-07 11:32:59 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WITH_EVDEV
|
|
|
|
Evdev,
|
2020-08-22 06:44:06 +00:00
|
|
|
#endif
|
|
|
|
Count
|
|
|
|
};
|
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
enum : int
|
|
|
|
{
|
2020-12-29 06:29:30 +00:00
|
|
|
NUM_HAT_DIRECTIONS = 4,
|
|
|
|
HAT_DIRECTION_UP = 0,
|
|
|
|
HAT_DIRECTION_DOWN = 1,
|
|
|
|
HAT_DIRECTION_LEFT = 2,
|
|
|
|
HAT_DIRECTION_RIGHT = 3,
|
2020-03-21 14:49:46 +00:00
|
|
|
};
|
|
|
|
|
2020-11-15 13:56:52 +00:00
|
|
|
enum AxisSide
|
|
|
|
{
|
|
|
|
Full,
|
|
|
|
Positive,
|
|
|
|
Negative
|
|
|
|
};
|
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
using AxisCallback = CommonHostInterface::InputAxisHandler;
|
|
|
|
using ButtonCallback = CommonHostInterface::InputButtonHandler;
|
|
|
|
|
|
|
|
ControllerInterface();
|
|
|
|
virtual ~ControllerInterface();
|
|
|
|
|
2020-08-22 06:44:06 +00:00
|
|
|
static std::optional<Backend> ParseBackendName(const char* name);
|
|
|
|
static const char* GetBackendName(Backend type);
|
|
|
|
static Backend GetDefaultBackend();
|
|
|
|
static std::unique_ptr<ControllerInterface> Create(Backend type);
|
|
|
|
|
|
|
|
virtual Backend GetBackend() const = 0;
|
2020-03-21 14:49:46 +00:00
|
|
|
virtual bool Initialize(CommonHostInterface* host_interface);
|
|
|
|
virtual void Shutdown();
|
|
|
|
|
|
|
|
// Removes all bindings. Call before setting new bindings.
|
|
|
|
virtual void ClearBindings() = 0;
|
|
|
|
|
|
|
|
// Binding to events. If a binding for this axis/button already exists, returns false.
|
2021-03-14 06:18:56 +00:00
|
|
|
virtual std::optional<int> GetControllerIndex(const std::string_view& device);
|
2020-11-15 13:56:52 +00:00
|
|
|
virtual bool BindControllerAxis(int controller_index, int axis_number, AxisSide axis_side, AxisCallback callback) = 0;
|
2020-03-21 14:49:46 +00:00
|
|
|
virtual bool BindControllerButton(int controller_index, int button_number, ButtonCallback callback) = 0;
|
|
|
|
virtual bool BindControllerAxisToButton(int controller_index, int axis_number, bool direction,
|
|
|
|
ButtonCallback callback) = 0;
|
2020-11-15 13:56:52 +00:00
|
|
|
virtual bool BindControllerHatToButton(int controller_index, int hat_number, std::string_view hat_position,
|
|
|
|
ButtonCallback callback) = 0;
|
2020-08-29 12:19:28 +00:00
|
|
|
virtual bool BindControllerButtonToAxis(int controller_index, int button_number, AxisCallback callback) = 0;
|
2020-04-14 06:34:39 +00:00
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
virtual void PollEvents() = 0;
|
2020-04-14 06:34:39 +00:00
|
|
|
|
|
|
|
// Changing rumble strength.
|
|
|
|
virtual u32 GetControllerRumbleMotorCount(int controller_index) = 0;
|
|
|
|
virtual void SetControllerRumbleStrength(int controller_index, const float* strengths, u32 num_motors) = 0;
|
2020-03-21 14:49:46 +00:00
|
|
|
|
2020-06-23 02:30:19 +00:00
|
|
|
// Set deadzone that will be applied on axis-to-button mappings
|
|
|
|
virtual bool SetControllerDeadzone(int controller_index, float size) = 0;
|
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
// Input monitoring for external access.
|
|
|
|
struct Hook
|
|
|
|
{
|
|
|
|
enum class Type
|
|
|
|
{
|
|
|
|
Axis,
|
2020-11-15 13:56:52 +00:00
|
|
|
Button,
|
|
|
|
Hat // Only for joysticks
|
2020-03-21 14:49:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum class CallbackResult
|
|
|
|
{
|
|
|
|
StopMonitoring,
|
|
|
|
ContinueMonitoring
|
|
|
|
};
|
|
|
|
|
|
|
|
using Callback = std::function<CallbackResult(const Hook& ei)>;
|
|
|
|
|
|
|
|
Type type;
|
|
|
|
int controller_index;
|
|
|
|
int button_or_axis_number;
|
2020-11-15 13:56:52 +00:00
|
|
|
std::variant<float, std::string_view> value; // 0/1 for buttons, -1..1 for axes, hat direction name for hats
|
|
|
|
bool track_history; // Track axis movement to spot inversion/half axes
|
2020-03-21 14:49:46 +00:00
|
|
|
};
|
|
|
|
void SetHook(Hook::Callback callback);
|
|
|
|
void ClearHook();
|
2021-02-24 16:05:33 +00:00
|
|
|
bool HasHook();
|
2020-03-21 14:49:46 +00:00
|
|
|
|
|
|
|
protected:
|
2020-11-15 13:56:52 +00:00
|
|
|
bool DoEventHook(Hook::Type type, int controller_index, int button_or_axis_number,
|
|
|
|
std::variant<float, std::string_view> value, bool track_history = false);
|
2020-03-21 14:49:46 +00:00
|
|
|
|
|
|
|
void OnControllerConnected(int host_id);
|
|
|
|
void OnControllerDisconnected(int host_id);
|
|
|
|
|
|
|
|
CommonHostInterface* m_host_interface = nullptr;
|
|
|
|
|
|
|
|
std::mutex m_event_intercept_mutex;
|
|
|
|
Hook::Callback m_event_intercept_callback;
|
|
|
|
};
|