mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-09 17:09:58 +00:00
input_profiles: Implement input profiles
This commit is contained in:
parent
75eaab2e0f
commit
57d89e291d
13 changed files with 506 additions and 127 deletions
|
@ -108,6 +108,8 @@ add_executable(yuzu
|
||||||
configuration/configure_web.cpp
|
configuration/configure_web.cpp
|
||||||
configuration/configure_web.h
|
configuration/configure_web.h
|
||||||
configuration/configure_web.ui
|
configuration/configure_web.ui
|
||||||
|
configuration/input_profiles.cpp
|
||||||
|
configuration/input_profiles.h
|
||||||
debugger/console.cpp
|
debugger/console.cpp
|
||||||
debugger/console.h
|
debugger/console.h
|
||||||
debugger/profiler.cpp
|
debugger/profiler.cpp
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "core/hle/service/hid/controllers/npad.h"
|
#include "core/hle/service/hid/controllers/npad.h"
|
||||||
|
@ -14,14 +15,27 @@
|
||||||
|
|
||||||
namespace FS = Common::FS;
|
namespace FS = Common::FS;
|
||||||
|
|
||||||
Config::Config(const std::string& config_file, bool is_global) {
|
Config::Config(const std::string& config_file, ConfigType config_type) : type(config_type) {
|
||||||
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
|
global = config_type == ConfigType::GlobalConfig;
|
||||||
qt_config_loc = FS::GetUserPath(FS::UserPath::ConfigDir) + config_file;
|
|
||||||
|
switch (config_type) {
|
||||||
|
case ConfigType::GlobalConfig:
|
||||||
|
case ConfigType::PerGameConfig:
|
||||||
|
qt_config_loc = fmt::format("{}" DIR_SEP "{}.ini", FS::GetUserPath(FS::UserPath::ConfigDir),
|
||||||
|
config_file);
|
||||||
FS::CreateFullPath(qt_config_loc);
|
FS::CreateFullPath(qt_config_loc);
|
||||||
qt_config =
|
qt_config = std::make_unique<QSettings>(QString::fromStdString(qt_config_loc),
|
||||||
std::make_unique<QSettings>(QString::fromStdString(qt_config_loc), QSettings::IniFormat);
|
QSettings::IniFormat);
|
||||||
global = is_global;
|
|
||||||
Reload();
|
Reload();
|
||||||
|
break;
|
||||||
|
case ConfigType::InputProfile:
|
||||||
|
qt_config_loc = fmt::format("{}input" DIR_SEP "{}.ini",
|
||||||
|
FS::GetUserPath(FS::UserPath::ConfigDir), config_file);
|
||||||
|
FS::CreateFullPath(qt_config_loc);
|
||||||
|
qt_config = std::make_unique<QSettings>(QString::fromStdString(qt_config_loc),
|
||||||
|
QSettings::IniFormat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::~Config() {
|
Config::~Config() {
|
||||||
|
@ -242,44 +256,65 @@ const std::array<UISettings::Shortcut, 16> Config::default_hotkeys{{
|
||||||
}};
|
}};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
void Config::ReadPlayerValues() {
|
void Config::ReadPlayerValue(std::size_t player_index) {
|
||||||
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
|
const QString player_prefix = [this, player_index] {
|
||||||
auto& player = Settings::values.players[p];
|
if (type == ConfigType::InputProfile) {
|
||||||
|
return QString{};
|
||||||
|
} else {
|
||||||
|
return QStringLiteral("player_%1_").arg(player_index);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
auto& player = Settings::values.players[player_index];
|
||||||
|
|
||||||
|
if (player_prefix.isEmpty()) {
|
||||||
|
const auto controller = static_cast<Settings::ControllerType>(
|
||||||
|
qt_config
|
||||||
|
->value(QStringLiteral("%1type").arg(player_prefix),
|
||||||
|
static_cast<u8>(Settings::ControllerType::ProController))
|
||||||
|
.toUInt());
|
||||||
|
|
||||||
|
if (controller == Settings::ControllerType::LeftJoycon ||
|
||||||
|
controller == Settings::ControllerType::RightJoycon) {
|
||||||
|
player.controller_type = controller;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
player.connected =
|
player.connected =
|
||||||
ReadSetting(QStringLiteral("player_%1_connected").arg(p), false).toBool();
|
ReadSetting(QStringLiteral("%1connected").arg(player_prefix), false).toBool();
|
||||||
|
|
||||||
player.controller_type = static_cast<Settings::ControllerType>(
|
player.controller_type = static_cast<Settings::ControllerType>(
|
||||||
qt_config
|
qt_config
|
||||||
->value(QStringLiteral("player_%1_type").arg(p),
|
->value(QStringLiteral("%1type").arg(player_prefix),
|
||||||
static_cast<u8>(Settings::ControllerType::ProController))
|
static_cast<u8>(Settings::ControllerType::ProController))
|
||||||
.toUInt());
|
.toUInt());
|
||||||
|
|
||||||
player.body_color_left = qt_config
|
player.body_color_left = qt_config
|
||||||
->value(QStringLiteral("player_%1_body_color_left").arg(p),
|
->value(QStringLiteral("%1body_color_left").arg(player_prefix),
|
||||||
Settings::JOYCON_BODY_NEON_BLUE)
|
Settings::JOYCON_BODY_NEON_BLUE)
|
||||||
.toUInt();
|
.toUInt();
|
||||||
player.body_color_right = qt_config
|
player.body_color_right =
|
||||||
->value(QStringLiteral("player_%1_body_color_right").arg(p),
|
qt_config
|
||||||
|
->value(QStringLiteral("%1body_color_right").arg(player_prefix),
|
||||||
Settings::JOYCON_BODY_NEON_RED)
|
Settings::JOYCON_BODY_NEON_RED)
|
||||||
.toUInt();
|
.toUInt();
|
||||||
player.button_color_left = qt_config
|
player.button_color_left =
|
||||||
->value(QStringLiteral("player_%1_button_color_left").arg(p),
|
qt_config
|
||||||
|
->value(QStringLiteral("%1button_color_left").arg(player_prefix),
|
||||||
Settings::JOYCON_BUTTONS_NEON_BLUE)
|
Settings::JOYCON_BUTTONS_NEON_BLUE)
|
||||||
.toUInt();
|
.toUInt();
|
||||||
player.button_color_right =
|
player.button_color_right =
|
||||||
qt_config
|
qt_config
|
||||||
->value(QStringLiteral("player_%1_button_color_right").arg(p),
|
->value(QStringLiteral("%1button_color_right").arg(player_prefix),
|
||||||
Settings::JOYCON_BUTTONS_NEON_RED)
|
Settings::JOYCON_BUTTONS_NEON_RED)
|
||||||
.toUInt();
|
.toUInt();
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||||
const std::string default_param =
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||||
InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
|
||||||
auto& player_buttons = player.buttons[i];
|
auto& player_buttons = player.buttons[i];
|
||||||
|
|
||||||
player_buttons = qt_config
|
player_buttons = qt_config
|
||||||
->value(QStringLiteral("player_%1_").arg(p) +
|
->value(QStringLiteral("%1").arg(player_prefix) +
|
||||||
QString::fromUtf8(Settings::NativeButton::mapping[i]),
|
QString::fromUtf8(Settings::NativeButton::mapping[i]),
|
||||||
QString::fromStdString(default_param))
|
QString::fromStdString(default_param))
|
||||||
.toString()
|
.toString()
|
||||||
|
@ -290,12 +325,11 @@ void Config::ReadPlayerValues() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||||
const std::string default_param =
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||||
InputCommon::GenerateKeyboardParam(default_motions[i]);
|
|
||||||
auto& player_motions = player.motions[i];
|
auto& player_motions = player.motions[i];
|
||||||
|
|
||||||
player_motions = qt_config
|
player_motions = qt_config
|
||||||
->value(QStringLiteral("player_%1_").arg(p) +
|
->value(QStringLiteral("%1").arg(player_prefix) +
|
||||||
QString::fromUtf8(Settings::NativeMotion::mapping[i]),
|
QString::fromUtf8(Settings::NativeMotion::mapping[i]),
|
||||||
QString::fromStdString(default_param))
|
QString::fromStdString(default_param))
|
||||||
.toString()
|
.toString()
|
||||||
|
@ -312,7 +346,7 @@ void Config::ReadPlayerValues() {
|
||||||
auto& player_analogs = player.analogs[i];
|
auto& player_analogs = player.analogs[i];
|
||||||
|
|
||||||
player_analogs = qt_config
|
player_analogs = qt_config
|
||||||
->value(QStringLiteral("player_%1_").arg(p) +
|
->value(QStringLiteral("%1").arg(player_prefix) +
|
||||||
QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
|
QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
|
||||||
QString::fromStdString(default_param))
|
QString::fromStdString(default_param))
|
||||||
.toString()
|
.toString()
|
||||||
|
@ -322,7 +356,6 @@ void Config::ReadPlayerValues() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Config::ReadDebugValues() {
|
void Config::ReadDebugValues() {
|
||||||
Settings::values.debug_pad_enabled =
|
Settings::values.debug_pad_enabled =
|
||||||
|
@ -436,7 +469,9 @@ void Config::ReadAudioValues() {
|
||||||
void Config::ReadControlValues() {
|
void Config::ReadControlValues() {
|
||||||
qt_config->beginGroup(QStringLiteral("Controls"));
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
|
||||||
ReadPlayerValues();
|
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
|
||||||
|
ReadPlayerValue(p);
|
||||||
|
}
|
||||||
ReadDebugValues();
|
ReadDebugValues();
|
||||||
ReadKeyboardValues();
|
ReadKeyboardValues();
|
||||||
ReadMouseValues();
|
ReadMouseValues();
|
||||||
|
@ -920,36 +955,43 @@ void Config::ReadValues() {
|
||||||
ReadSystemValues();
|
ReadSystemValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::SavePlayerValues() {
|
void Config::SavePlayerValue(std::size_t player_index) {
|
||||||
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
|
const QString player_prefix = [this, player_index] {
|
||||||
const auto& player = Settings::values.players[p];
|
if (type == ConfigType::InputProfile) {
|
||||||
|
return QString{};
|
||||||
|
} else {
|
||||||
|
return QStringLiteral("player_%1_").arg(player_index);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
WriteSetting(QStringLiteral("player_%1_connected").arg(p), player.connected, false);
|
const auto& player = Settings::values.players[player_index];
|
||||||
WriteSetting(QStringLiteral("player_%1_type").arg(p),
|
|
||||||
|
WriteSetting(QStringLiteral("%1type").arg(player_prefix),
|
||||||
static_cast<u8>(player.controller_type),
|
static_cast<u8>(player.controller_type),
|
||||||
static_cast<u8>(Settings::ControllerType::ProController));
|
static_cast<u8>(Settings::ControllerType::ProController));
|
||||||
|
|
||||||
WriteSetting(QStringLiteral("player_%1_body_color_left").arg(p), player.body_color_left,
|
if (!player_prefix.isEmpty()) {
|
||||||
|
WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, false);
|
||||||
|
WriteSetting(QStringLiteral("%1body_color_left").arg(player_prefix), player.body_color_left,
|
||||||
Settings::JOYCON_BODY_NEON_BLUE);
|
Settings::JOYCON_BODY_NEON_BLUE);
|
||||||
WriteSetting(QStringLiteral("player_%1_body_color_right").arg(p), player.body_color_right,
|
WriteSetting(QStringLiteral("%1body_color_right").arg(player_prefix),
|
||||||
Settings::JOYCON_BODY_NEON_RED);
|
player.body_color_right, Settings::JOYCON_BODY_NEON_RED);
|
||||||
WriteSetting(QStringLiteral("player_%1_button_color_left").arg(p), player.button_color_left,
|
WriteSetting(QStringLiteral("%1button_color_left").arg(player_prefix),
|
||||||
Settings::JOYCON_BUTTONS_NEON_BLUE);
|
player.button_color_left, Settings::JOYCON_BUTTONS_NEON_BLUE);
|
||||||
WriteSetting(QStringLiteral("player_%1_button_color_right").arg(p),
|
WriteSetting(QStringLiteral("%1button_color_right").arg(player_prefix),
|
||||||
player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED);
|
player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||||
const std::string default_param =
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||||
InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
WriteSetting(QStringLiteral("%1").arg(player_prefix) +
|
||||||
WriteSetting(QStringLiteral("player_%1_").arg(p) +
|
|
||||||
QString::fromStdString(Settings::NativeButton::mapping[i]),
|
QString::fromStdString(Settings::NativeButton::mapping[i]),
|
||||||
QString::fromStdString(player.buttons[i]),
|
QString::fromStdString(player.buttons[i]),
|
||||||
QString::fromStdString(default_param));
|
QString::fromStdString(default_param));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||||
const std::string default_param =
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||||
InputCommon::GenerateKeyboardParam(default_motions[i]);
|
WriteSetting(QStringLiteral("%1").arg(player_prefix) +
|
||||||
WriteSetting(QStringLiteral("player_%1_").arg(p) +
|
|
||||||
QString::fromStdString(Settings::NativeMotion::mapping[i]),
|
QString::fromStdString(Settings::NativeMotion::mapping[i]),
|
||||||
QString::fromStdString(player.motions[i]),
|
QString::fromStdString(player.motions[i]),
|
||||||
QString::fromStdString(default_param));
|
QString::fromStdString(default_param));
|
||||||
|
@ -958,13 +1000,12 @@ void Config::SavePlayerValues() {
|
||||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||||
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||||
WriteSetting(QStringLiteral("player_%1_").arg(p) +
|
WriteSetting(QStringLiteral("%1").arg(player_prefix) +
|
||||||
QString::fromStdString(Settings::NativeAnalog::mapping[i]),
|
QString::fromStdString(Settings::NativeAnalog::mapping[i]),
|
||||||
QString::fromStdString(player.analogs[i]),
|
QString::fromStdString(player.analogs[i]),
|
||||||
QString::fromStdString(default_param));
|
QString::fromStdString(default_param));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Config::SaveDebugValues() {
|
void Config::SaveDebugValues() {
|
||||||
WriteSetting(QStringLiteral("debug_pad_enabled"), Settings::values.debug_pad_enabled, false);
|
WriteSetting(QStringLiteral("debug_pad_enabled"), Settings::values.debug_pad_enabled, false);
|
||||||
|
@ -1087,7 +1128,9 @@ void Config::SaveAudioValues() {
|
||||||
void Config::SaveControlValues() {
|
void Config::SaveControlValues() {
|
||||||
qt_config->beginGroup(QStringLiteral("Controls"));
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
|
||||||
SavePlayerValues();
|
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
|
||||||
|
SavePlayerValue(p);
|
||||||
|
}
|
||||||
SaveDebugValues();
|
SaveDebugValues();
|
||||||
SaveMouseValues();
|
SaveMouseValues();
|
||||||
SaveTouchscreenValues();
|
SaveTouchscreenValues();
|
||||||
|
@ -1515,3 +1558,19 @@ void Config::Save() {
|
||||||
Settings::Sanitize();
|
Settings::Sanitize();
|
||||||
SaveValues();
|
SaveValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Config::ReadControlPlayerValue(std::size_t player_index) {
|
||||||
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
ReadPlayerValue(player_index);
|
||||||
|
qt_config->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::SaveControlPlayerValue(std::size_t player_index) {
|
||||||
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
SavePlayerValue(player_index);
|
||||||
|
qt_config->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Config::GetConfigFilePath() const {
|
||||||
|
return qt_config_loc;
|
||||||
|
}
|
||||||
|
|
|
@ -16,12 +16,24 @@ class QSettings;
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
explicit Config(const std::string& config_loc = "qt-config.ini", bool is_global = true);
|
enum class ConfigType {
|
||||||
|
GlobalConfig,
|
||||||
|
PerGameConfig,
|
||||||
|
InputProfile,
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit Config(const std::string& config_loc = "qt-config",
|
||||||
|
ConfigType config_type = ConfigType::GlobalConfig);
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
void Reload();
|
void Reload();
|
||||||
void Save();
|
void Save();
|
||||||
|
|
||||||
|
void ReadControlPlayerValue(std::size_t player_index);
|
||||||
|
void SaveControlPlayerValue(std::size_t player_index);
|
||||||
|
|
||||||
|
const std::string& GetConfigFilePath() const;
|
||||||
|
|
||||||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
|
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
|
||||||
static const std::array<int, Settings::NativeMotion::NumMotions> default_motions;
|
static const std::array<int, Settings::NativeMotion::NumMotions> default_motions;
|
||||||
static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
||||||
|
@ -34,7 +46,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ReadValues();
|
void ReadValues();
|
||||||
void ReadPlayerValues();
|
void ReadPlayerValue(std::size_t player_index);
|
||||||
void ReadDebugValues();
|
void ReadDebugValues();
|
||||||
void ReadKeyboardValues();
|
void ReadKeyboardValues();
|
||||||
void ReadMouseValues();
|
void ReadMouseValues();
|
||||||
|
@ -62,7 +74,7 @@ private:
|
||||||
void ReadWebServiceValues();
|
void ReadWebServiceValues();
|
||||||
|
|
||||||
void SaveValues();
|
void SaveValues();
|
||||||
void SavePlayerValues();
|
void SavePlayerValue(std::size_t player_index);
|
||||||
void SaveDebugValues();
|
void SaveDebugValues();
|
||||||
void SaveMouseValues();
|
void SaveMouseValues();
|
||||||
void SaveTouchscreenValues();
|
void SaveTouchscreenValues();
|
||||||
|
@ -111,9 +123,9 @@ private:
|
||||||
void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
|
void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
|
||||||
const QVariant& default_value);
|
const QVariant& default_value);
|
||||||
|
|
||||||
|
ConfigType type;
|
||||||
std::unique_ptr<QSettings> qt_config;
|
std::unique_ptr<QSettings> qt_config;
|
||||||
std::string qt_config_loc;
|
std::string qt_config_loc;
|
||||||
|
|
||||||
bool global;
|
bool global;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
#include "yuzu/configuration/configure_debug_controller.h"
|
#include "yuzu/configuration/configure_debug_controller.h"
|
||||||
|
|
||||||
ConfigureDebugController::ConfigureDebugController(QWidget* parent,
|
ConfigureDebugController::ConfigureDebugController(QWidget* parent,
|
||||||
InputCommon::InputSubsystem* input_subsystem)
|
InputCommon::InputSubsystem* input_subsystem,
|
||||||
|
InputProfiles* profiles)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDebugController>()),
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDebugController>()),
|
||||||
debug_controller(new ConfigureInputPlayer(this, 9, nullptr, input_subsystem, true)) {
|
debug_controller(
|
||||||
|
new ConfigureInputPlayer(this, 9, nullptr, input_subsystem, profiles, true)) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->controllerLayout->addWidget(debug_controller);
|
ui->controllerLayout->addWidget(debug_controller);
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
|
|
||||||
|
class InputProfiles;
|
||||||
|
|
||||||
namespace InputCommon {
|
namespace InputCommon {
|
||||||
class InputSubsystem;
|
class InputSubsystem;
|
||||||
}
|
}
|
||||||
|
@ -22,8 +24,8 @@ class ConfigureDebugController : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureDebugController(QWidget* parent,
|
explicit ConfigureDebugController(QWidget* parent, InputCommon::InputSubsystem* input_subsystem,
|
||||||
InputCommon::InputSubsystem* input_subsystem);
|
InputProfiles* profiles);
|
||||||
~ConfigureDebugController() override;
|
~ConfigureDebugController() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "yuzu/configuration/configure_motion_touch.h"
|
#include "yuzu/configuration/configure_motion_touch.h"
|
||||||
#include "yuzu/configuration/configure_mouse_advanced.h"
|
#include "yuzu/configuration/configure_mouse_advanced.h"
|
||||||
#include "yuzu/configuration/configure_touchscreen_advanced.h"
|
#include "yuzu/configuration/configure_touchscreen_advanced.h"
|
||||||
|
#include "yuzu/configuration/input_profiles.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <typename Dialog, typename... Args>
|
template <typename Dialog, typename... Args>
|
||||||
|
@ -64,7 +65,8 @@ void OnDockedModeChanged(bool last_state, bool new_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureInput::ConfigureInput(QWidget* parent)
|
ConfigureInput::ConfigureInput(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()),
|
||||||
|
profiles(std::make_unique<InputProfiles>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,14 +75,22 @@ ConfigureInput::~ConfigureInput() = default;
|
||||||
void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
|
void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
|
||||||
std::size_t max_players) {
|
std::size_t max_players) {
|
||||||
player_controllers = {
|
player_controllers = {
|
||||||
new ConfigureInputPlayer(this, 0, ui->consoleInputSettings, input_subsystem),
|
new ConfigureInputPlayer(this, 0, ui->consoleInputSettings, input_subsystem,
|
||||||
new ConfigureInputPlayer(this, 1, ui->consoleInputSettings, input_subsystem),
|
profiles.get()),
|
||||||
new ConfigureInputPlayer(this, 2, ui->consoleInputSettings, input_subsystem),
|
new ConfigureInputPlayer(this, 1, ui->consoleInputSettings, input_subsystem,
|
||||||
new ConfigureInputPlayer(this, 3, ui->consoleInputSettings, input_subsystem),
|
profiles.get()),
|
||||||
new ConfigureInputPlayer(this, 4, ui->consoleInputSettings, input_subsystem),
|
new ConfigureInputPlayer(this, 2, ui->consoleInputSettings, input_subsystem,
|
||||||
new ConfigureInputPlayer(this, 5, ui->consoleInputSettings, input_subsystem),
|
profiles.get()),
|
||||||
new ConfigureInputPlayer(this, 6, ui->consoleInputSettings, input_subsystem),
|
new ConfigureInputPlayer(this, 3, ui->consoleInputSettings, input_subsystem,
|
||||||
new ConfigureInputPlayer(this, 7, ui->consoleInputSettings, input_subsystem),
|
profiles.get()),
|
||||||
|
new ConfigureInputPlayer(this, 4, ui->consoleInputSettings, input_subsystem,
|
||||||
|
profiles.get()),
|
||||||
|
new ConfigureInputPlayer(this, 5, ui->consoleInputSettings, input_subsystem,
|
||||||
|
profiles.get()),
|
||||||
|
new ConfigureInputPlayer(this, 6, ui->consoleInputSettings, input_subsystem,
|
||||||
|
profiles.get()),
|
||||||
|
new ConfigureInputPlayer(this, 7, ui->consoleInputSettings, input_subsystem,
|
||||||
|
profiles.get()),
|
||||||
};
|
};
|
||||||
|
|
||||||
player_tabs = {
|
player_tabs = {
|
||||||
|
@ -134,7 +144,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
|
||||||
ui->tabAdvanced->setLayout(new QHBoxLayout(ui->tabAdvanced));
|
ui->tabAdvanced->setLayout(new QHBoxLayout(ui->tabAdvanced));
|
||||||
ui->tabAdvanced->layout()->addWidget(advanced);
|
ui->tabAdvanced->layout()->addWidget(advanced);
|
||||||
connect(advanced, &ConfigureInputAdvanced::CallDebugControllerDialog, [this, input_subsystem] {
|
connect(advanced, &ConfigureInputAdvanced::CallDebugControllerDialog, [this, input_subsystem] {
|
||||||
CallConfigureDialog<ConfigureDebugController>(*this, input_subsystem);
|
CallConfigureDialog<ConfigureDebugController>(*this, input_subsystem, profiles.get());
|
||||||
});
|
});
|
||||||
connect(advanced, &ConfigureInputAdvanced::CallMouseConfigDialog, [this, input_subsystem] {
|
connect(advanced, &ConfigureInputAdvanced::CallMouseConfigDialog, [this, input_subsystem] {
|
||||||
CallConfigureDialog<ConfigureMouseAdvanced>(*this, input_subsystem);
|
CallConfigureDialog<ConfigureMouseAdvanced>(*this, input_subsystem);
|
||||||
|
|
|
@ -19,6 +19,8 @@ class QCheckBox;
|
||||||
class QString;
|
class QString;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
|
||||||
|
class InputProfiles;
|
||||||
|
|
||||||
namespace InputCommon {
|
namespace InputCommon {
|
||||||
class InputSubsystem;
|
class InputSubsystem;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +63,8 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureInput> ui;
|
std::unique_ptr<Ui::ConfigureInput> ui;
|
||||||
|
|
||||||
|
std::unique_ptr<InputProfiles> profiles;
|
||||||
|
|
||||||
std::array<ConfigureInputPlayer*, 8> player_controllers;
|
std::array<ConfigureInputPlayer*, 8> player_controllers;
|
||||||
std::array<QWidget*, 8> player_tabs;
|
std::array<QWidget*, 8> player_tabs;
|
||||||
std::array<QCheckBox*, 8> player_connected;
|
std::array<QCheckBox*, 8> player_connected;
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include "ui_configure_input_player.h"
|
#include "ui_configure_input_player.h"
|
||||||
#include "yuzu/configuration/config.h"
|
#include "yuzu/configuration/config.h"
|
||||||
#include "yuzu/configuration/configure_input_player.h"
|
#include "yuzu/configuration/configure_input_player.h"
|
||||||
|
#include "yuzu/configuration/input_profiles.h"
|
||||||
|
#include "yuzu/util/limitable_input_dialog.h"
|
||||||
|
|
||||||
constexpr std::size_t HANDHELD_INDEX = 8;
|
constexpr std::size_t HANDHELD_INDEX = 8;
|
||||||
|
|
||||||
|
@ -240,10 +242,11 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)
|
||||||
ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index,
|
ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index,
|
||||||
QWidget* bottom_row,
|
QWidget* bottom_row,
|
||||||
InputCommon::InputSubsystem* input_subsystem_,
|
InputCommon::InputSubsystem* input_subsystem_,
|
||||||
bool debug)
|
InputProfiles* profiles_, bool debug)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index),
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index),
|
||||||
debug(debug), input_subsystem{input_subsystem_}, timeout_timer(std::make_unique<QTimer>()),
|
debug(debug), input_subsystem{input_subsystem_}, profiles(profiles_),
|
||||||
poll_timer(std::make_unique<QTimer>()), bottom_row(bottom_row) {
|
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()),
|
||||||
|
bottom_row(bottom_row) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
@ -521,6 +524,17 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RefreshInputProfiles();
|
||||||
|
|
||||||
|
connect(ui->buttonProfilesNew, &QPushButton::clicked, this,
|
||||||
|
&ConfigureInputPlayer::CreateProfile);
|
||||||
|
connect(ui->buttonProfilesDelete, &QPushButton::clicked, this,
|
||||||
|
&ConfigureInputPlayer::DeleteProfile);
|
||||||
|
connect(ui->comboProfiles, qOverload<int>(&QComboBox::activated), this,
|
||||||
|
&ConfigureInputPlayer::LoadProfile);
|
||||||
|
connect(ui->buttonProfilesSave, &QPushButton::clicked, this,
|
||||||
|
&ConfigureInputPlayer::SaveProfile);
|
||||||
|
|
||||||
LoadConfiguration();
|
LoadConfiguration();
|
||||||
|
|
||||||
// TODO(wwylele): enable this when we actually emulate it
|
// TODO(wwylele): enable this when we actually emulate it
|
||||||
|
@ -1061,3 +1075,94 @@ void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
SetPollingResult({}, true);
|
SetPollingResult({}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureInputPlayer::CreateProfile() {
|
||||||
|
const auto profile_name =
|
||||||
|
LimitableInputDialog::GetText(this, tr("New Profile"), tr("Enter a profile name:"), 1, 20);
|
||||||
|
|
||||||
|
if (profile_name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!profiles->IsProfileNameValid(profile_name.toStdString())) {
|
||||||
|
QMessageBox::critical(this, tr("Create Input Profile"),
|
||||||
|
tr("The given profile name is not valid!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyConfiguration();
|
||||||
|
|
||||||
|
if (!profiles->CreateProfile(profile_name.toStdString(), player_index)) {
|
||||||
|
QMessageBox::critical(this, tr("Create Input Profile"),
|
||||||
|
tr("Failed to create the input profile \"%1\"").arg(profile_name));
|
||||||
|
RefreshInputProfiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->comboProfiles->addItem(profile_name);
|
||||||
|
ui->comboProfiles->setCurrentIndex(ui->comboProfiles->count() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputPlayer::DeleteProfile() {
|
||||||
|
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||||
|
|
||||||
|
if (profile_name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!profiles->DeleteProfile(profile_name.toStdString())) {
|
||||||
|
QMessageBox::critical(this, tr("Delete Input Profile"),
|
||||||
|
tr("Failed to delete the input profile \"%1\"").arg(profile_name));
|
||||||
|
RefreshInputProfiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->comboProfiles->removeItem(ui->comboProfiles->currentIndex());
|
||||||
|
ui->comboProfiles->setCurrentIndex(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputPlayer::LoadProfile() {
|
||||||
|
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||||
|
|
||||||
|
if (profile_name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyConfiguration();
|
||||||
|
|
||||||
|
if (!profiles->LoadProfile(profile_name.toStdString(), player_index)) {
|
||||||
|
QMessageBox::critical(this, tr("Load Input Profile"),
|
||||||
|
tr("Failed to load the input profile \"%1\"").arg(profile_name));
|
||||||
|
RefreshInputProfiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputPlayer::SaveProfile() {
|
||||||
|
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||||
|
|
||||||
|
if (profile_name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyConfiguration();
|
||||||
|
|
||||||
|
if (!profiles->SaveProfile(profile_name.toStdString(), player_index)) {
|
||||||
|
QMessageBox::critical(this, tr("Save Input Profile"),
|
||||||
|
tr("Failed to save the input profile \"%1\"").arg(profile_name));
|
||||||
|
RefreshInputProfiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputPlayer::RefreshInputProfiles() {
|
||||||
|
ui->comboProfiles->clear();
|
||||||
|
|
||||||
|
for (const auto& profile_name : profiles->GetInputProfileNames()) {
|
||||||
|
ui->comboProfiles->addItem(QString::fromStdString(profile_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->comboProfiles->setCurrentIndex(-1);
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ class QString;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
|
|
||||||
|
class InputProfiles;
|
||||||
|
|
||||||
namespace InputCommon {
|
namespace InputCommon {
|
||||||
class InputSubsystem;
|
class InputSubsystem;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +47,7 @@ class ConfigureInputPlayer : public QWidget {
|
||||||
public:
|
public:
|
||||||
explicit ConfigureInputPlayer(QWidget* parent, std::size_t player_index, QWidget* bottom_row,
|
explicit ConfigureInputPlayer(QWidget* parent, std::size_t player_index, QWidget* bottom_row,
|
||||||
InputCommon::InputSubsystem* input_subsystem_,
|
InputCommon::InputSubsystem* input_subsystem_,
|
||||||
bool debug = false);
|
InputProfiles* profiles_, bool debug = false);
|
||||||
~ConfigureInputPlayer() override;
|
~ConfigureInputPlayer() override;
|
||||||
|
|
||||||
/// Save all button configurations to settings file.
|
/// Save all button configurations to settings file.
|
||||||
|
@ -116,6 +118,21 @@ private:
|
||||||
/// Gets the default controller mapping for this device and auto configures the input to match.
|
/// Gets the default controller mapping for this device and auto configures the input to match.
|
||||||
void UpdateMappingWithDefaults();
|
void UpdateMappingWithDefaults();
|
||||||
|
|
||||||
|
/// Creates a controller profile.
|
||||||
|
void CreateProfile();
|
||||||
|
|
||||||
|
/// Deletes the selected controller profile.
|
||||||
|
void DeleteProfile();
|
||||||
|
|
||||||
|
/// Loads the selected controller profile.
|
||||||
|
void LoadProfile();
|
||||||
|
|
||||||
|
/// Saves the current controller configuration into a selected controller profile.
|
||||||
|
void SaveProfile();
|
||||||
|
|
||||||
|
/// Refreshes the list of controller profiles.
|
||||||
|
void RefreshInputProfiles();
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureInputPlayer> ui;
|
std::unique_ptr<Ui::ConfigureInputPlayer> ui;
|
||||||
|
|
||||||
std::size_t player_index;
|
std::size_t player_index;
|
||||||
|
@ -123,6 +140,8 @@ private:
|
||||||
|
|
||||||
InputCommon::InputSubsystem* input_subsystem;
|
InputCommon::InputSubsystem* input_subsystem;
|
||||||
|
|
||||||
|
InputProfiles* profiles;
|
||||||
|
|
||||||
std::unique_ptr<QTimer> timeout_timer;
|
std::unique_ptr<QTimer> timeout_timer;
|
||||||
std::unique_ptr<QTimer> poll_timer;
|
std::unique_ptr<QTimer> poll_timer;
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
|
|
||||||
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id)
|
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), title_id(title_id) {
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), title_id(title_id) {
|
||||||
game_config = std::make_unique<Config>(fmt::format("{:016X}.ini", title_id), false);
|
game_config = std::make_unique<Config>(fmt::format("{:016X}", title_id),
|
||||||
|
Config::ConfigType::PerGameConfig);
|
||||||
|
|
||||||
Settings::SetConfiguringGlobal(false);
|
Settings::SetConfiguringGlobal(false);
|
||||||
|
|
||||||
|
|
131
src/yuzu/configuration/input_profiles.cpp
Normal file
131
src/yuzu/configuration/input_profiles.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "common/common_paths.h"
|
||||||
|
#include "common/file_util.h"
|
||||||
|
#include "yuzu/configuration/config.h"
|
||||||
|
#include "yuzu/configuration/input_profiles.h"
|
||||||
|
|
||||||
|
namespace FS = Common::FS;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool ProfileExistsInFilesystem(std::string_view profile_name) {
|
||||||
|
return FS::Exists(fmt::format("{}input" DIR_SEP "{}.ini",
|
||||||
|
FS::GetUserPath(FS::UserPath::ConfigDir), profile_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsINI(std::string_view filename) {
|
||||||
|
const std::size_t index = filename.rfind('.');
|
||||||
|
|
||||||
|
if (index == std::string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filename.substr(index) == ".ini";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetNameWithoutExtension(const std::string& filename) {
|
||||||
|
const std::size_t index = filename.rfind('.');
|
||||||
|
|
||||||
|
if (index == std::string::npos) {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filename.substr(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
InputProfiles::InputProfiles() {
|
||||||
|
const std::string input_profile_loc =
|
||||||
|
fmt::format("{}input", FS::GetUserPath(FS::UserPath::ConfigDir));
|
||||||
|
|
||||||
|
FS::ForeachDirectoryEntry(
|
||||||
|
nullptr, input_profile_loc,
|
||||||
|
[this](u64* entries_out, const std::string& directory, const std::string& filename) {
|
||||||
|
if (IsINI(filename) && IsProfileNameValid(GetNameWithoutExtension(filename))) {
|
||||||
|
map_profiles.insert_or_assign(
|
||||||
|
GetNameWithoutExtension(filename),
|
||||||
|
std::make_unique<Config>(GetNameWithoutExtension(filename),
|
||||||
|
Config::ConfigType::InputProfile));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
InputProfiles::~InputProfiles() = default;
|
||||||
|
|
||||||
|
std::vector<std::string> InputProfiles::GetInputProfileNames() {
|
||||||
|
std::vector<std::string> profile_names;
|
||||||
|
profile_names.reserve(map_profiles.size());
|
||||||
|
|
||||||
|
for (const auto& [profile_name, config] : map_profiles) {
|
||||||
|
if (!ProfileExistsInFilesystem(profile_name)) {
|
||||||
|
DeleteProfile(profile_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
profile_names.push_back(profile_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::IsProfileNameValid(std::string_view profile_name) {
|
||||||
|
return profile_name.find_first_of("<>:;\"/\\|,.!?*") == std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::CreateProfile(const std::string& profile_name, std::size_t player_index) {
|
||||||
|
if (ProfileExistsInMap(profile_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_profiles.insert_or_assign(
|
||||||
|
profile_name, std::make_unique<Config>(profile_name, Config::ConfigType::InputProfile));
|
||||||
|
|
||||||
|
return SaveProfile(profile_name, player_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::DeleteProfile(const std::string& profile_name) {
|
||||||
|
if (!ProfileExistsInMap(profile_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ProfileExistsInFilesystem(profile_name) ||
|
||||||
|
FS::Delete(map_profiles[profile_name]->GetConfigFilePath())) {
|
||||||
|
map_profiles.erase(profile_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !ProfileExistsInMap(profile_name) && !ProfileExistsInFilesystem(profile_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::LoadProfile(const std::string& profile_name, std::size_t player_index) {
|
||||||
|
if (!ProfileExistsInMap(profile_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ProfileExistsInFilesystem(profile_name)) {
|
||||||
|
map_profiles.erase(profile_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_profiles[profile_name]->ReadControlPlayerValue(player_index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::SaveProfile(const std::string& profile_name, std::size_t player_index) {
|
||||||
|
if (!ProfileExistsInMap(profile_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_profiles[profile_name]->SaveControlPlayerValue(player_index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::ProfileExistsInMap(const std::string& profile_name) const {
|
||||||
|
return map_profiles.find(profile_name) != map_profiles.end();
|
||||||
|
}
|
32
src/yuzu/configuration/input_profiles.h
Normal file
32
src/yuzu/configuration/input_profiles.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class Config;
|
||||||
|
|
||||||
|
class InputProfiles {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit InputProfiles();
|
||||||
|
virtual ~InputProfiles();
|
||||||
|
|
||||||
|
std::vector<std::string> GetInputProfileNames();
|
||||||
|
|
||||||
|
static bool IsProfileNameValid(std::string_view profile_name);
|
||||||
|
|
||||||
|
bool CreateProfile(const std::string& profile_name, std::size_t player_index);
|
||||||
|
bool DeleteProfile(const std::string& profile_name);
|
||||||
|
bool LoadProfile(const std::string& profile_name, std::size_t player_index);
|
||||||
|
bool SaveProfile(const std::string& profile_name, std::size_t player_index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ProfileExistsInMap(const std::string& profile_name) const;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<Config>> map_profiles;
|
||||||
|
};
|
|
@ -1087,7 +1087,7 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||||
const auto loader = Loader::GetLoader(v_file);
|
const auto loader = Loader::GetLoader(v_file);
|
||||||
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
|
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
|
||||||
// Load per game settings
|
// Load per game settings
|
||||||
Config per_game_config(fmt::format("{:016X}.ini", title_id), false);
|
Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::LogSettings();
|
Settings::LogSettings();
|
||||||
|
|
Loading…
Reference in a new issue