2024-03-06 06:08:10 +00:00
|
|
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
2022-12-04 11:03:45 +00:00
|
|
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
|
|
|
|
2019-09-20 06:47:41 +00:00
|
|
|
#pragma once
|
2023-09-20 07:10:41 +00:00
|
|
|
|
2023-01-15 04:00:51 +00:00
|
|
|
#include "input_types.h"
|
2020-06-30 14:33:45 +00:00
|
|
|
#include "settings.h"
|
2019-09-20 06:47:41 +00:00
|
|
|
#include "types.h"
|
2023-09-20 07:10:41 +00:00
|
|
|
|
2019-12-10 13:05:19 +00:00
|
|
|
#include <memory>
|
2019-12-08 14:46:04 +00:00
|
|
|
#include <optional>
|
2023-09-20 07:10:41 +00:00
|
|
|
#include <span>
|
2020-01-02 06:10:42 +00:00
|
|
|
#include <string>
|
2019-12-08 14:46:04 +00:00
|
|
|
#include <string_view>
|
2022-07-11 13:03:29 +00:00
|
|
|
#include <tuple>
|
2020-01-02 06:10:42 +00:00
|
|
|
#include <vector>
|
2019-09-20 06:47:41 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
class SettingsInterface;
|
2019-09-29 15:59:35 +00:00
|
|
|
class StateWrapper;
|
2020-06-30 14:33:45 +00:00
|
|
|
class HostInterface;
|
2019-09-29 15:59:35 +00:00
|
|
|
|
2019-12-08 14:51:52 +00:00
|
|
|
class Controller
|
2019-09-20 06:47:41 +00:00
|
|
|
{
|
|
|
|
public:
|
2022-07-11 13:03:29 +00:00
|
|
|
enum class VibrationCapabilities : u8
|
|
|
|
{
|
|
|
|
NoVibration,
|
|
|
|
LargeSmallMotors,
|
|
|
|
SingleMotor,
|
|
|
|
Count
|
|
|
|
};
|
2020-01-02 06:10:42 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
struct ControllerBindingInfo
|
|
|
|
{
|
|
|
|
const char* name;
|
|
|
|
const char* display_name;
|
2023-11-26 10:30:10 +00:00
|
|
|
const char* icon_name;
|
2022-07-11 13:03:29 +00:00
|
|
|
u32 bind_index;
|
2023-01-15 04:00:51 +00:00
|
|
|
InputBindingInfo::Type type;
|
2022-07-11 13:03:29 +00:00
|
|
|
GenericInputBinding generic_mapping;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ControllerInfo
|
|
|
|
{
|
|
|
|
ControllerType type;
|
|
|
|
const char* name;
|
|
|
|
const char* display_name;
|
2023-11-26 10:30:10 +00:00
|
|
|
const char* icon_name;
|
2023-09-20 07:10:41 +00:00
|
|
|
std::span<const ControllerBindingInfo> bindings;
|
|
|
|
std::span<const SettingInfo> settings;
|
2022-07-11 13:03:29 +00:00
|
|
|
VibrationCapabilities vibration_caps;
|
2024-04-27 03:21:11 +00:00
|
|
|
|
|
|
|
/// Returns localized controller type name.
|
|
|
|
const char* GetDisplayName() const;
|
2022-07-11 13:03:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Default stick deadzone/sensitivity.
|
|
|
|
static constexpr float DEFAULT_STICK_DEADZONE = 0.0f;
|
|
|
|
static constexpr float DEFAULT_STICK_SENSITIVITY = 1.33f;
|
2022-09-22 03:50:31 +00:00
|
|
|
static constexpr float DEFAULT_BUTTON_DEADZONE = 0.25f;
|
2022-07-11 13:03:29 +00:00
|
|
|
|
|
|
|
Controller(u32 index);
|
2019-12-08 14:51:52 +00:00
|
|
|
virtual ~Controller();
|
2019-09-20 06:47:41 +00:00
|
|
|
|
2019-12-14 14:17:43 +00:00
|
|
|
/// Returns the type of controller.
|
|
|
|
virtual ControllerType GetType() const = 0;
|
|
|
|
|
2019-09-29 15:59:35 +00:00
|
|
|
virtual void Reset();
|
2020-12-16 14:09:32 +00:00
|
|
|
virtual bool DoState(StateWrapper& sw, bool apply_input_state);
|
2019-09-29 15:59:35 +00:00
|
|
|
|
2019-09-29 15:07:38 +00:00
|
|
|
// Resets all state for the transferring to/from the device.
|
|
|
|
virtual void ResetTransferState();
|
|
|
|
|
2019-09-20 06:47:41 +00:00
|
|
|
// Returns the value of ACK, as well as filling out_data.
|
|
|
|
virtual bool Transfer(const u8 data_in, u8* data_out);
|
|
|
|
|
2021-04-03 17:51:08 +00:00
|
|
|
/// Changes the specified axis state. Values are normalized from -1..1.
|
2022-07-11 13:03:29 +00:00
|
|
|
virtual float GetBindState(u32 index) const;
|
2021-04-03 17:51:08 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
/// Changes the specified bind state. Values are normalized from -1..1.
|
|
|
|
virtual void SetBindState(u32 index, float value);
|
2019-12-08 15:06:58 +00:00
|
|
|
|
2020-12-06 05:47:00 +00:00
|
|
|
/// Returns a bitmask of the current button states, 1 = on.
|
|
|
|
virtual u32 GetButtonStateBits() const;
|
|
|
|
|
2022-10-09 04:10:42 +00:00
|
|
|
/// Returns true if the controller supports analog mode, and it is active.
|
|
|
|
virtual bool InAnalogMode() const;
|
|
|
|
|
2021-01-04 06:54:16 +00:00
|
|
|
/// Returns analog input bytes packed as a u32. Values are specific to controller type.
|
|
|
|
virtual std::optional<u32> GetAnalogInputBytes() const;
|
|
|
|
|
2020-06-30 14:33:45 +00:00
|
|
|
/// Loads/refreshes any per-controller settings.
|
2022-07-11 13:03:29 +00:00
|
|
|
virtual void LoadSettings(SettingsInterface& si, const char* section);
|
2020-06-30 14:33:45 +00:00
|
|
|
|
2019-12-08 14:46:04 +00:00
|
|
|
/// Creates a new controller of the specified type.
|
2020-07-31 07:09:18 +00:00
|
|
|
static std::unique_ptr<Controller> Create(ControllerType type, u32 index);
|
2019-12-08 14:46:04 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
/// Returns the default type for the specified port.
|
|
|
|
static const char* GetDefaultPadType(u32 pad);
|
|
|
|
|
|
|
|
/// Returns a list of controller type names. Pair of [name, display name].
|
|
|
|
static std::vector<std::pair<std::string, std::string>> GetControllerTypeNames();
|
|
|
|
|
2019-12-14 14:31:07 +00:00
|
|
|
/// Gets the integer code for an axis in the specified controller type.
|
2024-05-05 10:21:54 +00:00
|
|
|
static std::optional<u32> GetBindIndex(ControllerType type, std::string_view bind_name);
|
2022-07-11 13:03:29 +00:00
|
|
|
|
|
|
|
/// Returns the vibration configuration for the specified controller type.
|
2024-05-05 10:21:54 +00:00
|
|
|
static VibrationCapabilities GetControllerVibrationCapabilities(std::string_view type);
|
2019-12-14 14:31:07 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
/// Returns general information for the specified controller type.
|
|
|
|
static const ControllerInfo* GetControllerInfo(ControllerType type);
|
2024-04-27 03:21:11 +00:00
|
|
|
static const ControllerInfo* GetControllerInfo(std::string_view name);
|
2020-01-02 06:10:42 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
/// Converts a global pad index to a multitap port and slot.
|
|
|
|
static std::tuple<u32, u32> ConvertPadToPortAndSlot(u32 index);
|
2020-01-02 06:10:42 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
/// Converts a multitap port and slot to a global pad index.
|
|
|
|
static u32 ConvertPortAndSlotToPad(u32 port, u32 slot);
|
2020-04-14 06:34:39 +00:00
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
/// Returns true if the given pad index is a multitap slot.
|
|
|
|
static bool PadIsMultitapSlot(u32 index);
|
|
|
|
static bool PortAndSlotIsMultitap(u32 port, u32 slot);
|
|
|
|
|
|
|
|
/// Returns the configuration section for the specified gamepad.
|
|
|
|
static std::string GetSettingsSection(u32 pad);
|
|
|
|
|
|
|
|
/// Applies an analog deadzone/sensitivity.
|
|
|
|
static float ApplyAnalogDeadzoneSensitivity(float deadzone, float sensitivity, float value)
|
|
|
|
{
|
|
|
|
return (value < deadzone) ? 0.0f : ((value - deadzone) / (1.0f - deadzone) * sensitivity);
|
|
|
|
}
|
2020-06-30 14:33:45 +00:00
|
|
|
|
2022-10-21 11:14:27 +00:00
|
|
|
/// Returns true if the specified coordinates are inside a circular deadzone.
|
|
|
|
static bool InCircularDeadzone(float deadzone, float pos_x, float pos_y);
|
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
protected:
|
|
|
|
u32 m_index;
|
2019-12-08 14:46:04 +00:00
|
|
|
};
|