forked from suyu/suyu
hid: Fix controller connection/disconnection
This commit is contained in:
parent
72e5920240
commit
4d308fd0b4
10 changed files with 226 additions and 65 deletions
|
@ -53,7 +53,6 @@ void EmulatedConsole::ReloadInput() {
|
||||||
touch_button_params.Set("x", x);
|
touch_button_params.Set("x", x);
|
||||||
touch_button_params.Set("y", y);
|
touch_button_params.Set("y", y);
|
||||||
touch_button_params.Set("touch_id", static_cast<int>(index));
|
touch_button_params.Set("touch_id", static_cast<int>(index));
|
||||||
LOG_ERROR(Common, "{} ", touch_button_params.Serialize());
|
|
||||||
touch_devices[index] =
|
touch_devices[index] =
|
||||||
Input::CreateDeviceFromString<Input::InputDevice>(touch_button_params.Serialize());
|
Input::CreateDeviceFromString<Input::InputDevice>(touch_button_params.Serialize());
|
||||||
if (!touch_devices[index]) {
|
if (!touch_devices[index]) {
|
||||||
|
|
|
@ -54,6 +54,7 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadType type
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::ReloadFromSettings() {
|
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_index = NpadIdTypeToIndex(npad_id_type);
|
||||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ void EmulatedController::ReloadFromSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::ReloadInput() {
|
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
|
// If you load any device here add the equivalent to the UnloadInput() function
|
||||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||||
const auto left_side = button_params[Settings::NativeButton::ZL];
|
const auto left_side = button_params[Settings::NativeButton::ZL];
|
||||||
|
@ -187,11 +189,29 @@ void EmulatedController::UnloadInput() {
|
||||||
|
|
||||||
void EmulatedController::EnableConfiguration() {
|
void EmulatedController::EnableConfiguration() {
|
||||||
is_configuring = true;
|
is_configuring = true;
|
||||||
SaveCurrentConfig();
|
temporary_is_connected = is_connected;
|
||||||
|
temporary_npad_type = npad_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::DisableConfiguration() {
|
void EmulatedController::DisableConfiguration() {
|
||||||
is_configuring = false;
|
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 {
|
bool EmulatedController::IsConfiguring() const {
|
||||||
|
@ -199,10 +219,6 @@ bool EmulatedController::IsConfiguring() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::SaveCurrentConfig() {
|
void EmulatedController::SaveCurrentConfig() {
|
||||||
if (!is_configuring) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||||
auto& player = Settings::values.players.GetValue()[player_index];
|
auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
player.connected = is_connected;
|
player.connected = is_connected;
|
||||||
|
@ -657,26 +673,47 @@ void EmulatedController::SetLedPattern() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::Connect() {
|
void EmulatedController::Connect() {
|
||||||
|
{
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
|
if (is_configuring) {
|
||||||
|
temporary_is_connected = true;
|
||||||
|
TriggerOnChange(ControllerTriggerType::Connected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_connected) {
|
if (is_connected) {
|
||||||
LOG_WARNING(Service_HID, "Tried to turn on a connected controller {}", npad_id_type);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
is_connected = true;
|
is_connected = true;
|
||||||
|
}
|
||||||
|
LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type));
|
||||||
TriggerOnChange(ControllerTriggerType::Connected);
|
TriggerOnChange(ControllerTriggerType::Connected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::Disconnect() {
|
void EmulatedController::Disconnect() {
|
||||||
|
{
|
||||||
std::lock_guard lock{mutex};
|
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) {
|
if (!is_connected) {
|
||||||
LOG_WARNING(Service_HID, "Tried to turn off a disconnected controller {}", npad_id_type);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
is_connected = false;
|
is_connected = false;
|
||||||
|
}
|
||||||
|
LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type));
|
||||||
TriggerOnChange(ControllerTriggerType::Disconnected);
|
TriggerOnChange(ControllerTriggerType::Disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::IsConnected() const {
|
bool EmulatedController::IsConnected(bool temporary) const {
|
||||||
|
if (temporary) {
|
||||||
|
return temporary_is_connected;
|
||||||
|
}
|
||||||
return is_connected;
|
return is_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,16 +725,35 @@ NpadIdType EmulatedController::GetNpadIdType() const {
|
||||||
return npad_id_type;
|
return npad_id_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpadType EmulatedController::GetNpadType() const {
|
NpadType EmulatedController::GetNpadType(bool temporary) const {
|
||||||
|
if (temporary) {
|
||||||
|
return temporary_npad_type;
|
||||||
|
}
|
||||||
return npad_type;
|
return npad_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::SetNpadType(NpadType npad_type_) {
|
void EmulatedController::SetNpadType(NpadType npad_type_) {
|
||||||
|
{
|
||||||
std::lock_guard lock{mutex};
|
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_) {
|
if (npad_type == npad_type_) {
|
||||||
return;
|
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);
|
TriggerOnChange(ControllerTriggerType::Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,8 +139,12 @@ public:
|
||||||
/// Sets the NpadType for this controller
|
/// Sets the NpadType for this controller
|
||||||
void SetNpadType(NpadType npad_type_);
|
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
|
/// Sets the connected status to true
|
||||||
void Connect();
|
void Connect();
|
||||||
|
@ -148,8 +152,12 @@ public:
|
||||||
/// Sets the connected status to false
|
/// Sets the connected status to false
|
||||||
void Disconnect();
|
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
|
/// Returns true if vibration is enabled
|
||||||
bool IsVibrationEnabled() const;
|
bool IsVibrationEnabled() const;
|
||||||
|
@ -323,7 +331,9 @@ private:
|
||||||
|
|
||||||
NpadIdType npad_id_type;
|
NpadIdType npad_id_type;
|
||||||
NpadType npad_type{NpadType::None};
|
NpadType npad_type{NpadType::None};
|
||||||
|
NpadType temporary_npad_type{NpadType::None};
|
||||||
bool is_connected{false};
|
bool is_connected{false};
|
||||||
|
bool temporary_is_connected{false};
|
||||||
bool is_configuring{false};
|
bool is_configuring{false};
|
||||||
bool is_vibration_enabled{true};
|
bool is_vibration_enabled{true};
|
||||||
f32 motion_sensitivity{0.01f};
|
f32 motion_sensitivity{0.01f};
|
||||||
|
|
|
@ -47,9 +47,9 @@ constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
|
||||||
return 6;
|
return 6;
|
||||||
case NpadIdType::Player8:
|
case NpadIdType::Player8:
|
||||||
return 7;
|
return 7;
|
||||||
case NpadIdType::Other:
|
|
||||||
return 8;
|
|
||||||
case NpadIdType::Handheld:
|
case NpadIdType::Handheld:
|
||||||
|
return 8;
|
||||||
|
case NpadIdType::Other:
|
||||||
return 9;
|
return 9;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -76,9 +76,9 @@ constexpr NpadIdType IndexToNpadIdType(size_t index) {
|
||||||
case 7:
|
case 7:
|
||||||
return NpadIdType::Player8;
|
return NpadIdType::Player8;
|
||||||
case 8:
|
case 8:
|
||||||
return NpadIdType::Other;
|
|
||||||
case 9:
|
|
||||||
return NpadIdType::Handheld;
|
return NpadIdType::Handheld;
|
||||||
|
case 9:
|
||||||
|
return NpadIdType::Other;
|
||||||
default:
|
default:
|
||||||
return NpadIdType::Invalid;
|
return NpadIdType::Invalid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ ControllerBase::~ControllerBase() = default;
|
||||||
|
|
||||||
void ControllerBase::ActivateController() {
|
void ControllerBase::ActivateController() {
|
||||||
if (is_activated) {
|
if (is_activated) {
|
||||||
OnRelease();
|
return;
|
||||||
}
|
}
|
||||||
is_activated = true;
|
is_activated = true;
|
||||||
OnInit();
|
OnInit();
|
||||||
|
|
|
@ -125,18 +125,22 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& controller = controller_data[controller_idx];
|
||||||
|
const auto is_connected = controller.device->IsConnected();
|
||||||
|
const auto npad_type = controller.device->GetNpadType();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Core::HID::ControllerTriggerType::Connected:
|
case Core::HID::ControllerTriggerType::Connected:
|
||||||
InitNewlyAddedController(controller_idx);
|
|
||||||
break;
|
|
||||||
case Core::HID::ControllerTriggerType::Disconnected:
|
case Core::HID::ControllerTriggerType::Disconnected:
|
||||||
DisconnectNpadAtIndex(controller_idx);
|
if (is_connected == controller.is_connected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateControllerAt(npad_type, controller_idx, is_connected);
|
||||||
break;
|
break;
|
||||||
case Core::HID::ControllerTriggerType::Type: {
|
case Core::HID::ControllerTriggerType::Type: {
|
||||||
auto& controller = controller_data[controller_idx];
|
if (npad_type == controller.npad_type) {
|
||||||
if (controller.device->IsConnected()) {
|
return;
|
||||||
LOG_ERROR(Service_HID, "Controller type changed without turning off the controller");
|
|
||||||
}
|
}
|
||||||
|
// UpdateControllerAt(npad_type, controller_idx, is_connected);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -146,6 +150,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
|
||||||
|
|
||||||
void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
|
void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
|
||||||
auto& controller = controller_data[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();
|
const auto controller_type = controller.device->GetNpadType();
|
||||||
auto& shared_memory = controller.shared_memory_entry;
|
auto& shared_memory = controller.shared_memory_entry;
|
||||||
if (controller_type == Core::HID::NpadType::None) {
|
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_left = battery_level.left.battery_level;
|
||||||
shared_memory.battery_level_right = battery_level.right.battery_level;
|
shared_memory.battery_level_right = battery_level.right.battery_level;
|
||||||
|
|
||||||
|
controller.is_connected = true;
|
||||||
|
controller.device->Connect();
|
||||||
SignalStyleSetChangedEvent(IndexToNPad(controller_idx));
|
SignalStyleSetChangedEvent(IndexToNPad(controller_idx));
|
||||||
|
WriteEmptyEntry(controller.shared_memory_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::OnInit() {
|
void Controller_NPad::OnInit() {
|
||||||
|
if (!IsControllerActivated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
controller.styleset_changed_event =
|
controller.styleset_changed_event =
|
||||||
service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
|
service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsControllerActivated()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (system.HIDCore().GetSupportedStyleTag().raw == 0) {
|
if (system.HIDCore().GetSupportedStyleTag().raw == 0) {
|
||||||
// We want to support all controllers
|
// We want to support all controllers
|
||||||
Core::HID::NpadStyleTag style{};
|
Core::HID::NpadStyleTag style{};
|
||||||
|
@ -277,18 +285,31 @@ void Controller_NPad::OnInit() {
|
||||||
for (auto& controller : controller_data) {
|
for (auto& controller : controller_data) {
|
||||||
NPadGenericState dummy_pad_state{};
|
NPadGenericState dummy_pad_state{};
|
||||||
auto& npad = controller.shared_memory_entry;
|
auto& npad = controller.shared_memory_entry;
|
||||||
for (std::size_t i = 0; i < 17; ++i) {
|
for (std::size_t i = 0; i < 19; ++i) {
|
||||||
dummy_pad_state.sampling_number =
|
WriteEmptyEntry(npad);
|
||||||
npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
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);
|
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);
|
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);
|
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);
|
npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
|
||||||
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);
|
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() {
|
void Controller_NPad::OnRelease() {
|
||||||
|
@ -359,6 +380,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||||
if (!IsControllerActivated()) {
|
if (!IsControllerActivated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
for (std::size_t i = 0; i < controller_data.size(); ++i) {
|
||||||
auto& controller = controller_data[i];
|
auto& controller = controller_data[i];
|
||||||
auto& npad = controller.shared_memory_entry;
|
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();
|
const auto& controller_type = controller.device->GetNpadType();
|
||||||
|
|
||||||
if (controller_type == Core::HID::NpadType::None || !controller.device->IsConnected()) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
const u32 npad_index = static_cast<u32>(i);
|
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,
|
void Controller_NPad::UpdateControllerAt(Core::HID::NpadType type, std::size_t npad_index,
|
||||||
bool connected) {
|
bool connected) {
|
||||||
auto& controller = controller_data[npad_index].device;
|
auto& controller = controller_data[npad_index];
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
DisconnectNpadAtIndex(npad_index);
|
DisconnectNpadAtIndex(npad_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller->SetNpadType(type);
|
controller.device->SetNpadType(type);
|
||||||
controller->Connect();
|
controller.device->Connect();
|
||||||
InitNewlyAddedController(npad_index);
|
InitNewlyAddedController(npad_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,14 +872,13 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) {
|
||||||
|
|
||||||
void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
|
void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
|
||||||
auto& controller = controller_data[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) {
|
for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
|
||||||
// Send an empty vibration to stop any vibrations.
|
// Send an empty vibration to stop any vibrations.
|
||||||
VibrateControllerAtIndex(npad_index, device_idx, {});
|
VibrateControllerAtIndex(npad_index, device_idx, {});
|
||||||
controller.vibration[device_idx].device_mounted = false;
|
controller.vibration[device_idx].device_mounted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.device->Disconnect();
|
|
||||||
|
|
||||||
auto& shared_memory_entry = controller.shared_memory_entry;
|
auto& shared_memory_entry = controller.shared_memory_entry;
|
||||||
shared_memory_entry.style_set.raw = 0; // Zero out
|
shared_memory_entry.style_set.raw = 0; // Zero out
|
||||||
shared_memory_entry.device_type.raw = 0;
|
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.assignment_mode = NpadJoyAssignmentMode::Dual;
|
||||||
shared_memory_entry.footer_type = AppletFooterUiType::None;
|
shared_memory_entry.footer_type = AppletFooterUiType::None;
|
||||||
|
|
||||||
|
controller.is_connected = false;
|
||||||
|
controller.device->Disconnect();
|
||||||
SignalStyleSetChangedEvent(IndexToNPad(npad_index));
|
SignalStyleSetChangedEvent(IndexToNPad(npad_index));
|
||||||
|
WriteEmptyEntry(controller.shared_memory_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) {
|
void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) {
|
||||||
|
|
|
@ -417,6 +417,8 @@ private:
|
||||||
|
|
||||||
std::array<VibrationData, 2> vibration{};
|
std::array<VibrationData, 2> vibration{};
|
||||||
bool unintended_home_button_input_protection{};
|
bool unintended_home_button_input_protection{};
|
||||||
|
bool is_connected{};
|
||||||
|
Core::HID::NpadType npad_type{Core::HID::NpadType::None};
|
||||||
|
|
||||||
// Current pad state
|
// Current pad state
|
||||||
NPadGenericState npad_pad_state{};
|
NPadGenericState npad_pad_state{};
|
||||||
|
@ -435,6 +437,7 @@ private:
|
||||||
void InitNewlyAddedController(std::size_t controller_idx);
|
void InitNewlyAddedController(std::size_t controller_idx);
|
||||||
bool IsControllerSupported(Core::HID::NpadType controller) const;
|
bool IsControllerSupported(Core::HID::NpadType controller) const;
|
||||||
void RequestPadStateUpdate(u32 npad_id);
|
void RequestPadStateUpdate(u32 npad_id);
|
||||||
|
void WriteEmptyEntry(NpadInternalState& npad);
|
||||||
|
|
||||||
std::atomic<u32> press_state{};
|
std::atomic<u32> press_state{};
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, Co
|
||||||
player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i]));
|
player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i]));
|
||||||
player_tabs[i]->layout()->addWidget(player_controllers[i]);
|
player_tabs[i]->layout()->addWidget(player_controllers[i]);
|
||||||
connect(player_controllers[i], &ConfigureInputPlayer::Connected, [&, i](bool is_connected) {
|
connect(player_controllers[i], &ConfigureInputPlayer::Connected, [&, i](bool is_connected) {
|
||||||
|
// Ensures that the controllers are always connected in sequential order
|
||||||
if (is_connected) {
|
if (is_connected) {
|
||||||
for (std::size_t index = 0; index <= i; ++index) {
|
for (std::size_t index = 0; index <= i; ++index) {
|
||||||
player_connected[index]->setChecked(is_connected);
|
player_connected[index]->setChecked(is_connected);
|
||||||
|
|
|
@ -143,8 +143,26 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||||
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()),
|
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()),
|
||||||
bottom_row(bottom_row), system{system_} {
|
bottom_row(bottom_row), system{system_} {
|
||||||
|
|
||||||
|
if (player_index == 0) {
|
||||||
|
auto* emulated_controller_p1 =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
|
auto* emulated_controller_hanheld =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
emulated_controller_p1->SaveCurrentConfig();
|
||||||
|
emulated_controller_p1->EnableConfiguration();
|
||||||
|
emulated_controller_hanheld->SaveCurrentConfig();
|
||||||
|
emulated_controller_hanheld->EnableConfiguration();
|
||||||
|
if (emulated_controller_hanheld->IsConnected(true)) {
|
||||||
|
emulated_controller_p1->Disconnect();
|
||||||
|
emulated_controller = emulated_controller_hanheld;
|
||||||
|
} else {
|
||||||
|
emulated_controller = emulated_controller_p1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
emulated_controller = system_.HIDCore().GetEmulatedControllerByIndex(player_index);
|
emulated_controller = system_.HIDCore().GetEmulatedControllerByIndex(player_index);
|
||||||
|
emulated_controller->SaveCurrentConfig();
|
||||||
emulated_controller->EnableConfiguration();
|
emulated_controller->EnableConfiguration();
|
||||||
|
}
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
@ -460,13 +478,36 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||||
UpdateControllerEnabledButtons();
|
UpdateControllerEnabledButtons();
|
||||||
UpdateControllerButtonNames();
|
UpdateControllerButtonNames();
|
||||||
UpdateMotionButtons();
|
UpdateMotionButtons();
|
||||||
connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) {
|
connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this, player_index](int) {
|
||||||
UpdateControllerAvailableButtons();
|
UpdateControllerAvailableButtons();
|
||||||
UpdateControllerEnabledButtons();
|
UpdateControllerEnabledButtons();
|
||||||
UpdateControllerButtonNames();
|
UpdateControllerButtonNames();
|
||||||
UpdateMotionButtons();
|
UpdateMotionButtons();
|
||||||
emulated_controller->SetNpadType(
|
const Core::HID::NpadType type = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex());
|
||||||
GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()));
|
|
||||||
|
if (player_index == 0) {
|
||||||
|
auto* emulated_controller_p1 =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
|
auto* emulated_controller_hanheld =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
bool is_connected = emulated_controller->IsConnected(true);
|
||||||
|
|
||||||
|
emulated_controller_p1->SetNpadType(type);
|
||||||
|
emulated_controller_hanheld->SetNpadType(type);
|
||||||
|
if (is_connected) {
|
||||||
|
if (type == Core::HID::NpadType::Handheld) {
|
||||||
|
emulated_controller_p1->Disconnect();
|
||||||
|
emulated_controller_hanheld->Connect();
|
||||||
|
emulated_controller = emulated_controller_hanheld;
|
||||||
|
} else {
|
||||||
|
emulated_controller_hanheld->Disconnect();
|
||||||
|
emulated_controller_p1->Connect();
|
||||||
|
emulated_controller = emulated_controller_p1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->controllerFrame->SetController(emulated_controller);
|
||||||
|
}
|
||||||
|
emulated_controller->SetNpadType(type);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this,
|
connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this,
|
||||||
|
@ -504,11 +545,35 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureInputPlayer::~ConfigureInputPlayer() {
|
ConfigureInputPlayer::~ConfigureInputPlayer() {
|
||||||
|
if (player_index == 0) {
|
||||||
|
auto* emulated_controller_p1 =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
|
auto* emulated_controller_hanheld =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
emulated_controller_p1->DisableConfiguration();
|
||||||
|
emulated_controller_hanheld->DisableConfiguration();
|
||||||
|
} else {
|
||||||
emulated_controller->DisableConfiguration();
|
emulated_controller->DisableConfiguration();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ConfigureInputPlayer::ApplyConfiguration() {
|
void ConfigureInputPlayer::ApplyConfiguration() {
|
||||||
|
if (player_index == 0) {
|
||||||
|
auto* emulated_controller_p1 =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
|
auto* emulated_controller_hanheld =
|
||||||
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
emulated_controller_p1->DisableConfiguration();
|
||||||
|
emulated_controller_p1->SaveCurrentConfig();
|
||||||
|
emulated_controller_p1->EnableConfiguration();
|
||||||
|
emulated_controller_hanheld->DisableConfiguration();
|
||||||
|
emulated_controller_hanheld->SaveCurrentConfig();
|
||||||
|
emulated_controller_hanheld->EnableConfiguration();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emulated_controller->DisableConfiguration();
|
||||||
emulated_controller->SaveCurrentConfig();
|
emulated_controller->SaveCurrentConfig();
|
||||||
|
emulated_controller->EnableConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInputPlayer::showEvent(QShowEvent* event) {
|
void ConfigureInputPlayer::showEvent(QShowEvent* event) {
|
||||||
|
@ -535,9 +600,9 @@ void ConfigureInputPlayer::RetranslateUI() {
|
||||||
void ConfigureInputPlayer::LoadConfiguration() {
|
void ConfigureInputPlayer::LoadConfiguration() {
|
||||||
UpdateUI();
|
UpdateUI();
|
||||||
UpdateInputDeviceCombobox();
|
UpdateInputDeviceCombobox();
|
||||||
const int comboBoxIndex = GetIndexFromControllerType(emulated_controller->GetNpadType());
|
const int comboBoxIndex = GetIndexFromControllerType(emulated_controller->GetNpadType(true));
|
||||||
ui->comboControllerType->setCurrentIndex(comboBoxIndex);
|
ui->comboControllerType->setCurrentIndex(comboBoxIndex);
|
||||||
ui->groupConnectedController->setChecked(emulated_controller->IsConnected());
|
ui->groupConnectedController->setChecked(emulated_controller->IsConnected(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInputPlayer::ConnectPlayer(bool connected) {
|
void ConfigureInputPlayer::ConnectPlayer(bool connected) {
|
||||||
|
|
|
@ -145,7 +145,7 @@ void PlayerControlPreview::ControllerUpdate(Core::HID::ControllerTriggerType typ
|
||||||
needs_redraw = true;
|
needs_redraw = true;
|
||||||
break;
|
break;
|
||||||
case Core::HID::ControllerTriggerType::Type:
|
case Core::HID::ControllerTriggerType::Type:
|
||||||
controller_type = controller->GetNpadType();
|
controller_type = controller->GetNpadType(true);
|
||||||
needs_redraw = true;
|
needs_redraw = true;
|
||||||
break;
|
break;
|
||||||
case Core::HID::ControllerTriggerType::Color:
|
case Core::HID::ControllerTriggerType::Color:
|
||||||
|
|
Loading…
Reference in a new issue