diff --git a/pcsx2-qt/Settings/ControllerSettingsDialog.cpp b/pcsx2-qt/Settings/ControllerSettingsDialog.cpp index 7b606edea4..baf9fcf1db 100644 --- a/pcsx2-qt/Settings/ControllerSettingsDialog.cpp +++ b/pcsx2-qt/Settings/ControllerSettingsDialog.cpp @@ -128,6 +128,7 @@ void ControllerSettingsDialog::onNewProfileClicked() // from global auto lock = Host::GetSettingsLock(); PAD::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true, false); + USB::CopyConfiguration(&temp_si, *Host::Internal::GetBaseSettingsLayer(), true, true); } else { @@ -135,6 +136,7 @@ void ControllerSettingsDialog::onNewProfileClicked() const bool copy_hotkey_bindings = m_profile_interface->GetBoolValue("Pad", "UseProfileHotkeyBindings", false); temp_si.SetBoolValue("Pad", "UseProfileHotkeyBindings", copy_hotkey_bindings); PAD::CopyConfiguration(&temp_si, *m_profile_interface, true, true, copy_hotkey_bindings); + USB::CopyConfiguration(&temp_si, *m_profile_interface, true, true); } } @@ -163,6 +165,7 @@ void ControllerSettingsDialog::onLoadProfileClicked() { auto lock = Host::GetSettingsLock(); PAD::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true, false); + USB::CopyConfiguration(Host::Internal::GetBaseSettingsLayer(), *m_profile_interface, true, true); } Host::CommitBaseSettingChanges(); diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 6a6e8969fe..e292c15a85 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -66,6 +66,10 @@ struct SettingInfo float FloatMinValue() const; float FloatMaxValue() const; float FloatStepValue() const; + + void SetDefaultValue(SettingsInterface* si, const char* section, const char* key) const; + void CopyValue(SettingsInterface* dest_si, const SettingsInterface& src_si, + const char* section, const char* key) const; }; enum class GenericInputBinding : u8; diff --git a/pcsx2/ImGui/FullscreenUI.cpp b/pcsx2/ImGui/FullscreenUI.cpp index e72d08977c..e413a7009f 100644 --- a/pcsx2/ImGui/FullscreenUI.cpp +++ b/pcsx2/ImGui/FullscreenUI.cpp @@ -3590,6 +3590,7 @@ void FullscreenUI::CopyGlobalControllerSettingsToGame() SettingsInterface* ssi = GetEditingSettingsInterface(false); PAD::CopyConfiguration(dsi, *ssi, true, true, false); + USB::CopyConfiguration(dsi, *ssi, true, true); SetSettingsChanged(dsi); ShowToast(std::string(), "Per-game controller configuration initialized with global settings."); @@ -3601,6 +3602,7 @@ void FullscreenUI::ResetControllerSettings() PAD::SetDefaultControllerConfig(*dsi); PAD::SetDefaultHotkeyConfig(*dsi); + USB::SetDefaultConfiguration(dsi); ShowToast(std::string(), "Controller settings reset to default."); } @@ -3633,6 +3635,7 @@ void FullscreenUI::DoLoadInputProfile() auto lock = Host::GetSettingsLock(); SettingsInterface* dsi = GetEditingSettingsInterface(); PAD::CopyConfiguration(dsi, ssi, true, true, IsEditingGameSettings(dsi)); + USB::CopyConfiguration(dsi, ssi, true, true); SetSettingsChanged(dsi); ShowToast(std::string(), fmt::format("Input profile '{}' loaded.", title)); CloseChoiceDialog(); @@ -3646,6 +3649,7 @@ void FullscreenUI::DoSaveInputProfile(const std::string& name) auto lock = Host::GetSettingsLock(); SettingsInterface* ssi = GetEditingSettingsInterface(); PAD::CopyConfiguration(&dsi, *ssi, true, true, IsEditingGameSettings(ssi)); + USB::CopyConfiguration(&dsi, *ssi, true, true); if (dsi.Save()) ShowToast(std::string(), fmt::format("Input profile '{}' saved.", name)); else diff --git a/pcsx2/PAD/Host/PAD.cpp b/pcsx2/PAD/Host/PAD.cpp index 014ce03b77..b19c293f02 100644 --- a/pcsx2/PAD/Host/PAD.cpp +++ b/pcsx2/PAD/Host/PAD.cpp @@ -287,26 +287,7 @@ void PAD::SetDefaultControllerConfig(SettingsInterface& si) for (u32 i = 0; i < ci->num_settings; i++) { const SettingInfo& csi = ci->settings[i]; - switch (csi.type) - { - case SettingInfo::Type::Boolean: - si.SetBoolValue(section.c_str(), csi.name, csi.BooleanDefaultValue()); - break; - case SettingInfo::Type::Integer: - case SettingInfo::Type::IntegerList: - si.SetIntValue(section.c_str(), csi.name, csi.IntegerDefaultValue()); - break; - case SettingInfo::Type::Float: - si.SetFloatValue(section.c_str(), csi.name, csi.FloatDefaultValue()); - break; - case SettingInfo::Type::String: - case SettingInfo::Type::StringList: - case SettingInfo::Type::Path: - si.SetStringValue(section.c_str(), csi.name, csi.StringDefaultValue()); - break; - default: - break; - } + csi.SetDefaultValue(&si, section.c_str(), csi.name); } } } @@ -583,26 +564,7 @@ void PAD::CopyConfiguration(SettingsInterface* dest_si, const SettingsInterface& for (u32 i = 0; i < info->num_settings; i++) { const SettingInfo& csi = info->settings[i]; - switch (csi.type) - { - case SettingInfo::Type::Boolean: - dest_si->CopyBoolValue(src_si, section.c_str(), csi.name); - break; - case SettingInfo::Type::Integer: - case SettingInfo::Type::IntegerList: - dest_si->CopyIntValue(src_si, section.c_str(), csi.name); - break; - case SettingInfo::Type::Float: - dest_si->CopyFloatValue(src_si, section.c_str(), csi.name); - break; - case SettingInfo::Type::String: - case SettingInfo::Type::StringList: - case SettingInfo::Type::Path: - dest_si->CopyStringValue(src_si, section.c_str(), csi.name); - break; - default: - break; - } + csi.CopyValue(dest_si, src_si, section.c_str(), csi.name); } } } diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 7ccc48b76e..1285b94b0b 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -88,6 +88,55 @@ float SettingInfo::FloatStepValue() const return step_value ? StringUtil::FromChars(step_value).value_or(fallback_value) : fallback_value; } +void SettingInfo::SetDefaultValue(SettingsInterface* si, const char* section, const char* key) const +{ + switch (type) + { + case SettingInfo::Type::Boolean: + si->SetBoolValue(section, key, BooleanDefaultValue()); + break; + case SettingInfo::Type::Integer: + case SettingInfo::Type::IntegerList: + si->SetIntValue(section, key, IntegerDefaultValue()); + break; + case SettingInfo::Type::Float: + si->SetFloatValue(section, key, FloatDefaultValue()); + break; + case SettingInfo::Type::String: + case SettingInfo::Type::StringList: + case SettingInfo::Type::Path: + si->SetStringValue(section, key, StringDefaultValue()); + break; + default: + break; + } +} + +void SettingInfo::CopyValue(SettingsInterface* dest_si, const SettingsInterface& src_si, + const char* section, const char* key) const +{ + switch (type) + { + case SettingInfo::Type::Boolean: + dest_si->CopyBoolValue(src_si, section, key); + break; + case SettingInfo::Type::Integer: + case SettingInfo::Type::IntegerList: + dest_si->CopyIntValue(src_si, section, key); + break; + case SettingInfo::Type::Float: + dest_si->CopyFloatValue(src_si, section, key); + break; + case SettingInfo::Type::String: + case SettingInfo::Type::StringList: + case SettingInfo::Type::Path: + dest_si->CopyStringValue(src_si, section, key); + break; + default: + break; + } +} + namespace EmuFolders { std::string AppRoot; diff --git a/pcsx2/USB/USB.cpp b/pcsx2/USB/USB.cpp index 1511baadb8..427c543412 100644 --- a/pcsx2/USB/USB.cpp +++ b/pcsx2/USB/USB.cpp @@ -749,8 +749,8 @@ bool USB::MapDevice(SettingsInterface& si, u32 port, const std::vectorCopyStringValue(src_si, section.c_str(), "Type"); + if (dev) + { + dest_si->CopyUIntValue(src_si, section.c_str(), fmt::format("{}_subtype", type).c_str()); + + for (const SettingInfo& si : dev->Settings(subtype)) + si.CopyValue(dest_si, src_si, section.c_str(), GetConfigSubKey(type, si.name).c_str()); + } + } + + if (copy_bindings && dev) + { + for (const InputBindingInfo& bi : dev->Bindings(subtype)) + dest_si->CopyStringValue(src_si, section.c_str(), GetConfigSubKey(type, bi.name).c_str()); + } + } +} + +void USB::SetDefaultConfiguration(SettingsInterface* si) +{ + for (u32 port = 0; port < NUM_PORTS; port++) + { + const std::string section = GetConfigSection(port); + + si->ClearSection(section.c_str()); + si->SetStringValue(section.c_str(), "Type", "None"); + } +} + void USB::CheckForConfigChanges(const Pcsx2Config& old_config) { static_assert(Pcsx2Config::USBOptions::NUM_PORTS == NUM_PORTS); diff --git a/pcsx2/USB/USB.h b/pcsx2/USB/USB.h index dd818f6180..eeb40f3631 100644 --- a/pcsx2/USB/USB.h +++ b/pcsx2/USB/USB.h @@ -70,6 +70,13 @@ namespace USB /// Clears all bindings for a given port. void ClearPortBindings(SettingsInterface& si, u32 port); + /// Copies configuration between two profiles. + void CopyConfiguration(SettingsInterface* dest_si, const SettingsInterface& src_si, bool copy_devices = true, + bool copy_bindings = true); + + /// Resets configuration for all ports. + void SetDefaultConfiguration(SettingsInterface* si); + /// Identifies any device/subtype changes and recreates devices. void CheckForConfigChanges(const Pcsx2Config& old_config); diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp index 4f32030854..fbe099c024 100644 --- a/pcsx2/VMManager.cpp +++ b/pcsx2/VMManager.cpp @@ -443,7 +443,10 @@ void VMManager::SetDefaultSettings( LogSink::SetDefaultLoggingSettings(si); } if (controllers) + { PAD::SetDefaultControllerConfig(si); + USB::SetDefaultConfiguration(&si); + } if (hotkeys) PAD::SetDefaultHotkeyConfig(si); if (ui)