summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hid/emulated_controller.cpp119
-rw-r--r--src/core/hid/emulated_controller.h13
-rw-r--r--src/core/hid/hid_types.h18
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp27
-rw-r--r--src/core/hle/service/hid/controllers/npad.h18
5 files changed, 126 insertions, 69 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 4eb5d99bc..b9d16657a 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -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;
+}
+
+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;
}
-int EmulatedController::TestVibration(std::size_t device_index) {
- return 1;
+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;
}
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index 94db9b00b..322d2cab0 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -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;
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index d3f7930c9..f12a14cb8 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -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,
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 03cbd42f4..a2e9ddf4d 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -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 {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 483cae5b6..b0e2f8430 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -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);