FrontendCommon: Add input profile support
This commit is contained in:
parent
193763b4aa
commit
f75ea052a6
|
@ -694,6 +694,7 @@ void HostInterface::InitializeUserDirectory()
|
|||
result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("cache").c_str(), false);
|
||||
result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("dump").c_str(), false);
|
||||
result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("dump/audio").c_str(), false);
|
||||
result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("inputprofiles").c_str(), false);
|
||||
result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("savestates").c_str(), false);
|
||||
result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("screenshots").c_str(), false);
|
||||
result &= FileSystem::CreateDirectory(GetUserDirectoryRelativePath("memcards").c_str(), false);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "sdl_audio_stream.h"
|
||||
#include "sdl_controller_interface.h"
|
||||
#endif
|
||||
#include "ini_settings_interface.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
Log_SetChannel(CommonHostInterface);
|
||||
|
@ -794,3 +795,153 @@ void CommonHostInterface::RegisterSaveStateHotkeys()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> CommonHostInterface::GetInputProfileList() const
|
||||
{
|
||||
FileSystem::FindResultsArray results;
|
||||
FileSystem::FindFiles(GetUserDirectoryRelativePath("inputprofiles").c_str(), "*.ini",
|
||||
FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_RELATIVE_PATHS, &results);
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> profile_names;
|
||||
profile_names.reserve(results.size());
|
||||
for (auto& it : results)
|
||||
{
|
||||
if (it.FileName.size() < 4)
|
||||
continue;
|
||||
|
||||
std::string profile_name = it.FileName.substr(0, it.FileName.length() - 4);
|
||||
std::string full_filename = GetUserDirectoryRelativePath("inputprofiles/%s", it.FileName.c_str());
|
||||
profile_names.emplace_back(std::move(profile_name), std::move(full_filename));
|
||||
}
|
||||
|
||||
return profile_names;
|
||||
}
|
||||
|
||||
void CommonHostInterface::ClearAllControllerBindings(SettingsInterface& si)
|
||||
{
|
||||
for (u32 controller_index = 1; controller_index <= NUM_CONTROLLER_AND_CARD_PORTS; controller_index++)
|
||||
{
|
||||
const ControllerType ctype = m_settings.controller_types[controller_index - 1];
|
||||
if (ctype == ControllerType::None)
|
||||
continue;
|
||||
|
||||
const auto section_name = TinyString::FromFormat("Controller%u", controller_index);
|
||||
|
||||
si.DeleteValue(section_name, "Type");
|
||||
|
||||
for (const auto& button : Controller::GetButtonNames(ctype))
|
||||
si.DeleteValue(section_name, button.first.c_str());
|
||||
|
||||
for (const auto& axis : Controller::GetAxisNames(ctype))
|
||||
si.DeleteValue(section_name, axis.first.c_str());
|
||||
|
||||
if (Controller::GetVibrationMotorCount(ctype) > 0)
|
||||
si.DeleteValue(section_name, "Rumble");
|
||||
}
|
||||
}
|
||||
|
||||
void CommonHostInterface::ApplyInputProfile(const char* profile_path, SettingsInterface& si)
|
||||
{
|
||||
// clear bindings for all controllers
|
||||
ClearAllControllerBindings(si);
|
||||
|
||||
INISettingsInterface profile(profile_path);
|
||||
|
||||
for (u32 controller_index = 1; controller_index <= NUM_CONTROLLER_AND_CARD_PORTS; controller_index++)
|
||||
{
|
||||
const auto section_name = TinyString::FromFormat("Controller%u", controller_index);
|
||||
const std::string ctype_str = profile.GetStringValue(section_name, "Type");
|
||||
if (ctype_str.empty())
|
||||
continue;
|
||||
|
||||
std::optional<ControllerType> ctype = Settings::ParseControllerTypeName(ctype_str.c_str());
|
||||
if (!ctype)
|
||||
{
|
||||
Log_ErrorPrintf("Invalid controller type in profile: '%s'", ctype_str.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_settings.controller_types[controller_index - 1] = *ctype;
|
||||
HostInterface::OnControllerTypeChanged(controller_index - 1);
|
||||
|
||||
si.SetStringValue(section_name, "Type", Settings::GetControllerTypeName(*ctype));
|
||||
|
||||
for (const auto& button : Controller::GetButtonNames(*ctype))
|
||||
{
|
||||
const auto key_name = TinyString::FromFormat("Button%s", button.first.c_str());
|
||||
si.DeleteValue(section_name, key_name);
|
||||
const std::vector<std::string> bindings = profile.GetStringList(section_name, key_name);
|
||||
for (const std::string& binding : bindings)
|
||||
si.AddToStringList(section_name, key_name, binding.c_str());
|
||||
}
|
||||
|
||||
for (const auto& axis : Controller::GetAxisNames(*ctype))
|
||||
{
|
||||
const auto key_name = TinyString::FromFormat("Axis%s", axis.first.c_str());
|
||||
si.DeleteValue(section_name, axis.first.c_str());
|
||||
const std::vector<std::string> bindings = profile.GetStringList(section_name, key_name);
|
||||
for (const std::string& binding : bindings)
|
||||
si.AddToStringList(section_name, key_name, binding.c_str());
|
||||
}
|
||||
|
||||
si.DeleteValue(section_name, "Rumble");
|
||||
const std::string rumble_value = profile.GetStringValue(section_name, "Rumble");
|
||||
if (!rumble_value.empty())
|
||||
si.SetStringValue(section_name, "Rumble", rumble_value.c_str());
|
||||
}
|
||||
|
||||
UpdateInputMap(si);
|
||||
|
||||
if (m_system)
|
||||
m_system->UpdateControllers();
|
||||
|
||||
ReportFormattedMessage("Loaded input profile from '%s'", profile_path);
|
||||
}
|
||||
|
||||
bool CommonHostInterface::SaveInputProfile(const char* profile_path, SettingsInterface& si)
|
||||
{
|
||||
if (FileSystem::FileExists(profile_path))
|
||||
{
|
||||
if (!FileSystem::DeleteFile(profile_path))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to delete existing input profile '%s' when saving", profile_path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
INISettingsInterface profile(profile_path);
|
||||
|
||||
for (u32 controller_index = 1; controller_index <= NUM_CONTROLLER_AND_CARD_PORTS; controller_index++)
|
||||
{
|
||||
const ControllerType ctype = m_settings.controller_types[controller_index - 1];
|
||||
if (ctype == ControllerType::None)
|
||||
continue;
|
||||
|
||||
const auto section_name = TinyString::FromFormat("Controller%u", controller_index);
|
||||
|
||||
profile.SetStringValue(section_name, "Type", Settings::GetControllerTypeName(ctype));
|
||||
|
||||
for (const auto& button : Controller::GetButtonNames(ctype))
|
||||
{
|
||||
const auto key_name = TinyString::FromFormat("Button%s", button.first.c_str());
|
||||
const std::vector<std::string> bindings = si.GetStringList(section_name, key_name);
|
||||
for (const std::string& binding : bindings)
|
||||
profile.AddToStringList(section_name, key_name, binding.c_str());
|
||||
}
|
||||
|
||||
for (const auto& axis : Controller::GetAxisNames(ctype))
|
||||
{
|
||||
const auto key_name = TinyString::FromFormat("Axis%s", axis.first.c_str());
|
||||
const std::vector<std::string> bindings = si.GetStringList(section_name, key_name);
|
||||
for (const std::string& binding : bindings)
|
||||
profile.AddToStringList(section_name, key_name, binding.c_str());
|
||||
}
|
||||
|
||||
const std::string rumble_value = si.GetStringValue(section_name, "Rumble");
|
||||
if (!rumble_value.empty())
|
||||
profile.SetStringValue(section_name, "Rumble", rumble_value.c_str());
|
||||
}
|
||||
|
||||
profile.Save();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,15 @@ protected:
|
|||
/// Reloads the input map from config. Callable from controller interface.
|
||||
virtual void UpdateInputMap() = 0;
|
||||
|
||||
/// Returns a list of all input profiles. first - name, second - path
|
||||
std::vector<std::pair<std::string, std::string>> GetInputProfileList() const;
|
||||
|
||||
/// Applies the specified input profile.
|
||||
void ApplyInputProfile(const char* profile_path, SettingsInterface& si);
|
||||
|
||||
/// Saves the current input configuration to the specified profile name.
|
||||
bool SaveInputProfile(const char* profile_path, SettingsInterface& si);
|
||||
|
||||
void RegisterHotkey(String category, String name, String display_name, InputButtonHandler handler);
|
||||
bool HandleHostKeyEvent(HostKeyCode code, bool pressed);
|
||||
void UpdateInputMap(SettingsInterface& si);
|
||||
|
@ -102,6 +111,7 @@ private:
|
|||
void RegisterSaveStateHotkeys();
|
||||
void UpdateControllerInputMap(SettingsInterface& si);
|
||||
void UpdateHotkeyInputMap(SettingsInterface& si);
|
||||
void ClearAllControllerBindings(SettingsInterface& si);
|
||||
|
||||
HotkeyInfoList m_hotkeys;
|
||||
|
||||
|
|
Loading…
Reference in New Issue