2022-04-23 09:59:50 +01:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
#include <mutex>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "common/input.h"
|
|
|
|
#include "common/param_package.h"
|
2022-02-05 17:35:39 +00:00
|
|
|
#include "common/uuid.h"
|
2021-09-20 22:34:05 +01:00
|
|
|
#include "input_common/main.h"
|
|
|
|
|
|
|
|
// Pad Identifier of data source
|
|
|
|
struct PadIdentifier {
|
2022-02-05 17:35:39 +00:00
|
|
|
Common::UUID guid{};
|
2021-09-20 22:34:05 +01:00
|
|
|
std::size_t port{};
|
|
|
|
std::size_t pad{};
|
|
|
|
|
|
|
|
friend constexpr bool operator==(const PadIdentifier&, const PadIdentifier&) = default;
|
|
|
|
};
|
|
|
|
|
2021-12-13 15:18:02 +00:00
|
|
|
// Basic motion data containing data from the sensors and a timestamp in microseconds
|
2021-09-20 22:34:05 +01:00
|
|
|
struct BasicMotion {
|
2021-12-13 15:18:02 +00:00
|
|
|
float gyro_x{};
|
|
|
|
float gyro_y{};
|
|
|
|
float gyro_z{};
|
|
|
|
float accel_x{};
|
|
|
|
float accel_y{};
|
|
|
|
float accel_z{};
|
|
|
|
u64 delta_timestamp{};
|
2021-09-20 22:34:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Types of input that are stored in the engine
|
|
|
|
enum class EngineInputType {
|
|
|
|
None,
|
2022-06-19 05:32:07 +01:00
|
|
|
Analog,
|
|
|
|
Battery,
|
2021-09-20 22:34:05 +01:00
|
|
|
Button,
|
2022-06-19 05:32:07 +01:00
|
|
|
Camera,
|
2022-12-20 19:23:31 +00:00
|
|
|
Color,
|
2021-09-20 22:34:05 +01:00
|
|
|
HatButton,
|
|
|
|
Motion,
|
2022-09-25 01:46:49 +01:00
|
|
|
Nfc,
|
2021-09-20 22:34:05 +01:00
|
|
|
};
|
|
|
|
|
2024-02-23 21:00:48 +00:00
|
|
|
struct VibrationRequest {
|
|
|
|
PadIdentifier identifier;
|
|
|
|
Common::Input::VibrationStatus vibration;
|
|
|
|
};
|
|
|
|
|
2021-09-20 22:34:05 +01:00
|
|
|
namespace std {
|
|
|
|
// Hash used to create lists from PadIdentifier data
|
|
|
|
template <>
|
|
|
|
struct hash<PadIdentifier> {
|
|
|
|
size_t operator()(const PadIdentifier& pad_id) const noexcept {
|
2022-02-05 05:40:28 +00:00
|
|
|
u64 hash_value = pad_id.guid.Hash();
|
2021-09-20 22:34:05 +01:00
|
|
|
hash_value ^= (static_cast<u64>(pad_id.port) << 32);
|
|
|
|
hash_value ^= static_cast<u64>(pad_id.pad);
|
|
|
|
return static_cast<size_t>(hash_value);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace std
|
|
|
|
|
|
|
|
namespace InputCommon {
|
|
|
|
|
|
|
|
// Data from the engine and device needed for creating a ParamPackage
|
|
|
|
struct MappingData {
|
|
|
|
std::string engine{};
|
|
|
|
PadIdentifier pad{};
|
|
|
|
EngineInputType type{};
|
|
|
|
int index{};
|
|
|
|
bool button_value{};
|
|
|
|
std::string hat_name{};
|
|
|
|
f32 axis_value{};
|
|
|
|
BasicMotion motion_value{};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Triggered if data changed on the controller
|
|
|
|
struct UpdateCallback {
|
|
|
|
std::function<void()> on_change;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Triggered if data changed on the controller and the engine is on configuring mode
|
|
|
|
struct MappingCallback {
|
2022-01-24 16:31:40 +00:00
|
|
|
std::function<void(const MappingData&)> on_data;
|
2021-09-20 22:34:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Input Identifier of data source
|
|
|
|
struct InputIdentifier {
|
|
|
|
PadIdentifier identifier;
|
|
|
|
EngineInputType type;
|
2021-10-31 15:41:44 +00:00
|
|
|
int index;
|
2021-09-20 22:34:05 +01:00
|
|
|
UpdateCallback callback;
|
|
|
|
};
|
|
|
|
|
|
|
|
class InputEngine {
|
|
|
|
public:
|
2021-12-13 14:05:23 +00:00
|
|
|
explicit InputEngine(std::string input_engine_) : input_engine{std::move(input_engine_)} {}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
virtual ~InputEngine() = default;
|
|
|
|
|
|
|
|
// Enable configuring mode for mapping
|
|
|
|
void BeginConfiguration();
|
|
|
|
|
|
|
|
// Disable configuring mode for mapping
|
|
|
|
void EndConfiguration();
|
|
|
|
|
|
|
|
// Sets a led pattern for a controller
|
2022-12-26 17:11:01 +00:00
|
|
|
virtual Common::Input::DriverResult SetLeds(
|
|
|
|
[[maybe_unused]] const PadIdentifier& identifier,
|
|
|
|
[[maybe_unused]] const Common::Input::LedStatus& led_status) {
|
|
|
|
return Common::Input::DriverResult::NotSupported;
|
|
|
|
}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
2021-10-11 06:43:11 +01:00
|
|
|
// Sets rumble to a controller
|
2022-12-26 17:11:01 +00:00
|
|
|
virtual Common::Input::DriverResult SetVibration(
|
2021-10-16 01:07:47 +01:00
|
|
|
[[maybe_unused]] const PadIdentifier& identifier,
|
2021-12-13 14:09:03 +00:00
|
|
|
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
|
2022-12-26 17:11:01 +00:00
|
|
|
return Common::Input::DriverResult::NotSupported;
|
2021-10-11 06:43:11 +01:00
|
|
|
}
|
|
|
|
|
2022-10-21 06:23:12 +01:00
|
|
|
// Returns true if device supports vibrations
|
|
|
|
virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-10-11 06:43:11 +01:00
|
|
|
// Sets polling mode to a controller
|
2022-12-26 17:11:01 +00:00
|
|
|
virtual Common::Input::DriverResult SetPollingMode(
|
2021-10-16 01:07:47 +01:00
|
|
|
[[maybe_unused]] const PadIdentifier& identifier,
|
2022-06-19 05:32:07 +01:00
|
|
|
[[maybe_unused]] const Common::Input::PollingMode polling_mode) {
|
2022-12-26 17:11:01 +00:00
|
|
|
return Common::Input::DriverResult::NotSupported;
|
2021-10-11 06:43:11 +01:00
|
|
|
}
|
|
|
|
|
2022-06-19 05:32:07 +01:00
|
|
|
// Sets camera format to a controller
|
2022-12-26 17:11:01 +00:00
|
|
|
virtual Common::Input::DriverResult SetCameraFormat(
|
2022-06-19 05:32:07 +01:00
|
|
|
[[maybe_unused]] const PadIdentifier& identifier,
|
|
|
|
[[maybe_unused]] Common::Input::CameraFormat camera_format) {
|
2022-12-26 17:11:01 +00:00
|
|
|
return Common::Input::DriverResult::NotSupported;
|
2022-06-19 05:32:07 +01:00
|
|
|
}
|
|
|
|
|
2022-11-13 16:56:01 +00:00
|
|
|
// Returns success if nfc is supported
|
2022-09-25 04:52:33 +01:00
|
|
|
virtual Common::Input::NfcState SupportsNfc(
|
|
|
|
[[maybe_unused]] const PadIdentifier& identifier) const {
|
2022-09-25 01:46:49 +01:00
|
|
|
return Common::Input::NfcState::NotSupported;
|
|
|
|
}
|
|
|
|
|
2023-06-17 04:57:21 +01:00
|
|
|
// Start scanning for nfc tags
|
|
|
|
virtual Common::Input::NfcState StartNfcPolling(
|
|
|
|
[[maybe_unused]] const PadIdentifier& identifier_) {
|
|
|
|
return Common::Input::NfcState::NotSupported;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start scanning for nfc tags
|
|
|
|
virtual Common::Input::NfcState StopNfcPolling(
|
|
|
|
[[maybe_unused]] const PadIdentifier& identifier_) {
|
|
|
|
return Common::Input::NfcState::NotSupported;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reads data from amiibo tag
|
|
|
|
virtual Common::Input::NfcState ReadAmiiboData(
|
|
|
|
[[maybe_unused]] const PadIdentifier& identifier_,
|
|
|
|
[[maybe_unused]] std::vector<u8>& out_data) {
|
|
|
|
return Common::Input::NfcState::NotSupported;
|
|
|
|
}
|
|
|
|
|
2022-09-25 01:46:49 +01:00
|
|
|
// Writes data to an nfc tag
|
|
|
|
virtual Common::Input::NfcState WriteNfcData([[maybe_unused]] const PadIdentifier& identifier,
|
|
|
|
[[maybe_unused]] const std::vector<u8>& data) {
|
|
|
|
return Common::Input::NfcState::NotSupported;
|
|
|
|
}
|
|
|
|
|
2023-06-17 04:57:21 +01:00
|
|
|
// Reads data from mifare tag
|
|
|
|
virtual Common::Input::NfcState ReadMifareData(
|
|
|
|
[[maybe_unused]] const PadIdentifier& identifier_,
|
|
|
|
[[maybe_unused]] const Common::Input::MifareRequest& request,
|
|
|
|
[[maybe_unused]] Common::Input::MifareRequest& out_data) {
|
|
|
|
return Common::Input::NfcState::NotSupported;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write data to mifare tag
|
|
|
|
virtual Common::Input::NfcState WriteMifareData(
|
|
|
|
[[maybe_unused]] const PadIdentifier& identifier_,
|
|
|
|
[[maybe_unused]] const Common::Input::MifareRequest& request) {
|
|
|
|
return Common::Input::NfcState::NotSupported;
|
|
|
|
}
|
|
|
|
|
2021-09-20 22:34:05 +01:00
|
|
|
// Returns the engine name
|
|
|
|
[[nodiscard]] const std::string& GetEngineName() const;
|
|
|
|
|
|
|
|
/// Used for automapping features
|
|
|
|
virtual std::vector<Common::ParamPackage> GetInputDevices() const {
|
|
|
|
return {};
|
2021-12-13 13:52:59 +00:00
|
|
|
}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
/// Retrieves the button mappings for the given device
|
2021-12-13 14:34:46 +00:00
|
|
|
virtual ButtonMapping GetButtonMappingForDevice(
|
2021-09-20 22:34:05 +01:00
|
|
|
[[maybe_unused]] const Common::ParamPackage& params) {
|
|
|
|
return {};
|
2021-12-13 13:52:59 +00:00
|
|
|
}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
/// Retrieves the analog mappings for the given device
|
2021-12-13 14:34:46 +00:00
|
|
|
virtual AnalogMapping GetAnalogMappingForDevice(
|
2021-09-20 22:34:05 +01:00
|
|
|
[[maybe_unused]] const Common::ParamPackage& params) {
|
|
|
|
return {};
|
2021-12-13 13:52:59 +00:00
|
|
|
}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
/// Retrieves the motion mappings for the given device
|
2021-12-13 14:34:46 +00:00
|
|
|
virtual MotionMapping GetMotionMappingForDevice(
|
2021-09-20 22:34:05 +01:00
|
|
|
[[maybe_unused]] const Common::ParamPackage& params) {
|
|
|
|
return {};
|
2021-12-13 13:52:59 +00:00
|
|
|
}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
/// Retrieves the name of the given input.
|
2021-11-21 20:12:01 +00:00
|
|
|
virtual Common::Input::ButtonNames GetUIName(
|
|
|
|
[[maybe_unused]] const Common::ParamPackage& params) const {
|
|
|
|
return Common::Input::ButtonNames::Engine;
|
2021-12-13 13:52:59 +00:00
|
|
|
}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
/// Retrieves the index number of the given hat button direction
|
2021-11-15 03:56:54 +00:00
|
|
|
virtual u8 GetHatButtonId([[maybe_unused]] const std::string& direction_name) const {
|
2021-09-20 22:34:05 +01:00
|
|
|
return 0;
|
2021-12-13 13:52:59 +00:00
|
|
|
}
|
2021-09-20 22:34:05 +01:00
|
|
|
|
2022-03-04 17:47:13 +00:00
|
|
|
/// Returns true if axis of a stick aren't mapped in the correct direction
|
|
|
|
virtual bool IsStickInverted([[maybe_unused]] const Common::ParamPackage& params) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-09-20 22:34:05 +01:00
|
|
|
void PreSetController(const PadIdentifier& identifier);
|
|
|
|
void PreSetButton(const PadIdentifier& identifier, int button);
|
|
|
|
void PreSetHatButton(const PadIdentifier& identifier, int button);
|
|
|
|
void PreSetAxis(const PadIdentifier& identifier, int axis);
|
|
|
|
void PreSetMotion(const PadIdentifier& identifier, int motion);
|
|
|
|
void ResetButtonState();
|
|
|
|
void ResetAnalogState();
|
|
|
|
|
|
|
|
bool GetButton(const PadIdentifier& identifier, int button) const;
|
|
|
|
bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const;
|
|
|
|
f32 GetAxis(const PadIdentifier& identifier, int axis) const;
|
2022-02-07 00:20:12 +00:00
|
|
|
Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const;
|
2022-12-20 19:23:31 +00:00
|
|
|
Common::Input::BodyColorStatus GetColor(const PadIdentifier& identifier) const;
|
2021-09-20 22:34:05 +01:00
|
|
|
BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const;
|
2022-06-19 05:32:07 +01:00
|
|
|
Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const;
|
2022-09-25 01:46:49 +01:00
|
|
|
Common::Input::NfcStatus GetNfc(const PadIdentifier& identifier) const;
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
int SetCallback(InputIdentifier input_identifier);
|
|
|
|
void SetMappingCallback(MappingCallback callback);
|
|
|
|
void DeleteCallback(int key);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void SetButton(const PadIdentifier& identifier, int button, bool value);
|
|
|
|
void SetHatButton(const PadIdentifier& identifier, int button, u8 value);
|
|
|
|
void SetAxis(const PadIdentifier& identifier, int axis, f32 value);
|
2022-02-07 00:20:12 +00:00
|
|
|
void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
|
2022-12-20 19:23:31 +00:00
|
|
|
void SetColor(const PadIdentifier& identifier, Common::Input::BodyColorStatus value);
|
2021-12-13 14:26:44 +00:00
|
|
|
void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value);
|
2022-06-19 05:32:07 +01:00
|
|
|
void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value);
|
2022-09-25 01:46:49 +01:00
|
|
|
void SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value);
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const {
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct ControllerData {
|
|
|
|
std::unordered_map<int, bool> buttons;
|
|
|
|
std::unordered_map<int, u8> hat_buttons;
|
|
|
|
std::unordered_map<int, float> axes;
|
|
|
|
std::unordered_map<int, BasicMotion> motions;
|
2022-02-07 00:20:12 +00:00
|
|
|
Common::Input::BatteryLevel battery{};
|
2022-12-20 19:23:31 +00:00
|
|
|
Common::Input::BodyColorStatus color{};
|
2022-06-19 05:32:07 +01:00
|
|
|
Common::Input::CameraStatus camera{};
|
2022-09-25 01:46:49 +01:00
|
|
|
Common::Input::NfcStatus nfc{};
|
2021-09-20 22:34:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value);
|
|
|
|
void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value);
|
2021-12-13 15:21:37 +00:00
|
|
|
void TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value);
|
2022-02-07 00:20:12 +00:00
|
|
|
void TriggerOnBatteryChange(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
|
2022-12-20 19:23:31 +00:00
|
|
|
void TriggerOnColorChange(const PadIdentifier& identifier,
|
|
|
|
Common::Input::BodyColorStatus value);
|
2021-12-13 14:26:44 +00:00
|
|
|
void TriggerOnMotionChange(const PadIdentifier& identifier, int motion,
|
|
|
|
const BasicMotion& value);
|
2022-06-19 05:32:07 +01:00
|
|
|
void TriggerOnCameraChange(const PadIdentifier& identifier,
|
|
|
|
const Common::Input::CameraStatus& value);
|
2022-09-25 01:46:49 +01:00
|
|
|
void TriggerOnNfcChange(const PadIdentifier& identifier, const Common::Input::NfcStatus& value);
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
bool IsInputIdentifierEqual(const InputIdentifier& input_identifier,
|
|
|
|
const PadIdentifier& identifier, EngineInputType type,
|
2021-10-31 15:41:44 +00:00
|
|
|
int index) const;
|
2021-09-20 22:34:05 +01:00
|
|
|
|
|
|
|
mutable std::mutex mutex;
|
|
|
|
mutable std::mutex mutex_callback;
|
|
|
|
bool configuring{false};
|
|
|
|
const std::string input_engine;
|
|
|
|
int last_callback_key = 0;
|
|
|
|
std::unordered_map<PadIdentifier, ControllerData> controller_list;
|
|
|
|
std::unordered_map<int, InputIdentifier> callback_list;
|
|
|
|
MappingCallback mapping_callback;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace InputCommon
|