core/hid: Add output devices
This commit is contained in:
parent
e14ae06391
commit
06a5ef5874
20 changed files with 313 additions and 145 deletions
|
@ -66,12 +66,32 @@ void EmulatedController::ReloadFromSettings() {
|
|||
for (std::size_t index = 0; index < player.motions.size(); ++index) {
|
||||
motion_params[index] = Common::ParamPackage(player.motions[index]);
|
||||
}
|
||||
|
||||
controller.colors_state.left = {
|
||||
.body = player.body_color_left,
|
||||
.button = player.button_color_left,
|
||||
};
|
||||
|
||||
controller.colors_state.right = {
|
||||
.body = player.body_color_right,
|
||||
.button = player.button_color_right,
|
||||
};
|
||||
|
||||
controller.colors_state.fullkey = controller.colors_state.left;
|
||||
|
||||
SetNpadType(MapSettingsTypeToNPad(player.controller_type));
|
||||
|
||||
if (player.connected) {
|
||||
Connect();
|
||||
} else {
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
ReloadInput();
|
||||
}
|
||||
|
||||
void EmulatedController::ReloadInput() {
|
||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||
const auto left_side = button_params[Settings::NativeButton::ZL];
|
||||
const auto right_side = button_params[Settings::NativeButton::ZR];
|
||||
|
||||
|
@ -90,21 +110,13 @@ void EmulatedController::ReloadInput() {
|
|||
trigger_devices[1] =
|
||||
Input::CreateDevice<Input::InputDevice>(button_params[Settings::NativeButton::ZR]);
|
||||
|
||||
controller.colors_state.left = {
|
||||
.body = player.body_color_left,
|
||||
.button = player.button_color_left,
|
||||
};
|
||||
|
||||
controller.colors_state.right = {
|
||||
.body = player.body_color_right,
|
||||
.button = player.button_color_right,
|
||||
};
|
||||
|
||||
controller.colors_state.fullkey = controller.colors_state.left;
|
||||
|
||||
battery_devices[0] = Input::CreateDevice<Input::InputDevice>(left_side);
|
||||
battery_devices[1] = Input::CreateDevice<Input::InputDevice>(right_side);
|
||||
|
||||
button_params[Settings::NativeButton::ZL].Set("output",true);
|
||||
output_devices[0] =
|
||||
Input::CreateDevice<Input::OutputDevice>(button_params[Settings::NativeButton::ZL]);
|
||||
|
||||
for (std::size_t index = 0; index < button_devices.size(); ++index) {
|
||||
if (!button_devices[index]) {
|
||||
continue;
|
||||
|
@ -149,14 +161,6 @@ void EmulatedController::ReloadInput() {
|
|||
[this, index](Input::CallbackStatus callback) { SetMotion(callback, index); }};
|
||||
motion_devices[index]->SetCallback(motion_callback);
|
||||
}
|
||||
|
||||
SetNpadType(MapSettingsTypeToNPad(player.controller_type));
|
||||
|
||||
if (player.connected) {
|
||||
Connect();
|
||||
} else {
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedController::UnloadInput() {
|
||||
|
@ -197,7 +201,8 @@ void EmulatedController::SaveCurrentConfig() {
|
|||
|
||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||
auto& player = Settings::values.players.GetValue()[player_index];
|
||||
|
||||
player.connected = is_connected;
|
||||
player.controller_type = MapNPadToSettingsType(npad_type);
|
||||
for (std::size_t index = 0; index < player.buttons.size(); ++index) {
|
||||
player.buttons[index] = button_params[index].Serialize();
|
||||
}
|
||||
|
@ -601,13 +606,50 @@ void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t
|
|||
TriggerOnChange(ControllerTriggerType::Battery);
|
||||
}
|
||||
|
||||
bool EmulatedController::SetVibration([[maybe_unused]] std::size_t device_index,
|
||||
[[maybe_unused]] VibrationValue vibration) {
|
||||
return false;
|
||||
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
|
||||
if (!output_devices[device_index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Input::VibrationStatus status = {
|
||||
.low_amplitude = vibration.high_amplitude,
|
||||
.low_frequency = vibration.high_amplitude,
|
||||
.high_amplitude = vibration.high_amplitude,
|
||||
.high_frequency = vibration.high_amplitude,
|
||||
};
|
||||
return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None;
|
||||
}
|
||||
|
||||
int EmulatedController::TestVibration(std::size_t device_index) {
|
||||
return 1;
|
||||
bool EmulatedController::TestVibration(std::size_t device_index) {
|
||||
if (!output_devices[device_index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a slight vibration to test for rumble support
|
||||
constexpr Input::VibrationStatus status = {
|
||||
.low_amplitude = 0.001f,
|
||||
.low_frequency = 160.0f,
|
||||
.high_amplitude = 0.001f,
|
||||
.high_frequency = 320.0f,
|
||||
};
|
||||
return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None;
|
||||
}
|
||||
|
||||
void EmulatedController::SetLedPattern() {
|
||||
for (auto& device : output_devices) {
|
||||
if (!device) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const LedPattern pattern = GetLedPattern();
|
||||
const Input::LedStatus status = {
|
||||
.led_1 = pattern.position1 != 0,
|
||||
.led_2 = pattern.position2 != 0,
|
||||
.led_3 = pattern.position3 != 0,
|
||||
.led_4 = pattern.position4 != 0,
|
||||
};
|
||||
device->SetLED(status);
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedController::Connect() {
|
||||
|
@ -655,6 +697,29 @@ void EmulatedController::SetNpadType(NpadType npad_type_) {
|
|||
TriggerOnChange(ControllerTriggerType::Type);
|
||||
}
|
||||
|
||||
LedPattern EmulatedController::GetLedPattern() const {
|
||||
switch (npad_id_type) {
|
||||
case NpadIdType::Player1:
|
||||
return LedPattern{1, 0, 0, 0};
|
||||
case NpadIdType::Player2:
|
||||
return LedPattern{1, 1, 0, 0};
|
||||
case NpadIdType::Player3:
|
||||
return LedPattern{1, 1, 1, 0};
|
||||
case NpadIdType::Player4:
|
||||
return LedPattern{1, 1, 1, 1};
|
||||
case NpadIdType::Player5:
|
||||
return LedPattern{1, 0, 0, 1};
|
||||
case NpadIdType::Player6:
|
||||
return LedPattern{1, 0, 1, 0};
|
||||
case NpadIdType::Player7:
|
||||
return LedPattern{1, 0, 1, 1};
|
||||
case NpadIdType::Player8:
|
||||
return LedPattern{0, 1, 1, 0};
|
||||
default:
|
||||
return LedPattern{0, 0, 0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
ButtonValues EmulatedController::GetButtonsValues() const {
|
||||
return controller.button_values;
|
||||
}
|
||||
|
|
|
@ -33,12 +33,14 @@ using ControllerMotionDevices =
|
|||
using TriggerDevices =
|
||||
std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
|
||||
using BatteryDevices = std::array<std::unique_ptr<Input::InputDevice>, 2>;
|
||||
using OutputDevices = std::array<std::unique_ptr<Input::OutputDevice>, 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 OutputParams = std::array<Common::ParamPackage, 2>;
|
||||
|
||||
using ButtonValues = std::array<Input::ButtonStatus, Settings::NativeButton::NumButtons>;
|
||||
using SticksValues = std::array<Input::StickStatus, Settings::NativeAnalog::NumAnalogs>;
|
||||
|
@ -94,6 +96,7 @@ struct ControllerStatus {
|
|||
ControllerColors colors_state{};
|
||||
BatteryLevelState battery_state{};
|
||||
};
|
||||
|
||||
enum class ControllerTriggerType {
|
||||
Button,
|
||||
Stick,
|
||||
|
@ -137,6 +140,9 @@ public:
|
|||
/// Gets the NpadType for this controller.
|
||||
NpadType GetNpadType() const;
|
||||
|
||||
/// Gets the NpadType for this controller.
|
||||
LedPattern GetLedPattern() const;
|
||||
|
||||
void Connect();
|
||||
void Disconnect();
|
||||
|
||||
|
@ -179,7 +185,9 @@ public:
|
|||
BatteryLevelState GetBattery() const;
|
||||
|
||||
bool SetVibration(std::size_t device_index, VibrationValue vibration);
|
||||
int TestVibration(std::size_t device_index);
|
||||
bool TestVibration(std::size_t device_index);
|
||||
|
||||
void SetLedPattern();
|
||||
|
||||
int SetCallback(ControllerUpdateCallback update_callback);
|
||||
void DeleteCallback(int key);
|
||||
|
@ -215,13 +223,14 @@ private:
|
|||
ControllerMotionParams motion_params;
|
||||
TriggerParams trigger_params;
|
||||
BatteryParams battery_params;
|
||||
OutputParams output_params;
|
||||
|
||||
ButtonDevices button_devices;
|
||||
StickDevices stick_devices;
|
||||
ControllerMotionDevices motion_devices;
|
||||
TriggerDevices trigger_devices;
|
||||
BatteryDevices battery_devices;
|
||||
// VibrationDevices vibration_devices;
|
||||
OutputDevices output_devices;
|
||||
|
||||
mutable std::mutex mutex;
|
||||
std::unordered_map<int, ControllerUpdateCallback> callback_list;
|
||||
|
|
|
@ -112,6 +112,8 @@ struct NpadStyleTag {
|
|||
BitField<7, 1, u32> lark;
|
||||
BitField<8, 1, u32> handheld_lark;
|
||||
BitField<9, 1, u32> lucia;
|
||||
BitField<10, 1, u32> lagoon;
|
||||
BitField<11, 1, u32> lager;
|
||||
BitField<29, 1, u32> system_ext;
|
||||
BitField<30, 1, u32> system;
|
||||
};
|
||||
|
@ -175,6 +177,22 @@ struct NpadPowerInfo {
|
|||
};
|
||||
static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
|
||||
|
||||
struct LedPattern {
|
||||
explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
|
||||
position1.Assign(light1);
|
||||
position2.Assign(light2);
|
||||
position3.Assign(light3);
|
||||
position4.Assign(light4);
|
||||
}
|
||||
union {
|
||||
u64 raw{};
|
||||
BitField<0, 1, u64> position1;
|
||||
BitField<1, 1, u64> position2;
|
||||
BitField<2, 1, u64> position3;
|
||||
BitField<3, 1, u64> position4;
|
||||
};
|
||||
};
|
||||
|
||||
// This is nn::hid::NpadButton
|
||||
enum class NpadButton : u64 {
|
||||
None = 0,
|
||||
|
|
|
@ -796,7 +796,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index,
|
|||
}
|
||||
|
||||
controller.vibration[device_index].device_mounted =
|
||||
controller.device->TestVibration(device_index) == 1;
|
||||
controller.device->TestVibration(device_index);
|
||||
}
|
||||
|
||||
void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
|
||||
|
@ -954,31 +954,12 @@ bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) {
|
|||
return true;
|
||||
}
|
||||
|
||||
Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
|
||||
Core::HID::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
|
||||
if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) {
|
||||
// These are controllers without led patterns
|
||||
return LedPattern{0, 0, 0, 0};
|
||||
}
|
||||
switch (npad_id) {
|
||||
case 0:
|
||||
return LedPattern{1, 0, 0, 0};
|
||||
case 1:
|
||||
return LedPattern{1, 1, 0, 0};
|
||||
case 2:
|
||||
return LedPattern{1, 1, 1, 0};
|
||||
case 3:
|
||||
return LedPattern{1, 1, 1, 1};
|
||||
case 4:
|
||||
return LedPattern{1, 0, 0, 1};
|
||||
case 5:
|
||||
return LedPattern{1, 0, 1, 0};
|
||||
case 6:
|
||||
return LedPattern{1, 0, 1, 1};
|
||||
case 7:
|
||||
return LedPattern{0, 1, 1, 0};
|
||||
default:
|
||||
return LedPattern{0, 0, 0, 0};
|
||||
return Core::HID::LedPattern{0, 0, 0, 0};
|
||||
}
|
||||
return controller_data[npad_id].device->GetLedPattern();
|
||||
}
|
||||
|
||||
bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const {
|
||||
|
|
|
@ -115,22 +115,6 @@ public:
|
|||
.freq_high = 320.0f,
|
||||
};
|
||||
|
||||
struct LedPattern {
|
||||
explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
|
||||
position1.Assign(light1);
|
||||
position2.Assign(light2);
|
||||
position3.Assign(light3);
|
||||
position4.Assign(light4);
|
||||
}
|
||||
union {
|
||||
u64 raw{};
|
||||
BitField<0, 1, u64> position1;
|
||||
BitField<1, 1, u64> position2;
|
||||
BitField<2, 1, u64> position3;
|
||||
BitField<3, 1, u64> position4;
|
||||
};
|
||||
};
|
||||
|
||||
void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
|
||||
Core::HID::NpadStyleTag GetSupportedStyleSet() const;
|
||||
|
||||
|
@ -186,7 +170,7 @@ public:
|
|||
void SetSixAxisFusionParameters(f32 parameter1, f32 parameter2);
|
||||
std::pair<f32, f32> GetSixAxisFusionParameters();
|
||||
void ResetSixAxisFusionParameters();
|
||||
LedPattern GetLedPattern(u32 npad_id);
|
||||
Core::HID::LedPattern GetLedPattern(u32 npad_id);
|
||||
bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
|
||||
void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id);
|
||||
void SetAnalogStickUseCenterClamp(bool use_center_clamp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue