Input: Allow per-game configuration to specify directories for input-profiles. If specified, the directories are searched recursively for inis
This commit is contained in:
parent
3b11066e61
commit
bce8041cce
|
@ -15,6 +15,7 @@
|
||||||
#include "InputCommon/ControllerEmu/ControllerEmu.h"
|
#include "InputCommon/ControllerEmu/ControllerEmu.h"
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
#include "InputCommon/InputConfig.h"
|
#include "InputCommon/InputConfig.h"
|
||||||
|
#include "InputCommon/InputProfile.h"
|
||||||
|
|
||||||
InputConfig::InputConfig(const std::string& ini_name, const std::string& gui_name,
|
InputConfig::InputConfig(const std::string& ini_name, const std::string& gui_name,
|
||||||
const std::string& profile_name)
|
const std::string& profile_name)
|
||||||
|
@ -56,23 +57,22 @@ bool InputConfig::LoadConfig(bool isGC)
|
||||||
std::string profile_setting;
|
std::string profile_setting;
|
||||||
if (control_section->Get(type + "Profile" + num[i], &profile_setting))
|
if (control_section->Get(type + "Profile" + num[i], &profile_setting))
|
||||||
{
|
{
|
||||||
// Setting can contain commas, which means there are multiple profiles specified
|
auto profiles = InputProfile::GetProfilesFromSetting(
|
||||||
// this is used for controller cycling
|
profile_setting, File::GetUserPath(D_CONFIG_IDX) + path);
|
||||||
const auto& profile_options = SplitString(profile_setting, ',');
|
|
||||||
|
if (profiles.empty())
|
||||||
|
{
|
||||||
|
const std::string error =
|
||||||
|
"No profiles found for game setting '" + profile_setting + "'";
|
||||||
|
// TODO: PanicAlert shouldn't be used for this.
|
||||||
|
PanicAlertT("%s", error.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Use the first profile by default
|
// Use the first profile by default
|
||||||
profile[i] = profile_options[0];
|
profile[i] = profiles[0];
|
||||||
|
|
||||||
if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile[i] + ".ini"))
|
|
||||||
{
|
|
||||||
useProfile[i] = true;
|
useProfile[i] = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: PanicAlert shouldn't be used for this.
|
|
||||||
PanicAlertT("Selected controller profile does not exist");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,37 @@ namespace
|
||||||
constexpr int display_message_ms = 3000;
|
constexpr int display_message_ms = 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> GetProfilesFromSetting(const std::string& setting, const std::string& root)
|
||||||
|
{
|
||||||
|
const auto& setting_choices = SplitString(setting, ',');
|
||||||
|
|
||||||
|
std::vector<std::string> result;
|
||||||
|
for (const std::string& setting_choice : setting_choices)
|
||||||
|
{
|
||||||
|
const std::string path = root + StripSpaces(setting_choice);
|
||||||
|
if (File::IsDirectory(path))
|
||||||
|
{
|
||||||
|
const auto files_under_directory = Common::DoFileSearch({path}, {".ini"}, true);
|
||||||
|
result.insert(result.end(), files_under_directory.begin(), files_under_directory.end());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const std::string file_path = path + ".ini";
|
||||||
|
if (File::Exists(file_path))
|
||||||
|
{
|
||||||
|
result.push_back(file_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> ProfileCycler::GetProfilesForDevice(InputConfig* device_configuration)
|
std::vector<std::string> ProfileCycler::GetProfilesForDevice(InputConfig* device_configuration)
|
||||||
{
|
{
|
||||||
const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" +
|
const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" +
|
||||||
device_configuration->GetProfileName());
|
device_configuration->GetProfileName());
|
||||||
return Common::DoFileSearch({device_profile_root_location}, {".ini"});
|
return Common::DoFileSearch({device_profile_root_location}, {".ini"}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ProfileCycler::GetProfile(CycleDirection cycle_direction, int& profile_index,
|
std::string ProfileCycler::GetProfile(CycleDirection cycle_direction, int& profile_index,
|
||||||
|
@ -66,29 +92,15 @@ void ProfileCycler::UpdateToProfile(const std::string& profile_filename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> ProfileCycler::GetProfilesFromSetting(const std::string& setting,
|
|
||||||
InputConfig* device_configuration)
|
|
||||||
{
|
|
||||||
const auto& profiles = SplitString(setting, ',');
|
|
||||||
|
|
||||||
const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" +
|
|
||||||
device_configuration->GetProfileName());
|
|
||||||
|
|
||||||
std::vector<std::string> result(profiles.size());
|
|
||||||
std::transform(profiles.begin(), profiles.end(), result.begin(),
|
|
||||||
[&device_profile_root_location](const std::string& profile) {
|
|
||||||
return device_profile_root_location + "/" + StripSpaces(profile) + ".ini";
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
ProfileCycler::GetMatchingProfilesFromSetting(const std::string& setting,
|
ProfileCycler::GetMatchingProfilesFromSetting(const std::string& setting,
|
||||||
const std::vector<std::string>& profiles,
|
const std::vector<std::string>& profiles,
|
||||||
InputConfig* device_configuration)
|
InputConfig* device_configuration)
|
||||||
{
|
{
|
||||||
const auto& profiles_from_setting = GetProfilesFromSetting(setting, device_configuration);
|
const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" +
|
||||||
|
device_configuration->GetProfileName() + "/");
|
||||||
|
|
||||||
|
const auto& profiles_from_setting = GetProfilesFromSetting(setting, device_profile_root_location);
|
||||||
if (profiles_from_setting.empty())
|
if (profiles_from_setting.empty())
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -16,6 +16,9 @@ class EmulatedController;
|
||||||
|
|
||||||
namespace InputProfile
|
namespace InputProfile
|
||||||
{
|
{
|
||||||
|
std::vector<std::string> GetProfilesFromSetting(const std::string& setting,
|
||||||
|
const std::string& root);
|
||||||
|
|
||||||
enum class CycleDirection : int
|
enum class CycleDirection : int
|
||||||
{
|
{
|
||||||
Forward = 1,
|
Forward = 1,
|
||||||
|
@ -36,8 +39,6 @@ private:
|
||||||
void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration,
|
void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration,
|
||||||
int& profile_index, const std::string& setting, int controller_index);
|
int& profile_index, const std::string& setting, int controller_index);
|
||||||
std::vector<std::string> GetProfilesForDevice(InputConfig* device_configuration);
|
std::vector<std::string> GetProfilesForDevice(InputConfig* device_configuration);
|
||||||
std::vector<std::string> GetProfilesFromSetting(const std::string& setting,
|
|
||||||
InputConfig* device_configuration);
|
|
||||||
std::string GetProfile(CycleDirection cycle_direction, int& profile_index,
|
std::string GetProfile(CycleDirection cycle_direction, int& profile_index,
|
||||||
const std::vector<std::string>& profiles);
|
const std::vector<std::string>& profiles);
|
||||||
std::vector<std::string> GetMatchingProfilesFromSetting(const std::string& setting,
|
std::vector<std::string> GetMatchingProfilesFromSetting(const std::string& setting,
|
||||||
|
|
Loading…
Reference in New Issue