233 lines
7.2 KiB
C++
233 lines
7.2 KiB
C++
|
// Copyright 2021 yuzu Emulator Project
|
||
|
// Licensed under GPLv2 or any later version
|
||
|
// Refer to the license.txt file included.
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <functional>
|
||
|
#include <mutex>
|
||
|
#include <unordered_map>
|
||
|
|
||
|
#include "common/input.h"
|
||
|
#include "common/param_package.h"
|
||
|
#include "common/point.h"
|
||
|
#include "common/quaternion.h"
|
||
|
#include "common/settings.h"
|
||
|
#include "common/vector_math.h"
|
||
|
#include "core/hid/hid_types.h"
|
||
|
#include "core/hid/motion_input.h"
|
||
|
|
||
|
namespace Core::HID {
|
||
|
|
||
|
struct ControllerMotionInfo {
|
||
|
Input::MotionStatus raw_status;
|
||
|
MotionInput emulated{};
|
||
|
};
|
||
|
|
||
|
using ButtonDevices =
|
||
|
std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeButton::NumButtons>;
|
||
|
using StickDevices =
|
||
|
std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeAnalog::NumAnalogs>;
|
||
|
using ControllerMotionDevices =
|
||
|
std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeMotion::NumMotions>;
|
||
|
using TriggerDevices =
|
||
|
std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
|
||
|
using BatteryDevices = std::array<std::unique_ptr<Input::InputDevice>, 2>;
|
||
|
|
||
|
using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
|
||
|
using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
|
||
|
using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
|
||
|
using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
|
||
|
using BatteryParams = std::array<Common::ParamPackage, 2>;
|
||
|
|
||
|
using ButtonValues = std::array<Input::ButtonStatus, Settings::NativeButton::NumButtons>;
|
||
|
using SticksValues = std::array<Input::StickStatus, Settings::NativeAnalog::NumAnalogs>;
|
||
|
using TriggerValues = std::array<Input::TriggerStatus, Settings::NativeTrigger::NumTriggers>;
|
||
|
using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::NativeMotion::NumMotions>;
|
||
|
using ColorValues = std::array<Input::BodyColorStatus, 3>;
|
||
|
using BatteryValues = std::array<Input::BatteryStatus, 3>;
|
||
|
using VibrationValues = std::array<Input::VibrationStatus, 2>;
|
||
|
|
||
|
struct AnalogSticks {
|
||
|
AnalogStickState left;
|
||
|
AnalogStickState right;
|
||
|
};
|
||
|
|
||
|
struct ControllerColors {
|
||
|
NpadControllerColor fullkey;
|
||
|
NpadControllerColor left;
|
||
|
NpadControllerColor right;
|
||
|
};
|
||
|
|
||
|
struct BatteryLevelState {
|
||
|
NpadPowerInfo dual;
|
||
|
NpadPowerInfo left;
|
||
|
NpadPowerInfo right;
|
||
|
};
|
||
|
|
||
|
struct ControllerMotion {
|
||
|
bool is_at_rest;
|
||
|
Common::Vec3f accel{};
|
||
|
Common::Vec3f gyro{};
|
||
|
Common::Vec3f rotation{};
|
||
|
std::array<Common::Vec3f, 3> orientation{};
|
||
|
};
|
||
|
|
||
|
using MotionState = std::array<ControllerMotion, 2>;
|
||
|
|
||
|
struct ControllerStatus {
|
||
|
// Data from input_common
|
||
|
ButtonValues button_values{};
|
||
|
SticksValues stick_values{};
|
||
|
ControllerMotionValues motion_values{};
|
||
|
TriggerValues trigger_values{};
|
||
|
ColorValues color_values{};
|
||
|
BatteryValues battery_values{};
|
||
|
VibrationValues vibration_values{};
|
||
|
|
||
|
// Data for Nintendo devices
|
||
|
NpadButtonState npad_button_state{};
|
||
|
DebugPadButton debug_pad_button_state{};
|
||
|
AnalogSticks analog_stick_state{};
|
||
|
MotionState motion_state{};
|
||
|
NpadGcTriggerState gc_trigger_state{};
|
||
|
ControllerColors colors_state{};
|
||
|
BatteryLevelState battery_state{};
|
||
|
};
|
||
|
enum class ControllerTriggerType {
|
||
|
Button,
|
||
|
Stick,
|
||
|
Trigger,
|
||
|
Motion,
|
||
|
Color,
|
||
|
Battery,
|
||
|
Vibration,
|
||
|
Connected,
|
||
|
Disconnected,
|
||
|
Type,
|
||
|
All,
|
||
|
};
|
||
|
|
||
|
struct ControllerUpdateCallback {
|
||
|
std::function<void(ControllerTriggerType)> on_change;
|
||
|
};
|
||
|
|
||
|
class EmulatedController {
|
||
|
public:
|
||
|
/**
|
||
|
* TODO: Write description
|
||
|
*
|
||
|
* @param npad_id_type
|
||
|
*/
|
||
|
explicit EmulatedController(NpadIdType npad_id_type_);
|
||
|
~EmulatedController();
|
||
|
|
||
|
YUZU_NON_COPYABLE(EmulatedController);
|
||
|
YUZU_NON_MOVEABLE(EmulatedController);
|
||
|
|
||
|
static NpadType MapSettingsTypeToNPad(Settings::ControllerType type);
|
||
|
static Settings::ControllerType MapNPadToSettingsType(NpadType type);
|
||
|
|
||
|
/// Gets the NpadIdType for this controller.
|
||
|
NpadIdType GetNpadIdType() const;
|
||
|
|
||
|
/// Sets the NpadType for this controller.
|
||
|
void SetNpadType(NpadType npad_type_);
|
||
|
|
||
|
/// Gets the NpadType for this controller.
|
||
|
NpadType GetNpadType() const;
|
||
|
|
||
|
void Connect();
|
||
|
void Disconnect();
|
||
|
|
||
|
bool IsConnected() const;
|
||
|
bool IsVibrationEnabled() const;
|
||
|
|
||
|
void ReloadFromSettings();
|
||
|
void ReloadInput();
|
||
|
void UnloadInput();
|
||
|
|
||
|
void EnableConfiguration();
|
||
|
void DisableConfiguration();
|
||
|
bool IsConfiguring() const;
|
||
|
void SaveCurrentConfig();
|
||
|
void RestoreConfig();
|
||
|
|
||
|
std::vector<Common::ParamPackage> GetMappedDevices() const;
|
||
|
|
||
|
Common::ParamPackage GetButtonParam(std::size_t index) const;
|
||
|
Common::ParamPackage GetStickParam(std::size_t index) const;
|
||
|
Common::ParamPackage GetMotionParam(std::size_t index) const;
|
||
|
|
||
|
void SetButtonParam(std::size_t index, Common::ParamPackage param);
|
||
|
void SetStickParam(std::size_t index, Common::ParamPackage param);
|
||
|
void SetMotionParam(std::size_t index, Common::ParamPackage param);
|
||
|
|
||
|
ButtonValues GetButtonsValues() const;
|
||
|
SticksValues GetSticksValues() const;
|
||
|
TriggerValues GetTriggersValues() const;
|
||
|
ControllerMotionValues GetMotionValues() const;
|
||
|
ColorValues GetColorsValues() const;
|
||
|
BatteryValues GetBatteryValues() const;
|
||
|
|
||
|
NpadButtonState GetNpadButtons() const;
|
||
|
DebugPadButton GetDebugPadButtons() const;
|
||
|
AnalogSticks GetSticks() const;
|
||
|
NpadGcTriggerState GetTriggers() const;
|
||
|
MotionState GetMotions() const;
|
||
|
ControllerColors GetColors() const;
|
||
|
BatteryLevelState GetBattery() const;
|
||
|
|
||
|
bool SetVibration(std::size_t device_index, VibrationValue vibration);
|
||
|
int TestVibration(std::size_t device_index);
|
||
|
|
||
|
int SetCallback(ControllerUpdateCallback update_callback);
|
||
|
void DeleteCallback(int key);
|
||
|
|
||
|
private:
|
||
|
/**
|
||
|
* Sets the status of a button. Applies toggle properties to the output.
|
||
|
*
|
||
|
* @param A CallbackStatus and a button index number
|
||
|
*/
|
||
|
void SetButton(Input::CallbackStatus callback, std::size_t index);
|
||
|
void SetStick(Input::CallbackStatus callback, std::size_t index);
|
||
|
void SetTrigger(Input::CallbackStatus callback, std::size_t index);
|
||
|
void SetMotion(Input::CallbackStatus callback, std::size_t index);
|
||
|
void SetBattery(Input::CallbackStatus callback, std::size_t index);
|
||
|
|
||
|
/**
|
||
|
* Triggers a callback that something has changed
|
||
|
*
|
||
|
* @param Input type of the trigger
|
||
|
*/
|
||
|
void TriggerOnChange(ControllerTriggerType type);
|
||
|
|
||
|
NpadIdType npad_id_type;
|
||
|
NpadType npad_type{NpadType::None};
|
||
|
bool is_connected{false};
|
||
|
bool is_configuring{false};
|
||
|
bool is_vibration_enabled{true};
|
||
|
f32 motion_sensitivity{0.01f};
|
||
|
|
||
|
ButtonParams button_params;
|
||
|
StickParams stick_params;
|
||
|
ControllerMotionParams motion_params;
|
||
|
TriggerParams trigger_params;
|
||
|
BatteryParams battery_params;
|
||
|
|
||
|
ButtonDevices button_devices;
|
||
|
StickDevices stick_devices;
|
||
|
ControllerMotionDevices motion_devices;
|
||
|
TriggerDevices trigger_devices;
|
||
|
BatteryDevices battery_devices;
|
||
|
// VibrationDevices vibration_devices;
|
||
|
|
||
|
mutable std::mutex mutex;
|
||
|
std::unordered_map<int, ControllerUpdateCallback> callback_list;
|
||
|
int last_callback_key = 0;
|
||
|
ControllerStatus controller;
|
||
|
};
|
||
|
|
||
|
} // namespace Core::HID
|