summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hid/emulated_console.cpp1
-rw-r--r--src/core/hid/emulated_controller.cpp98
-rw-r--r--src/core/hid/emulated_controller.h18
-rw-r--r--src/core/hid/hid_types.h8
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp77
-rw-r--r--src/core/hle/service/hid/controllers/npad.h3
7 files changed, 151 insertions, 56 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index c65d05041..7f7c8fd59 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -53,7 +53,6 @@ void EmulatedConsole::ReloadInput() {
touch_button_params.Set("x", x);
touch_button_params.Set("y", y);
touch_button_params.Set("touch_id", static_cast<int>(index));
- LOG_ERROR(Common, "{} ", touch_button_params.Serialize());
touch_devices[index] =
Input::CreateDeviceFromString<Input::InputDevice>(touch_button_params.Serialize());
if (!touch_devices[index]) {
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index b04ab4cd8..7ef6ef118 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -54,6 +54,7 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadType type
}
void EmulatedController::ReloadFromSettings() {
+ //LOG_ERROR(Service_HID, "reload config from settings {}", NpadIdTypeToIndex(npad_id_type));
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
@@ -91,6 +92,7 @@ void EmulatedController::ReloadFromSettings() {
}
void EmulatedController::ReloadInput() {
+ //LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type));
// If you load any device here add the equivalent to the UnloadInput() function
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto left_side = button_params[Settings::NativeButton::ZL];
@@ -187,11 +189,29 @@ void EmulatedController::UnloadInput() {
void EmulatedController::EnableConfiguration() {
is_configuring = true;
- SaveCurrentConfig();
+ temporary_is_connected = is_connected;
+ temporary_npad_type = npad_type;
}
void EmulatedController::DisableConfiguration() {
is_configuring = false;
+
+ // Apply temporary npad type to the real controller
+ if (temporary_npad_type != npad_type) {
+ if (is_connected) {
+ Disconnect();
+ }
+ SetNpadType(temporary_npad_type);
+ }
+
+ // Apply temporary connected status to the real controller
+ if (temporary_is_connected != is_connected) {
+ if (temporary_is_connected) {
+ Connect();
+ return;
+ }
+ Disconnect();
+ }
}
bool EmulatedController::IsConfiguring() const {
@@ -199,10 +219,6 @@ bool EmulatedController::IsConfiguring() const {
}
void EmulatedController::SaveCurrentConfig() {
- if (!is_configuring) {
- return;
- }
-
const auto player_index = NpadIdTypeToIndex(npad_id_type);
auto& player = Settings::values.players.GetValue()[player_index];
player.connected = is_connected;
@@ -657,26 +673,47 @@ void EmulatedController::SetLedPattern() {
}
void EmulatedController::Connect() {
- std::lock_guard lock{mutex};
- if (is_connected) {
- LOG_WARNING(Service_HID, "Tried to turn on a connected controller {}", npad_id_type);
- return;
+ {
+ std::lock_guard lock{mutex};
+ if (is_configuring) {
+ temporary_is_connected = true;
+ TriggerOnChange(ControllerTriggerType::Connected);
+ return;
+ }
+
+ if (is_connected) {
+ return;
+ }
+ is_connected = true;
}
- is_connected = true;
+ LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type));
TriggerOnChange(ControllerTriggerType::Connected);
}
void EmulatedController::Disconnect() {
- std::lock_guard lock{mutex};
- if (!is_connected) {
- LOG_WARNING(Service_HID, "Tried to turn off a disconnected controller {}", npad_id_type);
- return;
+ {
+ std::lock_guard lock{mutex};
+ if (is_configuring) {
+ temporary_is_connected = false;
+ LOG_ERROR(Service_HID, "Disconnected temporal controller {}",
+ NpadIdTypeToIndex(npad_id_type));
+ TriggerOnChange(ControllerTriggerType::Disconnected);
+ return;
+ }
+
+ if (!is_connected) {
+ return;
+ }
+ is_connected = false;
}
- is_connected = false;
+ LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type));
TriggerOnChange(ControllerTriggerType::Disconnected);
}
-bool EmulatedController::IsConnected() const {
+bool EmulatedController::IsConnected(bool temporary) const {
+ if (temporary) {
+ return temporary_is_connected;
+ }
return is_connected;
}
@@ -688,16 +725,35 @@ NpadIdType EmulatedController::GetNpadIdType() const {
return npad_id_type;
}
-NpadType EmulatedController::GetNpadType() const {
+NpadType EmulatedController::GetNpadType(bool temporary) const {
+ if (temporary) {
+ return temporary_npad_type;
+ }
return npad_type;
}
void EmulatedController::SetNpadType(NpadType npad_type_) {
- std::lock_guard lock{mutex};
- if (npad_type == npad_type_) {
- return;
+ {
+ std::lock_guard lock{mutex};
+
+ if (is_configuring) {
+ if (temporary_npad_type == npad_type_) {
+ return;
+ }
+ temporary_npad_type = npad_type_;
+ TriggerOnChange(ControllerTriggerType::Type);
+ return;
+ }
+
+ if (npad_type == npad_type_) {
+ return;
+ }
+ if (is_connected) {
+ LOG_WARNING(Service_HID, "Controller {} type changed while it's connected",
+ NpadIdTypeToIndex(npad_id_type));
+ }
+ npad_type = npad_type_;
}
- npad_type = npad_type_;
TriggerOnChange(ControllerTriggerType::Type);
}
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index 096fe1705..6a6dc1892 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -139,8 +139,12 @@ public:
/// Sets the NpadType for this controller
void SetNpadType(NpadType npad_type_);
- /// Gets the NpadType for this controller
- NpadType GetNpadType() const;
+ /**
+ * Gets the NpadType for this controller
+ * @param Returns the temporary value if true
+ * @return NpadType set on the controller
+ */
+ NpadType GetNpadType(bool temporary = false) const;
/// Sets the connected status to true
void Connect();
@@ -148,8 +152,12 @@ public:
/// Sets the connected status to false
void Disconnect();
- /// Returns true if the controller has the connected status
- bool IsConnected() const;
+ /**
+ * Is the emulated connected
+ * @param Returns the temporary value if true
+ * @return true if the controller has the connected status
+ */
+ bool IsConnected(bool temporary = false) const;
/// Returns true if vibration is enabled
bool IsVibrationEnabled() const;
@@ -323,7 +331,9 @@ private:
NpadIdType npad_id_type;
NpadType npad_type{NpadType::None};
+ NpadType temporary_npad_type{NpadType::None};
bool is_connected{false};
+ bool temporary_is_connected{false};
bool is_configuring{false};
bool is_vibration_enabled{true};
f32 motion_sensitivity{0.01f};
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index f12a14cb8..539436283 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -47,9 +47,9 @@ constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
return 6;
case NpadIdType::Player8:
return 7;
- case NpadIdType::Other:
- return 8;
case NpadIdType::Handheld:
+ return 8;
+ case NpadIdType::Other:
return 9;
default:
return 0;
@@ -76,9 +76,9 @@ constexpr NpadIdType IndexToNpadIdType(size_t index) {
case 7:
return NpadIdType::Player8;
case 8:
- return NpadIdType::Other;
- case 9:
return NpadIdType::Handheld;
+ case 9:
+ return NpadIdType::Other;
default:
return NpadIdType::Invalid;
}
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp
index 9d1e6db6a..74a394784 100644
--- a/src/core/hle/service/hid/controllers/controller_base.cpp
+++ b/src/core/hle/service/hid/controllers/controller_base.cpp
@@ -11,7 +11,7 @@ ControllerBase::~ControllerBase() = default;
void ControllerBase::ActivateController() {
if (is_activated) {
- OnRelease();
+ return;
}
is_activated = true;
OnInit();
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index a2e9ddf4d..144abab65 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -125,18 +125,22 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
return;
}
+ auto& controller = controller_data[controller_idx];
+ const auto is_connected = controller.device->IsConnected();
+ const auto npad_type = controller.device->GetNpadType();
switch (type) {
case Core::HID::ControllerTriggerType::Connected:
- InitNewlyAddedController(controller_idx);
- break;
case Core::HID::ControllerTriggerType::Disconnected:
- DisconnectNpadAtIndex(controller_idx);
+ if (is_connected == controller.is_connected) {
+ return;
+ }
+ UpdateControllerAt(npad_type, controller_idx, is_connected);
break;
case Core::HID::ControllerTriggerType::Type: {
- auto& controller = controller_data[controller_idx];
- if (controller.device->IsConnected()) {
- LOG_ERROR(Service_HID, "Controller type changed without turning off the controller");
+ if (npad_type == controller.npad_type) {
+ return;
}
+ // UpdateControllerAt(npad_type, controller_idx, is_connected);
break;
}
default:
@@ -146,6 +150,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
auto& controller = controller_data[controller_idx];
+ LOG_ERROR(Service_HID, "Connect {} {}", controller_idx, controller.is_connected);
const auto controller_type = controller.device->GetNpadType();
auto& shared_memory = controller.shared_memory_entry;
if (controller_type == Core::HID::NpadType::None) {
@@ -235,20 +240,23 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
shared_memory.battery_level_left = battery_level.left.battery_level;
shared_memory.battery_level_right = battery_level.right.battery_level;
+ controller.is_connected = true;
+ controller.device->Connect();
SignalStyleSetChangedEvent(IndexToNPad(controller_idx));
+ WriteEmptyEntry(controller.shared_memory_entry);
}
void Controller_NPad::OnInit() {
+ if (!IsControllerActivated()) {
+ return;
+ }
+
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
controller.styleset_changed_event =
service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
}
- if (!IsControllerActivated()) {
- return;
- }
-
if (system.HIDCore().GetSupportedStyleTag().raw == 0) {
// We want to support all controllers
Core::HID::NpadStyleTag style{};
@@ -277,20 +285,33 @@ void Controller_NPad::OnInit() {
for (auto& controller : controller_data) {
NPadGenericState dummy_pad_state{};
auto& npad = controller.shared_memory_entry;
- for (std::size_t i = 0; i < 17; ++i) {
- dummy_pad_state.sampling_number =
- npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
- npad.fullkey_lifo.WriteNextEntry(dummy_pad_state);
- npad.handheld_lifo.WriteNextEntry(dummy_pad_state);
- npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state);
- npad.joy_left_lifo.WriteNextEntry(dummy_pad_state);
- npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
- npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
- npad.palma_lifo.WriteNextEntry(dummy_pad_state);
+ for (std::size_t i = 0; i < 19; ++i) {
+ WriteEmptyEntry(npad);
}
}
}
+void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) {
+ NPadGenericState dummy_pad_state{};
+ NpadGcTriggerState dummy_gc_state{};
+ dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.fullkey_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.handheld_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.joy_left_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.palma_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.system_ext_lifo.WriteNextEntry(dummy_pad_state);
+ dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
+ npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
+}
+
void Controller_NPad::OnRelease() {
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
@@ -359,6 +380,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
if (!IsControllerActivated()) {
return;
}
+
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
auto& npad = controller.shared_memory_entry;
@@ -366,6 +388,9 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
const auto& controller_type = controller.device->GetNpadType();
if (controller_type == Core::HID::NpadType::None || !controller.device->IsConnected()) {
+ // Refresh shared memory
+ std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
+ &controller.shared_memory_entry, sizeof(NpadInternalState));
continue;
}
const u32 npad_index = static_cast<u32>(i);
@@ -830,14 +855,14 @@ void Controller_NPad::AddNewControllerAt(Core::HID::NpadType controller, std::si
void Controller_NPad::UpdateControllerAt(Core::HID::NpadType type, std::size_t npad_index,
bool connected) {
- auto& controller = controller_data[npad_index].device;
+ auto& controller = controller_data[npad_index];
if (!connected) {
DisconnectNpadAtIndex(npad_index);
return;
}
- controller->SetNpadType(type);
- controller->Connect();
+ controller.device->SetNpadType(type);
+ controller.device->Connect();
InitNewlyAddedController(npad_index);
}
@@ -847,14 +872,13 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) {
void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
auto& controller = controller_data[npad_index];
+ LOG_ERROR(Service_HID, "Disconnect {} {}", npad_index, controller.is_connected);
for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
// Send an empty vibration to stop any vibrations.
VibrateControllerAtIndex(npad_index, device_idx, {});
controller.vibration[device_idx].device_mounted = false;
}
- controller.device->Disconnect();
-
auto& shared_memory_entry = controller.shared_memory_entry;
shared_memory_entry.style_set.raw = 0; // Zero out
shared_memory_entry.device_type.raw = 0;
@@ -868,7 +892,10 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual;
shared_memory_entry.footer_type = AppletFooterUiType::None;
+ controller.is_connected = false;
+ controller.device->Disconnect();
SignalStyleSetChangedEvent(IndexToNPad(npad_index));
+ WriteEmptyEntry(controller.shared_memory_entry);
}
void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index b0e2f8430..d805ccb97 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -417,6 +417,8 @@ private:
std::array<VibrationData, 2> vibration{};
bool unintended_home_button_input_protection{};
+ bool is_connected{};
+ Core::HID::NpadType npad_type{Core::HID::NpadType::None};
// Current pad state
NPadGenericState npad_pad_state{};
@@ -435,6 +437,7 @@ private:
void InitNewlyAddedController(std::size_t controller_idx);
bool IsControllerSupported(Core::HID::NpadType controller) const;
void RequestPadStateUpdate(u32 npad_id);
+ void WriteEmptyEntry(NpadInternalState& npad);
std::atomic<u32> press_state{};