2020-02-15 15:14:53 +00:00
|
|
|
#pragma once
|
2020-03-21 14:49:46 +00:00
|
|
|
#include "controller_interface.h"
|
2020-08-29 12:19:28 +00:00
|
|
|
#include "core/types.h"
|
2020-02-15 15:14:53 +00:00
|
|
|
#include <array>
|
|
|
|
#include <functional>
|
|
|
|
#include <mutex>
|
2020-08-29 12:19:28 +00:00
|
|
|
#include <vector>
|
2020-02-15 15:14:53 +00:00
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
class SDLControllerInterface final : public ControllerInterface
|
2020-02-15 15:14:53 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
SDLControllerInterface();
|
|
|
|
~SDLControllerInterface();
|
|
|
|
|
2020-08-22 06:44:06 +00:00
|
|
|
Backend GetBackend() const override;
|
2020-03-21 14:49:46 +00:00
|
|
|
bool Initialize(CommonHostInterface* host_interface) override;
|
|
|
|
void Shutdown() override;
|
2020-02-15 15:14:53 +00:00
|
|
|
|
2020-08-21 19:00:22 +00:00
|
|
|
/// Returns the path of the optional game controller database file.
|
|
|
|
std::string GetGameControllerDBFileName() const;
|
|
|
|
|
2020-02-15 15:14:53 +00:00
|
|
|
// Removes all bindings. Call before setting new bindings.
|
2020-03-21 14:49:46 +00:00
|
|
|
void ClearBindings() override;
|
2020-02-15 15:14:53 +00:00
|
|
|
|
|
|
|
// Binding to events. If a binding for this axis/button already exists, returns false.
|
2020-11-15 13:56:52 +00:00
|
|
|
bool BindControllerAxis(int controller_index, int axis_number, AxisSide axis_side, AxisCallback callback) override;
|
2020-03-21 14:49:46 +00:00
|
|
|
bool BindControllerButton(int controller_index, int button_number, ButtonCallback callback) override;
|
2020-08-29 12:19:28 +00:00
|
|
|
bool BindControllerAxisToButton(int controller_index, int axis_number, bool direction,
|
|
|
|
ButtonCallback callback) override;
|
2020-11-15 13:56:52 +00:00
|
|
|
bool BindControllerHatToButton(int controller_index, int hat_number, std::string_view hat_position,
|
|
|
|
ButtonCallback callback) override;
|
2020-08-29 12:19:28 +00:00
|
|
|
bool BindControllerButtonToAxis(int controller_index, int button_number, AxisCallback callback) override;
|
2020-02-15 15:14:53 +00:00
|
|
|
|
2020-04-14 06:34:39 +00:00
|
|
|
// Changing rumble strength.
|
|
|
|
u32 GetControllerRumbleMotorCount(int controller_index) override;
|
|
|
|
void SetControllerRumbleStrength(int controller_index, const float* strengths, u32 num_motors) override;
|
|
|
|
|
2020-06-23 02:30:19 +00:00
|
|
|
// Set deadzone that will be applied on axis-to-button mappings
|
|
|
|
bool SetControllerDeadzone(int controller_index, float size = 0.25f) override;
|
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
void PollEvents() override;
|
2020-02-15 15:14:53 +00:00
|
|
|
|
2020-11-15 14:21:39 +00:00
|
|
|
bool ProcessSDLEvent(const union SDL_Event* event);
|
2020-02-15 15:14:53 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
struct ControllerData
|
|
|
|
{
|
|
|
|
void* haptic;
|
2020-12-31 09:38:28 +00:00
|
|
|
void* game_controller;
|
2020-04-14 06:34:39 +00:00
|
|
|
int haptic_left_right_effect;
|
2020-03-21 14:49:46 +00:00
|
|
|
int joystick_id;
|
|
|
|
int player_id;
|
2020-12-31 09:38:28 +00:00
|
|
|
bool use_game_controller_rumble;
|
2020-02-15 15:14:53 +00:00
|
|
|
|
2020-06-23 02:30:19 +00:00
|
|
|
float deadzone = 0.25f;
|
2020-06-07 01:49:25 +00:00
|
|
|
|
2020-11-15 13:56:52 +00:00
|
|
|
// TODO: Turn to vectors to support arbitrary amounts of buttons and axes (for Joysticks)
|
|
|
|
// Preferably implement a simple "flat map", an ordered view over a vector
|
|
|
|
std::array<std::array<AxisCallback, 3>, MAX_NUM_AXISES> axis_mapping;
|
2020-02-15 15:14:53 +00:00
|
|
|
std::array<ButtonCallback, MAX_NUM_BUTTONS> button_mapping;
|
|
|
|
std::array<std::array<ButtonCallback, 2>, MAX_NUM_AXISES> axis_button_mapping;
|
2020-08-29 12:19:28 +00:00
|
|
|
std::array<AxisCallback, MAX_NUM_BUTTONS> button_axis_mapping;
|
2020-11-15 13:56:52 +00:00
|
|
|
std::vector<std::array<ButtonCallback, 4>> hat_button_mapping;
|
2020-12-31 09:38:28 +00:00
|
|
|
|
|
|
|
ALWAYS_INLINE bool IsGameController() const { return (game_controller != nullptr); }
|
2020-02-15 15:14:53 +00:00
|
|
|
};
|
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
using ControllerDataVector = std::vector<ControllerData>;
|
2020-02-15 15:14:53 +00:00
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
ControllerDataVector::iterator GetControllerDataForJoystickId(int id);
|
|
|
|
ControllerDataVector::iterator GetControllerDataForPlayerId(int id);
|
2020-04-11 09:36:53 +00:00
|
|
|
int GetFreePlayerId() const;
|
2020-03-21 14:49:46 +00:00
|
|
|
|
|
|
|
bool OpenGameController(int index);
|
2020-03-22 02:37:11 +00:00
|
|
|
bool CloseGameController(int joystick_index, bool notify);
|
2020-11-15 14:21:39 +00:00
|
|
|
bool HandleControllerAxisEvent(const struct SDL_ControllerAxisEvent* event);
|
|
|
|
bool HandleControllerButtonEvent(const struct SDL_ControllerButtonEvent* event);
|
2020-03-21 14:49:46 +00:00
|
|
|
|
2020-11-15 13:56:52 +00:00
|
|
|
bool OpenJoystick(int index);
|
|
|
|
bool HandleJoystickAxisEvent(const struct SDL_JoyAxisEvent* event);
|
|
|
|
bool HandleJoystickButtonEvent(const struct SDL_JoyButtonEvent* event);
|
|
|
|
bool HandleJoystickHatEvent(const struct SDL_JoyHatEvent* event);
|
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
ControllerDataVector m_controllers;
|
2020-02-15 15:14:53 +00:00
|
|
|
|
|
|
|
std::mutex m_event_intercept_mutex;
|
|
|
|
Hook::Callback m_event_intercept_callback;
|
|
|
|
|
2020-03-21 14:49:46 +00:00
|
|
|
bool m_sdl_subsystem_initialized = false;
|
2020-02-15 15:14:53 +00:00
|
|
|
};
|