narr don't look
This commit is contained in:
@ -15,8 +15,8 @@
|
|||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "input_common/drivers/udp_client.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/udp/client.h"
|
|
||||||
#include "network/network_settings.h"
|
#include "network/network_settings.h"
|
||||||
|
|
||||||
Config::Config() {
|
Config::Config() {
|
||||||
@ -97,7 +97,6 @@ void Config::ReadSetting(const std::string& group, Settings::Setting<Type, range
|
|||||||
|
|
||||||
void Config::ReadValues() {
|
void Config::ReadValues() {
|
||||||
// Controls
|
// Controls
|
||||||
// TODO: add multiple input profile support
|
|
||||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||||
Settings::values.current_input_profile.buttons[i] =
|
Settings::values.current_input_profile.buttons[i] =
|
||||||
|
@ -88,6 +88,8 @@ add_executable(citra-qt
|
|||||||
configuration/configure_cheats.cpp
|
configuration/configure_cheats.cpp
|
||||||
configuration/configure_cheats.h
|
configuration/configure_cheats.h
|
||||||
configuration/configure_cheats.ui
|
configuration/configure_cheats.ui
|
||||||
|
configuration/input_profiles.cpp
|
||||||
|
configuration/input_profiles.h
|
||||||
debugger/console.h
|
debugger/console.h
|
||||||
debugger/console.cpp
|
debugger/console.cpp
|
||||||
debugger/graphics/graphics.cpp
|
debugger/graphics/graphics.cpp
|
||||||
|
@ -27,17 +27,21 @@ Config::~Config() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = {
|
const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = {
|
||||||
Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_T, Qt::Key_G,
|
Qt::Key_C, Qt::Key_X, Qt::Key_V, Qt::Key_Z, Qt::Key_Up, Qt::Key_Down,
|
||||||
Qt::Key_F, Qt::Key_H, Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N,
|
Qt::Key_Left, Qt::Key_Right, Qt::Key_Q, Qt::Key_E, Qt::Key_M, Qt::Key_N,
|
||||||
Qt::Key_O, Qt::Key_P, Qt::Key_1, Qt::Key_2, Qt::Key_B,
|
Qt::Key_O, Qt::Key_P, Qt::Key_R, Qt::Key_T, Qt::Key_B,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motions = {
|
||||||
|
Qt::Key_7,
|
||||||
|
Qt::Key_8,
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{
|
const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{
|
||||||
{
|
{
|
||||||
Qt::Key_Up,
|
Qt::Key_W,
|
||||||
Qt::Key_Down,
|
Qt::Key_S,
|
||||||
Qt::Key_Left,
|
Qt::Key_A,
|
||||||
Qt::Key_Right,
|
|
||||||
Qt::Key_D,
|
Qt::Key_D,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -45,10 +49,14 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config:
|
|||||||
Qt::Key_K,
|
Qt::Key_K,
|
||||||
Qt::Key_J,
|
Qt::Key_J,
|
||||||
Qt::Key_L,
|
Qt::Key_L,
|
||||||
Qt::Key_D,
|
|
||||||
},
|
},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
const std::array<int, 2> Config::default_stick_mod = {
|
||||||
|
Qt::Key_Shift,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
// This shouldn't have anything except static initializers (no functions). So
|
// This shouldn't have anything except static initializers (no functions). So
|
||||||
// QKeySequence(...).toString() is NOT ALLOWED HERE.
|
// QKeySequence(...).toString() is NOT ALLOWED HERE.
|
||||||
// This must be in alphabetical order according to action name as it must have the same order as
|
// This must be in alphabetical order according to action name as it must have the same order as
|
||||||
@ -97,12 +105,21 @@ void Config::Initialize(const std::string& config_name) {
|
|||||||
case ConfigType::PerGameConfig:
|
case ConfigType::PerGameConfig:
|
||||||
qt_config_loc = fmt::format("{}/custom/{}", fs_config_loc, config_file);
|
qt_config_loc = fmt::format("{}/custom/{}", fs_config_loc, config_file);
|
||||||
break;
|
break;
|
||||||
|
case ConfigType::InputProfile:
|
||||||
|
qt_config_loc = fmt::format("{}/input/{}", fs_config_loc, config_file);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileUtil::CreateFullPath(qt_config_loc);
|
FileUtil::CreateFullPath(qt_config_loc);
|
||||||
qt_config =
|
qt_config =
|
||||||
std::make_unique<QSettings>(QString::fromStdString(qt_config_loc), QSettings::IniFormat);
|
std::make_unique<QSettings>(QString::fromStdString(qt_config_loc), QSettings::IniFormat);
|
||||||
|
if (type != ConfigType::InputProfile) {
|
||||||
Reload();
|
Reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::IsCustomConfig() {
|
||||||
|
return type == ConfigType::PerGameConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their
|
/* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their
|
||||||
@ -317,9 +334,78 @@ void Config::ReadCameraValues() {
|
|||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::ReadControlValues() {
|
void Config::ReadPlayerValues() {
|
||||||
qt_config->beginGroup(QStringLiteral("Controls"));
|
const QString player_prefix = [this] {
|
||||||
|
if (type == ConfigType::InputProfile) {
|
||||||
|
return QString{};
|
||||||
|
} else {
|
||||||
|
return QStringLiteral("player_");
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
auto& player = Settings::values.players.GetValue();
|
||||||
|
if (IsCustomConfig()) {
|
||||||
|
const auto profile_name =
|
||||||
|
qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{})
|
||||||
|
.toString()
|
||||||
|
.toStdString();
|
||||||
|
if (profile_name.empty()) {
|
||||||
|
// Use the global input config
|
||||||
|
player = Settings::values.players.GetValue(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
player.profile_name = profile_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||||
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||||
|
auto& player_buttons = player.buttons[i];
|
||||||
|
|
||||||
|
player_buttons = qt_config
|
||||||
|
->value(QStringLiteral("%1").arg(player_prefix) +
|
||||||
|
QString::fromUtf8(Settings::NativeButton::mapping[i]),
|
||||||
|
QString::fromStdString(default_param))
|
||||||
|
.toString()
|
||||||
|
.toStdString();
|
||||||
|
if (player_buttons.empty()) {
|
||||||
|
player_buttons = default_param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||||
|
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||||
|
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||||
|
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||||
|
auto& player_analogs = player.analogs[i];
|
||||||
|
|
||||||
|
player_analogs = qt_config
|
||||||
|
->value(QStringLiteral("%1").arg(player_prefix) +
|
||||||
|
QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
|
||||||
|
QString::fromStdString(default_param))
|
||||||
|
.toString()
|
||||||
|
.toStdString();
|
||||||
|
if (player_analogs.empty()) {
|
||||||
|
player_analogs = default_param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||||
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||||
|
auto& player_motions = player.motions[i];
|
||||||
|
|
||||||
|
player_motions = qt_config
|
||||||
|
->value(QStringLiteral("%1").arg(player_prefix) +
|
||||||
|
QString::fromUtf8(Settings::NativeMotion::mapping[i]),
|
||||||
|
QString::fromStdString(default_param))
|
||||||
|
.toString()
|
||||||
|
.toStdString();
|
||||||
|
if (player_motions.empty()) {
|
||||||
|
player_motions = default_param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::ReadMotionTouchValues() {
|
||||||
int num_touch_from_button_maps =
|
int num_touch_from_button_maps =
|
||||||
qt_config->beginReadArray(QStringLiteral("touch_from_button_maps"));
|
qt_config->beginReadArray(QStringLiteral("touch_from_button_maps"));
|
||||||
|
|
||||||
@ -352,80 +438,26 @@ void Config::ReadControlValues() {
|
|||||||
}
|
}
|
||||||
qt_config->endArray();
|
qt_config->endArray();
|
||||||
|
|
||||||
Settings::values.current_input_profile_index =
|
ReadBasicSetting(Settings::values.touch_device);
|
||||||
ReadSetting(QStringLiteral("profile"), 0).toInt();
|
ReadBasicSetting(Settings::values.touch_from_button_map_index);
|
||||||
|
Settings::values.touch_from_button_map_index = std::clamp(
|
||||||
|
Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
|
||||||
|
|
||||||
const auto append_profile = [this, num_touch_from_button_maps] {
|
ReadBasicSetting(Settings::values.udp_input_address);
|
||||||
Settings::InputProfile profile;
|
ReadBasicSetting(Settings::values.udp_input_port);
|
||||||
profile.name =
|
ReadBasicSetting(Settings::values.udp_pad_index);
|
||||||
ReadSetting(QStringLiteral("name"), QStringLiteral("default")).toString().toStdString();
|
}
|
||||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
|
||||||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
void Config::ReadControlValues() {
|
||||||
profile.buttons[i] = ReadSetting(QString::fromUtf8(Settings::NativeButton::mapping[i]),
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
QString::fromStdString(default_param))
|
|
||||||
.toString()
|
Settings::values.players.SetGlobal(!IsCustomConfig());
|
||||||
.toStdString();
|
ReadPlayerValues();
|
||||||
if (profile.buttons[i].empty())
|
if (IsCustomConfig()) {
|
||||||
profile.buttons[i] = default_param;
|
qt_config->endGroup();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
ReadMotionTouchValues();
|
||||||
std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
|
||||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
|
||||||
default_analogs[i][3], default_analogs[i][4], 0.5f);
|
|
||||||
profile.analogs[i] = ReadSetting(QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
|
|
||||||
QString::fromStdString(default_param))
|
|
||||||
.toString()
|
|
||||||
.toStdString();
|
|
||||||
if (profile.analogs[i].empty())
|
|
||||||
profile.analogs[i] = default_param;
|
|
||||||
}
|
|
||||||
profile.motion_device =
|
|
||||||
ReadSetting(QStringLiteral("motion_device"),
|
|
||||||
QStringLiteral(
|
|
||||||
"engine:motion_emu,update_period:100,sensitivity:0.01,tilt_clamp:90.0"))
|
|
||||||
.toString()
|
|
||||||
.toStdString();
|
|
||||||
profile.touch_device =
|
|
||||||
ReadSetting(QStringLiteral("touch_device"), QStringLiteral("engine:emu_window"))
|
|
||||||
.toString()
|
|
||||||
.toStdString();
|
|
||||||
profile.use_touch_from_button =
|
|
||||||
ReadSetting(QStringLiteral("use_touch_from_button"), false).toBool();
|
|
||||||
profile.touch_from_button_map_index =
|
|
||||||
ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt();
|
|
||||||
profile.touch_from_button_map_index =
|
|
||||||
std::clamp(profile.touch_from_button_map_index, 0, num_touch_from_button_maps - 1);
|
|
||||||
profile.udp_input_address =
|
|
||||||
ReadSetting(QStringLiteral("udp_input_address"), QString::fromUtf8("127.0.0.1"))
|
|
||||||
.toString()
|
|
||||||
.toStdString();
|
|
||||||
profile.udp_input_port =
|
|
||||||
static_cast<u16>(ReadSetting(QStringLiteral("udp_input_port"), 26760).toInt());
|
|
||||||
profile.udp_pad_index =
|
|
||||||
static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt());
|
|
||||||
Settings::values.input_profiles.emplace_back(std::move(profile));
|
|
||||||
};
|
|
||||||
|
|
||||||
int num_input_profiles = qt_config->beginReadArray(QStringLiteral("profiles"));
|
|
||||||
|
|
||||||
for (int i = 0; i < num_input_profiles; ++i) {
|
|
||||||
qt_config->setArrayIndex(i);
|
|
||||||
append_profile();
|
|
||||||
}
|
|
||||||
|
|
||||||
qt_config->endArray();
|
|
||||||
|
|
||||||
// create a input profile if no input profiles exist, with the default or old settings
|
|
||||||
if (num_input_profiles == 0) {
|
|
||||||
append_profile();
|
|
||||||
num_input_profiles = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that the current input profile index is valid.
|
|
||||||
Settings::values.current_input_profile_index =
|
|
||||||
std::clamp(Settings::values.current_input_profile_index, 0, num_input_profiles - 1);
|
|
||||||
|
|
||||||
Settings::LoadProfile(Settings::values.current_input_profile_index);
|
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
@ -882,60 +914,87 @@ void Config::SaveCameraValues() {
|
|||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::SaveControlValues() {
|
void Config::SavePlayerValues() {
|
||||||
qt_config->beginGroup(QStringLiteral("Controls"));
|
const QString player_prefix = [this] {
|
||||||
|
if (type == ConfigType::InputProfile) {
|
||||||
|
return QString{};
|
||||||
|
} else {
|
||||||
|
return QStringLiteral("player_");
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
const auto& player = Settings::values.players.GetValue();
|
||||||
|
if (IsCustomConfig()) {
|
||||||
|
if (player.profile_name.empty()) {
|
||||||
|
// No custom profile selected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix),
|
||||||
|
QString::fromStdString(player.profile_name), QString{});
|
||||||
|
}
|
||||||
|
|
||||||
WriteSetting(QStringLiteral("profile"), Settings::values.current_input_profile_index, 0);
|
|
||||||
qt_config->beginWriteArray(QStringLiteral("profiles"));
|
|
||||||
for (std::size_t p = 0; p < Settings::values.input_profiles.size(); ++p) {
|
|
||||||
qt_config->setArrayIndex(static_cast<int>(p));
|
|
||||||
const auto& profile = Settings::values.input_profiles[p];
|
|
||||||
WriteSetting(QStringLiteral("name"), QString::fromStdString(profile.name),
|
|
||||||
QStringLiteral("default"));
|
|
||||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||||
WriteSetting(QString::fromStdString(Settings::NativeButton::mapping[i]),
|
WriteSetting(QStringLiteral("%1").arg(player_prefix) +
|
||||||
QString::fromStdString(profile.buttons[i]),
|
QString::fromStdString(Settings::NativeButton::mapping[i]),
|
||||||
|
QString::fromStdString(player.buttons[i]),
|
||||||
QString::fromStdString(default_param));
|
QString::fromStdString(default_param));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||||
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_analogs[i][4], 0.5f);
|
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||||
WriteSetting(QString::fromStdString(Settings::NativeAnalog::mapping[i]),
|
WriteSetting(QStringLiteral("%1").arg(player_prefix) +
|
||||||
QString::fromStdString(profile.analogs[i]),
|
QString::fromStdString(Settings::NativeAnalog::mapping[i]),
|
||||||
|
QString::fromStdString(player.analogs[i]),
|
||||||
QString::fromStdString(default_param));
|
QString::fromStdString(default_param));
|
||||||
}
|
}
|
||||||
WriteSetting(
|
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||||
QStringLiteral("motion_device"), QString::fromStdString(profile.motion_device),
|
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||||
QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01,tilt_clamp:90.0"));
|
WriteSetting(QStringLiteral("%1").arg(player_prefix) +
|
||||||
WriteSetting(QStringLiteral("touch_device"), QString::fromStdString(profile.touch_device),
|
QString::fromStdString(Settings::NativeMotion::mapping[i]),
|
||||||
QStringLiteral("engine:emu_window"));
|
QString::fromStdString(player.motions[i]),
|
||||||
WriteSetting(QStringLiteral("use_touch_from_button"), profile.use_touch_from_button, false);
|
QString::fromStdString(default_param));
|
||||||
WriteSetting(QStringLiteral("touch_from_button_map"), profile.touch_from_button_map_index,
|
|
||||||
0);
|
|
||||||
WriteSetting(QStringLiteral("udp_input_address"),
|
|
||||||
QString::fromStdString(profile.udp_input_address),
|
|
||||||
QString::fromUtf8("127.0.0.1"));
|
|
||||||
WriteSetting(QStringLiteral("udp_input_port"), profile.udp_input_port, 26760);
|
|
||||||
WriteSetting(QStringLiteral("udp_pad_index"), profile.udp_pad_index, 0);
|
|
||||||
}
|
}
|
||||||
qt_config->endArray();
|
}
|
||||||
|
|
||||||
|
void Config::SaveMotionTouchValues() {
|
||||||
|
WriteBasicSetting(Settings::values.touch_device);
|
||||||
|
WriteBasicSetting(Settings::values.touch_from_button_map_index);
|
||||||
|
|
||||||
|
WriteBasicSetting(Settings::values.udp_input_address);
|
||||||
|
WriteBasicSetting(Settings::values.udp_input_port);
|
||||||
|
WriteBasicSetting(Settings::values.udp_pad_index);
|
||||||
|
|
||||||
qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));
|
qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));
|
||||||
for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
|
for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
|
||||||
qt_config->setArrayIndex(static_cast<int>(p));
|
qt_config->setArrayIndex(static_cast<int>(p));
|
||||||
const auto& map = Settings::values.touch_from_button_maps[p];
|
WriteSetting(QStringLiteral("name"),
|
||||||
WriteSetting(QStringLiteral("name"), QString::fromStdString(map.name),
|
QString::fromStdString(Settings::values.touch_from_button_maps[p].name),
|
||||||
QStringLiteral("default"));
|
QStringLiteral("default"));
|
||||||
qt_config->beginWriteArray(QStringLiteral("entries"));
|
qt_config->beginWriteArray(QStringLiteral("entries"));
|
||||||
for (std::size_t q = 0; q < map.buttons.size(); ++q) {
|
for (std::size_t q = 0; q < Settings::values.touch_from_button_maps[p].buttons.size();
|
||||||
|
++q) {
|
||||||
qt_config->setArrayIndex(static_cast<int>(q));
|
qt_config->setArrayIndex(static_cast<int>(q));
|
||||||
WriteSetting(QStringLiteral("bind"), QString::fromStdString(map.buttons[q]));
|
WriteSetting(
|
||||||
|
QStringLiteral("bind"),
|
||||||
|
QString::fromStdString(Settings::values.touch_from_button_maps[p].buttons[q]));
|
||||||
}
|
}
|
||||||
qt_config->endArray();
|
qt_config->endArray();
|
||||||
}
|
}
|
||||||
qt_config->endArray();
|
qt_config->endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::SaveControlValues() {
|
||||||
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
|
||||||
|
Settings::values.players.SetGlobal(!IsCustomConfig());
|
||||||
|
SavePlayerValues();
|
||||||
|
if (IsCustomConfig()) {
|
||||||
|
qt_config->endGroup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SaveMotionTouchValues();
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
@ -1299,3 +1358,26 @@ void Config::Reload() {
|
|||||||
void Config::Save() {
|
void Config::Save() {
|
||||||
SaveValues();
|
SaveValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Config::ReadControlPlayerValues() {
|
||||||
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
ReadPlayerValues();
|
||||||
|
qt_config->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::SaveControlPlayerValues() {
|
||||||
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
SavePlayerValues();
|
||||||
|
qt_config->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::ClearControlPlayerValues() {
|
||||||
|
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||||
|
// If key is an empty string, all keys in the current group() are removed.
|
||||||
|
qt_config->remove(QString{});
|
||||||
|
qt_config->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Config::GetConfigFilePath() const {
|
||||||
|
return qt_config_loc;
|
||||||
|
}
|
@ -15,7 +15,11 @@ class QSettings;
|
|||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
enum class ConfigType : u32 { GlobalConfig, PerGameConfig };
|
enum class ConfigType : u32 {
|
||||||
|
GlobalConfig,
|
||||||
|
PerGameConfig,
|
||||||
|
InputProfile,
|
||||||
|
};
|
||||||
|
|
||||||
explicit Config(const std::string& config_name = "qt-config",
|
explicit Config(const std::string& config_name = "qt-config",
|
||||||
ConfigType config_type = ConfigType::GlobalConfig);
|
ConfigType config_type = ConfigType::GlobalConfig);
|
||||||
@ -24,17 +28,28 @@ public:
|
|||||||
void Reload();
|
void Reload();
|
||||||
void Save();
|
void Save();
|
||||||
|
|
||||||
|
// Used for input profiles
|
||||||
|
void ReadControlPlayerValues();
|
||||||
|
void SaveControlPlayerValues();
|
||||||
|
void ClearControlPlayerValues();
|
||||||
|
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<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
||||||
static const std::array<UISettings::Shortcut, 28> default_hotkeys;
|
static const std::array<UISettings::Shortcut, 28> default_hotkeys;
|
||||||
|
static const std::array<int, 2> default_stick_mod;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize(const std::string& config_name);
|
void Initialize(const std::string& config_name);
|
||||||
|
bool IsCustomConfig();
|
||||||
|
|
||||||
void ReadValues();
|
void ReadValues();
|
||||||
|
void ReadPlayerValues();
|
||||||
|
void ReadMotionTouchValues();
|
||||||
|
void ReadControlValues();
|
||||||
void ReadAudioValues();
|
void ReadAudioValues();
|
||||||
void ReadCameraValues();
|
void ReadCameraValues();
|
||||||
void ReadControlValues();
|
|
||||||
void ReadCoreValues();
|
void ReadCoreValues();
|
||||||
void ReadDataStorageValues();
|
void ReadDataStorageValues();
|
||||||
void ReadDebuggingValues();
|
void ReadDebuggingValues();
|
||||||
@ -54,9 +69,11 @@ private:
|
|||||||
void ReadVideoDumpingValues();
|
void ReadVideoDumpingValues();
|
||||||
|
|
||||||
void SaveValues();
|
void SaveValues();
|
||||||
|
void SavePlayerValues();
|
||||||
|
void SaveMotionTouchValues();
|
||||||
|
void SaveControlValues();
|
||||||
void SaveAudioValues();
|
void SaveAudioValues();
|
||||||
void SaveCameraValues();
|
void SaveCameraValues();
|
||||||
void SaveControlValues();
|
|
||||||
void SaveCoreValues();
|
void SaveCoreValues();
|
||||||
void SaveDataStorageValues();
|
void SaveDataStorageValues();
|
||||||
void SaveDebuggingValues();
|
void SaveDebuggingValues();
|
||||||
|
@ -61,7 +61,6 @@ void ConfigureDialog::ApplyConfiguration() {
|
|||||||
ui->generalTab->ApplyConfiguration();
|
ui->generalTab->ApplyConfiguration();
|
||||||
ui->systemTab->ApplyConfiguration();
|
ui->systemTab->ApplyConfiguration();
|
||||||
ui->inputTab->ApplyConfiguration();
|
ui->inputTab->ApplyConfiguration();
|
||||||
ui->inputTab->ApplyProfile();
|
|
||||||
ui->hotkeysTab->ApplyConfiguration(registry);
|
ui->hotkeysTab->ApplyConfiguration(registry);
|
||||||
ui->graphicsTab->ApplyConfiguration();
|
ui->graphicsTab->ApplyConfiguration();
|
||||||
ui->enhancementsTab->ApplyConfiguration();
|
ui->enhancementsTab->ApplyConfiguration();
|
||||||
|
@ -5,19 +5,26 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <QGridLayout>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QLabel>
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSlider>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QWheelEvent>
|
||||||
|
#include "citra_qt/bootmanager.h"
|
||||||
#include "citra_qt/configuration/config.h"
|
#include "citra_qt/configuration/config.h"
|
||||||
#include "citra_qt/configuration/configure_input.h"
|
#include "citra_qt/configuration/configure_input.h"
|
||||||
#include "citra_qt/configuration/configure_motion_touch.h"
|
#include "citra_qt/configuration/configure_motion_touch.h"
|
||||||
|
#include "citra_qt/configuration/input_profiles.h"
|
||||||
|
#include "common/assert.h"
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/hid/emulated_controller.h"
|
#include "core/hid/emulated_controller.h"
|
||||||
|
#include "core/hid/hid_core.h"
|
||||||
|
#include "core/hid/hid_types.h"
|
||||||
|
#include "input_common/drivers/keyboard.h"
|
||||||
|
#include "input_common/drivers/mouse.h"
|
||||||
|
#include "input_common/main.h"
|
||||||
#include "ui_configure_input.h"
|
#include "ui_configure_input.h"
|
||||||
|
|
||||||
const std::array<std::string, ConfigureInput::ANALOG_SUB_BUTTONS_NUM>
|
const std::array<std::string, ConfigureInput::ANALOG_SUB_BUTTONS_NUM>
|
||||||
@ -271,15 +278,10 @@ ConfigureInput::~ConfigureInput() {
|
|||||||
void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem_) {
|
void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem_) {
|
||||||
input_subsystem = input_subsystem_;
|
input_subsystem = input_subsystem_;
|
||||||
emulated_controller = Core::System::GetInstance().HIDCore().GetEmulatedController();
|
emulated_controller = Core::System::GetInstance().HIDCore().GetEmulatedController();
|
||||||
|
profiles = std::make_unique<InputProfiles>();
|
||||||
|
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
|
||||||
for (const auto& profile : Settings::values.input_profiles) {
|
|
||||||
ui->profile->addItem(QString::fromStdString(profile.name));
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->profile->setCurrentIndex(Settings::values.current_input_profile_index);
|
|
||||||
|
|
||||||
button_map = {
|
button_map = {
|
||||||
ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
|
ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
|
||||||
ui->buttonDpadUp, ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight,
|
ui->buttonDpadUp, ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight,
|
||||||
@ -294,14 +296,12 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem_) {
|
|||||||
ui->buttonCirclePadDown,
|
ui->buttonCirclePadDown,
|
||||||
ui->buttonCirclePadLeft,
|
ui->buttonCirclePadLeft,
|
||||||
ui->buttonCirclePadRight,
|
ui->buttonCirclePadRight,
|
||||||
nullptr,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ui->buttonCStickUp,
|
ui->buttonCStickUp,
|
||||||
ui->buttonCStickDown,
|
ui->buttonCStickDown,
|
||||||
ui->buttonCStickLeft,
|
ui->buttonCStickLeft,
|
||||||
ui->buttonCStickRight,
|
ui->buttonCStickRight,
|
||||||
nullptr,
|
|
||||||
},
|
},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@ -624,13 +624,12 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem_) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// UpdateInputProfiles();
|
UpdateInputProfiles();
|
||||||
|
connect(ui->buttonProfilesNew, &QPushButton::clicked, this, &ConfigureInput::CreateProfile);
|
||||||
connect(ui->buttonProfilesNew, &QPushButton::clicked, this, &ConfigureInput::NewProfile);
|
|
||||||
connect(ui->buttonProfilesDelete, &QPushButton::clicked, this, &ConfigureInput::DeleteProfile);
|
connect(ui->buttonProfilesDelete, &QPushButton::clicked, this, &ConfigureInput::DeleteProfile);
|
||||||
// connect(ui->comboProfiles, qOverload<int>(&QComboBox::activated), this,
|
connect(ui->comboProfiles, qOverload<int>(&QComboBox::activated), this,
|
||||||
// &ConfigureInput::LoadProfile);
|
&ConfigureInput::LoadProfile);
|
||||||
// connect(ui->buttonProfilesSave, &QPushButton::clicked, this, &ConfigureInput::SaveProfile);
|
connect(ui->buttonProfilesSave, &QPushButton::clicked, this, &ConfigureInput::SaveProfile);
|
||||||
|
|
||||||
connect(ui->buttonMotionTouch, &QPushButton::clicked, [this, input_subsystem_] {
|
connect(ui->buttonMotionTouch, &QPushButton::clicked, [this, input_subsystem_] {
|
||||||
QDialog* motion_touch_dialog = new ConfigureMotionTouch(this, input_subsystem_);
|
QDialog* motion_touch_dialog = new ConfigureMotionTouch(this, input_subsystem_);
|
||||||
@ -648,41 +647,6 @@ void ConfigureInput::ApplyConfiguration() {
|
|||||||
emulated_controller->EnableConfiguration();
|
emulated_controller->EnableConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInput::ApplyProfile() {
|
|
||||||
Settings::values.current_input_profile_index = ui->profile->currentIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInput::EmitInputKeysChanged() {
|
|
||||||
emit InputKeysChanged(GetUsedKeyboardKeys());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInput::OnHotkeysChanged(QList<QKeySequence> new_key_list) {
|
|
||||||
hotkey_list = new_key_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QKeySequence> ConfigureInput::GetUsedKeyboardKeys() {
|
|
||||||
QList<QKeySequence> list;
|
|
||||||
for (int button = 0; button < Settings::NativeButton::NumButtons; button++) {
|
|
||||||
const auto& button_param = buttons_param[button];
|
|
||||||
if (button_param.Get("engine", "") == "keyboard") {
|
|
||||||
list << QKeySequence(button_param.Get("code", 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
|
|
||||||
const auto& analog_param = analogs_param[analog_id];
|
|
||||||
if (analog_param.Get("engine", "") == "analog_from_button") {
|
|
||||||
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
|
|
||||||
const Common::ParamPackage sub_button{
|
|
||||||
analog_param.Get(analog_sub_buttons[sub_button_id], "")};
|
|
||||||
list << QKeySequence(sub_button.Get("code", 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInput::LoadConfiguration() {
|
void ConfigureInput::LoadConfiguration() {
|
||||||
emulated_controller->ReloadFromSettings();
|
emulated_controller->ReloadFromSettings();
|
||||||
|
|
||||||
@ -813,6 +777,7 @@ void ConfigureInput::UpdateMappingWithDefaults() {
|
|||||||
button_id, Common::ParamPackage{InputCommon::GenerateKeyboardParam(
|
button_id, Common::ParamPackage{InputCommon::GenerateKeyboardParam(
|
||||||
Config::default_buttons[button_id])});
|
Config::default_buttons[button_id])});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
|
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
|
||||||
Common::ParamPackage analog_param{};
|
Common::ParamPackage analog_param{};
|
||||||
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
|
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
|
||||||
@ -821,8 +786,8 @@ void ConfigureInput::UpdateMappingWithDefaults() {
|
|||||||
SetAnalogParam(params, analog_param, analog_sub_buttons[sub_button_id]);
|
SetAnalogParam(params, analog_param, analog_sub_buttons[sub_button_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* analog_param.Set("modifier", InputCommon::GenerateKeyboardParam(
|
analog_param.Set("modifier", InputCommon::GenerateKeyboardParam(
|
||||||
Config::default_stick_mod[analog_id]));*/
|
Config::default_stick_mod[analog_id]));
|
||||||
emulated_controller->SetStickParam(analog_id, analog_param);
|
emulated_controller->SetStickParam(analog_id, analog_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,6 +826,7 @@ void ConfigureInput::HandleClick(QPushButton* button, std::size_t button_id,
|
|||||||
if (timeout_timer->isActive()) {
|
if (timeout_timer->isActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
button->setText(tr("[waiting]"));
|
||||||
button->setFocus();
|
button->setFocus();
|
||||||
|
|
||||||
input_setter = std::move(new_input_setter);
|
input_setter = std::move(new_input_setter);
|
||||||
@ -870,7 +836,7 @@ void ConfigureInput::HandleClick(QPushButton* button, std::size_t button_id,
|
|||||||
QWidget::grabMouse();
|
QWidget::grabMouse();
|
||||||
QWidget::grabKeyboard();
|
QWidget::grabKeyboard();
|
||||||
|
|
||||||
timeout_timer->start(2500); // Cancel after 2.5 seconds
|
timeout_timer->start(4000); // Cancel after 4 seconds
|
||||||
poll_timer->start(25); // Check for new inputs every 25ms
|
poll_timer->start(25); // Check for new inputs every 25ms
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,30 +879,44 @@ void ConfigureInput::SetPollingResult(const Common::ParamPackage& params, bool a
|
|||||||
input_setter = std::nullopt;
|
input_setter = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInput::keyPressEvent(QKeyEvent* event) {
|
void ConfigureInput::mousePressEvent(QMouseEvent* event) {
|
||||||
if (!input_setter || !event)
|
if (!input_setter || !event) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event->key() != Qt::Key_Escape && event->key() != previous_key_code) {
|
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
|
||||||
if (want_keyboard_keys) {
|
input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
|
||||||
// Check if key is already bound
|
}
|
||||||
if (hotkey_list.contains(QKeySequence(event->key())) ||
|
|
||||||
GetUsedKeyboardKeys().contains(QKeySequence(event->key()))) {
|
void ConfigureInput::wheelEvent(QWheelEvent* event) {
|
||||||
SetPollingResult({}, true);
|
const int x = event->angleDelta().x();
|
||||||
QMessageBox::critical(this, tr("Error!"),
|
const int y = event->angleDelta().y();
|
||||||
tr("You're using a key that's already bound."));
|
input_subsystem->GetMouse()->MouseWheelChange(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInput::keyPressEvent(QKeyEvent* event) {
|
||||||
|
if (!input_setter || !event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->key())},
|
event->ignore();
|
||||||
false);
|
if (event->key() != Qt::Key_Escape) {
|
||||||
} else {
|
input_subsystem->GetKeyboard()->PressKey(event->key());
|
||||||
// Escape key wasn't pressed and we don't want any keyboard keys, so don't stop
|
|
||||||
// polling
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigureInput::eventFilter(QObject* object, QEvent* event) {
|
||||||
|
if (object == ui->comboDevices && event->type() == QEvent::MouseButtonPress) {
|
||||||
|
UpdateInputDeviceCombobox();
|
||||||
}
|
}
|
||||||
SetPollingResult({}, true);
|
return object->eventFilter(object, event);
|
||||||
previous_key_code = 0;
|
}
|
||||||
|
|
||||||
|
void ConfigureInput::changeEvent(QEvent* event) {
|
||||||
|
if (event->type() == QEvent::LanguageChange) {
|
||||||
|
RetranslateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget::changeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInput::RetranslateUI() {
|
void ConfigureInput::RetranslateUI() {
|
||||||
@ -1028,60 +1008,128 @@ void ConfigureInput::UpdateInputDeviceCombobox() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInput::NewProfile() {
|
void ConfigureInput::EmitInputKeysChanged() {
|
||||||
const QString name =
|
emit InputKeysChanged(GetUsedKeyboardKeys());
|
||||||
QInputDialog::getText(this, tr("New Profile"), tr("Enter the name for the new profile."));
|
}
|
||||||
if (name.isEmpty()) {
|
|
||||||
|
void ConfigureInput::OnHotkeysChanged(QList<QKeySequence> new_key_list) {
|
||||||
|
hotkey_list = new_key_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QKeySequence> ConfigureInput::GetUsedKeyboardKeys() {
|
||||||
|
QList<QKeySequence> list;
|
||||||
|
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
|
||||||
|
const auto& button_param = emulated_controller->GetButtonParam(button_id);
|
||||||
|
if (button_param.Get("engine", "") == "keyboard") {
|
||||||
|
list << QKeySequence(button_param.Get("code", 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
|
||||||
|
const auto& analog_param = emulated_controller->GetStickParam(analog_id);
|
||||||
|
if (analog_param.Get("engine", "") == "analog_from_button") {
|
||||||
|
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
|
||||||
|
const Common::ParamPackage sub_button{
|
||||||
|
analog_param.Get(analog_sub_buttons[sub_button_id], "")};
|
||||||
|
list << QKeySequence(sub_button.Get("code", 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInput::CreateProfile() {
|
||||||
|
const QString profile_name =
|
||||||
|
QInputDialog::getText(this, tr("New Profile"), tr("Enter a profile name:"));
|
||||||
|
|
||||||
|
if (profile_name.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (IsProfileNameDuplicate(name)) {
|
|
||||||
WarnProposedProfileNameIsDuplicate();
|
if (!InputProfiles::IsProfileNameValid(profile_name.toStdString())) {
|
||||||
|
QMessageBox::critical(this, tr("Create Input Profile"),
|
||||||
|
tr("The given profile name is not valid!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyConfiguration();
|
ApplyConfiguration();
|
||||||
Settings::SaveProfile(ui->profile->currentIndex());
|
|
||||||
Settings::CreateProfile(name.toStdString());
|
if (!profiles->CreateProfile(profile_name.toStdString())) {
|
||||||
ui->profile->addItem(name);
|
QMessageBox::critical(this, tr("Create Input Profile"),
|
||||||
ui->profile->setCurrentIndex(Settings::values.current_input_profile_index);
|
tr("Failed to create the input profile \"%1\"").arg(profile_name));
|
||||||
LoadConfiguration();
|
UpdateInputProfiles();
|
||||||
ui->buttonProfilesDelete->setEnabled(ui->profile->count() > 1);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateInputProfiles();
|
||||||
|
|
||||||
|
ui->comboProfiles->addItem(profile_name);
|
||||||
|
ui->comboProfiles->setCurrentIndex(ui->comboProfiles->count() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInput::DeleteProfile() {
|
void ConfigureInput::DeleteProfile() {
|
||||||
const auto answer = QMessageBox::question(
|
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||||
this, tr("Delete Profile"), tr("Delete profile %1?").arg(ui->profile->currentText()));
|
|
||||||
if (answer != QMessageBox::Yes) {
|
if (profile_name.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int index = ui->profile->currentIndex();
|
|
||||||
ui->profile->removeItem(index);
|
if (!profiles->DeleteProfile(profile_name.toStdString())) {
|
||||||
ui->profile->setCurrentIndex(0);
|
QMessageBox::critical(this, tr("Delete Input Profile"),
|
||||||
Settings::DeleteProfile(index);
|
tr("Failed to delete the input profile \"%1\"").arg(profile_name));
|
||||||
|
UpdateInputProfiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateInputProfiles();
|
||||||
|
|
||||||
|
ui->comboProfiles->removeItem(ui->comboProfiles->currentIndex());
|
||||||
|
ui->comboProfiles->setCurrentIndex(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInput::LoadProfile() {
|
||||||
|
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||||
|
|
||||||
|
if (profile_name.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyConfiguration();
|
||||||
|
|
||||||
|
if (!profiles->LoadProfile(profile_name.toStdString())) {
|
||||||
|
QMessageBox::critical(this, tr("Load Input Profile"),
|
||||||
|
tr("Failed to load the input profile \"%1\"").arg(profile_name));
|
||||||
|
UpdateInputProfiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LoadConfiguration();
|
LoadConfiguration();
|
||||||
ui->buttonProfilesDelete->setEnabled(ui->profile->count() > 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInput::RenameProfile() {
|
void ConfigureInput::SaveProfile() {
|
||||||
const QString new_name = QInputDialog::getText(this, tr("Rename Profile"), tr("New name:"));
|
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||||
if (new_name.isEmpty()) {
|
|
||||||
return;
|
if (profile_name.isEmpty()) {
|
||||||
}
|
|
||||||
if (IsProfileNameDuplicate(new_name)) {
|
|
||||||
WarnProposedProfileNameIsDuplicate();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->profile->setItemText(ui->profile->currentIndex(), new_name);
|
ApplyConfiguration();
|
||||||
Settings::RenameCurrentProfile(new_name.toStdString());
|
|
||||||
Settings::SaveProfile(ui->profile->currentIndex());
|
if (!profiles->SaveProfile(profile_name.toStdString())) {
|
||||||
|
QMessageBox::critical(this, tr("Save Input Profile"),
|
||||||
|
tr("Failed to save the input profile \"%1\"").arg(profile_name));
|
||||||
|
UpdateInputProfiles();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigureInput::IsProfileNameDuplicate(const QString& name) const {
|
void ConfigureInput::UpdateInputProfiles() {
|
||||||
return ui->profile->findText(name, Qt::MatchFixedString | Qt::MatchCaseSensitive) != -1;
|
ui->comboProfiles->clear();
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInput::WarnProposedProfileNameIsDuplicate() {
|
for (const auto& profile_name : profiles->GetInputProfileNames()) {
|
||||||
QMessageBox::warning(this, tr("Duplicate profile name"),
|
ui->comboProfiles->addItem(QString::fromStdString(profile_name));
|
||||||
tr("Profile name already exists. Please choose a different name."));
|
}
|
||||||
|
|
||||||
|
ui->comboProfiles->setCurrentIndex(-1);
|
||||||
}
|
}
|
||||||
|
@ -9,29 +9,42 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <vector>
|
||||||
#include <QGroupBox>
|
|
||||||
#include <QKeySequence>
|
|
||||||
#include <QSpinBox>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "ui_configure_input.h"
|
||||||
|
|
||||||
|
class QCheckBox;
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QSlider;
|
class QSlider;
|
||||||
|
class QSpinBox;
|
||||||
class QString;
|
class QString;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
namespace Core::HID {
|
class InputProfiles;
|
||||||
class EmulatedController;
|
|
||||||
} // namespace Core::HID
|
namespace InputCommon {
|
||||||
|
class InputSubsystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace InputCommon::Polling {
|
||||||
|
enum class InputType;
|
||||||
|
} // namespace InputCommon::Polling
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureInput;
|
class ConfigureInput;
|
||||||
}
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Core::HID {
|
||||||
|
class HIDCore;
|
||||||
|
class EmulatedController;
|
||||||
|
} // namespace Core::HID
|
||||||
|
|
||||||
class ConfigureInput : public QWidget {
|
class ConfigureInput : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -40,18 +53,32 @@ public:
|
|||||||
explicit ConfigureInput(QWidget* parent = nullptr);
|
explicit ConfigureInput(QWidget* parent = nullptr);
|
||||||
~ConfigureInput() override;
|
~ConfigureInput() override;
|
||||||
|
|
||||||
|
/// Initializes the ConfigureInput dialog
|
||||||
void Initialize(InputCommon::InputSubsystem* input_subsystem_);
|
void Initialize(InputCommon::InputSubsystem* input_subsystem_);
|
||||||
|
|
||||||
/// Save all button configurations to settings file
|
|
||||||
void ApplyConfiguration();
|
|
||||||
void RetranslateUI();
|
|
||||||
|
|
||||||
/// Load configuration settings.
|
/// Load configuration settings.
|
||||||
void LoadConfiguration();
|
void LoadConfiguration();
|
||||||
|
|
||||||
|
/// Save all button configurations to settings file.
|
||||||
|
void ApplyConfiguration();
|
||||||
|
|
||||||
|
/// Update the input devices combobox.
|
||||||
|
void UpdateInputDeviceCombobox();
|
||||||
|
|
||||||
|
/// Updates the list of controller profiles.
|
||||||
|
void UpdateInputProfiles();
|
||||||
|
|
||||||
|
/// Restore all buttons to their default values.
|
||||||
|
void RestoreDefaults();
|
||||||
|
|
||||||
|
/// Clear all input configuration.
|
||||||
|
void ClearAll();
|
||||||
|
|
||||||
|
/// Updates UI with selected language translations
|
||||||
|
void RetranslateUI();
|
||||||
|
|
||||||
void EmitInputKeysChanged();
|
void EmitInputKeysChanged();
|
||||||
|
|
||||||
/// Save the current input profile index
|
|
||||||
void ApplyProfile();
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnHotkeysChanged(QList<QKeySequence> new_key_list);
|
void OnHotkeysChanged(QList<QKeySequence> new_key_list);
|
||||||
|
|
||||||
@ -59,16 +86,65 @@ signals:
|
|||||||
void InputKeysChanged(QList<QKeySequence> new_key_list);
|
void InputKeysChanged(QList<QKeySequence> new_key_list);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Generates list of all used keys
|
||||||
|
QList<QKeySequence> GetUsedKeyboardKeys();
|
||||||
|
|
||||||
QString ButtonToText(const Common::ParamPackage& param);
|
QString ButtonToText(const Common::ParamPackage& param);
|
||||||
|
|
||||||
QString AnalogToText(const Common::ParamPackage& param, const std::string& dir);
|
QString AnalogToText(const Common::ParamPackage& param, const std::string& dir);
|
||||||
|
|
||||||
|
void changeEvent(QEvent* event) override;
|
||||||
|
|
||||||
|
/// Called when the button was pressed.
|
||||||
|
void HandleClick(QPushButton* button, std::size_t button_id,
|
||||||
|
std::function<void(const Common::ParamPackage&)> new_input_setter,
|
||||||
|
InputCommon::Polling::InputType type);
|
||||||
|
|
||||||
|
/// Finish polling and configure input using the input_setter.
|
||||||
|
void SetPollingResult(const Common::ParamPackage& params, bool abort);
|
||||||
|
|
||||||
|
/// Checks whether a given input can be accepted.
|
||||||
|
bool IsInputAcceptable(const Common::ParamPackage& params) const;
|
||||||
|
|
||||||
|
/// Handle mouse button press events.
|
||||||
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
|
||||||
|
/// Handle mouse wheel move events.
|
||||||
|
void wheelEvent(QWheelEvent* event) override;
|
||||||
|
|
||||||
|
/// Handle key press events.
|
||||||
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
|
||||||
|
/// Handle combobox list refresh
|
||||||
|
bool eventFilter(QObject* object, QEvent* event) override;
|
||||||
|
|
||||||
/// Update UI to reflect current configuration.
|
/// Update UI to reflect current configuration.
|
||||||
void UpdateUI();
|
void UpdateUI();
|
||||||
|
|
||||||
|
/// Update the available input devices.
|
||||||
|
void UpdateInputDevices();
|
||||||
|
|
||||||
|
/// Gets the default controller mapping for this device and auto configures the input to match.
|
||||||
|
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();
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureInput> ui;
|
std::unique_ptr<Ui::ConfigureInput> ui;
|
||||||
|
|
||||||
InputCommon::InputSubsystem* input_subsystem;
|
InputCommon::InputSubsystem* input_subsystem;
|
||||||
|
|
||||||
|
std::unique_ptr<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;
|
||||||
|
|
||||||
@ -77,23 +153,18 @@ private:
|
|||||||
|
|
||||||
Core::HID::EmulatedController* emulated_controller;
|
Core::HID::EmulatedController* emulated_controller;
|
||||||
|
|
||||||
std::array<Common::ParamPackage, Settings::NativeButton::NumButtons> buttons_param;
|
static constexpr int ANALOG_SUB_BUTTONS_NUM = 4;
|
||||||
std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs> analogs_param;
|
|
||||||
|
|
||||||
static constexpr int ANALOG_SUB_BUTTONS_NUM = 5;
|
|
||||||
|
|
||||||
/// Each button input is represented by a QPushButton.
|
/// Each button input is represented by a QPushButton.
|
||||||
std::array<QPushButton*, Settings::NativeButton::NumButtons> button_map;
|
std::array<QPushButton*, Settings::NativeButton::NumButtons> button_map;
|
||||||
|
|
||||||
/// A group of five QPushButtons represent one analog input. The buttons each represent up,
|
/// A group of four QPushButtons represent one analog input. The buttons each represent up,
|
||||||
/// down, left, right, and modifier, respectively.
|
/// down, left, right, respectively.
|
||||||
std::array<std::array<QPushButton*, ANALOG_SUB_BUTTONS_NUM>, Settings::NativeAnalog::NumAnalogs>
|
std::array<std::array<QPushButton*, ANALOG_SUB_BUTTONS_NUM>, Settings::NativeAnalog::NumAnalogs>
|
||||||
analog_map_buttons;
|
analog_map_buttons;
|
||||||
|
|
||||||
/// Analog inputs are also represented each with a single button, used to configure with an
|
/// Each motion input is represented by a QPushButton.
|
||||||
/// actual analog stick
|
std::array<QPushButton*, Settings::NativeMotion::NumMotions> motion_map;
|
||||||
std::array<QPushButton*, Settings::NativeAnalog::NumAnalogs> analog_map_stick;
|
|
||||||
static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons;
|
|
||||||
|
|
||||||
std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone_label;
|
std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone_label;
|
||||||
std::array<QSlider*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone_slider;
|
std::array<QSlider*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone_slider;
|
||||||
@ -104,8 +175,7 @@ private:
|
|||||||
std::array<QGroupBox*, Settings::NativeAnalog::NumAnalogs> analog_map_range_groupbox;
|
std::array<QGroupBox*, Settings::NativeAnalog::NumAnalogs> analog_map_range_groupbox;
|
||||||
std::array<QSpinBox*, Settings::NativeAnalog::NumAnalogs> analog_map_range_spinbox;
|
std::array<QSpinBox*, Settings::NativeAnalog::NumAnalogs> analog_map_range_spinbox;
|
||||||
|
|
||||||
/// A flag to indicate that the "Map Analog Stick" pop-up has been shown and accepted once.
|
static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons;
|
||||||
bool map_analog_stick_accepted{};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of keys currently registered to hotkeys.
|
* List of keys currently registered to hotkeys.
|
||||||
@ -114,48 +184,10 @@ private:
|
|||||||
*/
|
*/
|
||||||
QList<QKeySequence> hotkey_list;
|
QList<QKeySequence> hotkey_list;
|
||||||
|
|
||||||
/// A flag to indicate if keyboard keys are okay when configuring an input. If this is false,
|
/// A flag to indicate that the "Map Analog Stick" pop-up has been shown and accepted once.
|
||||||
/// keyboard events are ignored.
|
bool map_analog_stick_accepted{};
|
||||||
bool want_keyboard_keys = false;
|
|
||||||
|
|
||||||
|
/// List of physical devices users can map with. If a SDL backed device is selected, then you
|
||||||
|
/// can use this device to get a default mapping.
|
||||||
std::vector<Common::ParamPackage> input_devices;
|
std::vector<Common::ParamPackage> input_devices;
|
||||||
|
|
||||||
/// Generates list of all used keys
|
|
||||||
QList<QKeySequence> GetUsedKeyboardKeys();
|
|
||||||
|
|
||||||
/// Restore all buttons to their default values.
|
|
||||||
void RestoreDefaults();
|
|
||||||
/// Clear all input configuration
|
|
||||||
void ClearAll();
|
|
||||||
|
|
||||||
/// Gets the default controller mapping for this device and auto configures the input to match.
|
|
||||||
void UpdateMappingWithDefaults();
|
|
||||||
|
|
||||||
/// Called when the button was pressed.
|
|
||||||
void HandleClick(QPushButton* button, std::size_t button_id,
|
|
||||||
std::function<void(const Common::ParamPackage&)> new_input_setter,
|
|
||||||
InputCommon::Polling::InputType type);
|
|
||||||
|
|
||||||
/// The key code of the previous state of the key being currently bound.
|
|
||||||
int previous_key_code;
|
|
||||||
|
|
||||||
/// Checks whether a given input can be accepted.
|
|
||||||
bool IsInputAcceptable(const Common::ParamPackage& params) const;
|
|
||||||
|
|
||||||
/// Finish polling and configure input using the input_setter
|
|
||||||
void SetPollingResult(const Common::ParamPackage& params, bool abort);
|
|
||||||
|
|
||||||
/// Handle key press events.
|
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
|
||||||
|
|
||||||
void UpdateInputDevices();
|
|
||||||
void UpdateInputDeviceCombobox();
|
|
||||||
|
|
||||||
/// input profiles
|
|
||||||
void NewProfile();
|
|
||||||
void DeleteProfile();
|
|
||||||
void RenameProfile();
|
|
||||||
|
|
||||||
bool IsProfileNameDuplicate(const QString& name) const;
|
|
||||||
void WarnProposedProfileNameIsDuplicate();
|
|
||||||
};
|
};
|
||||||
|
@ -68,7 +68,14 @@
|
|||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="profile"/>
|
<widget class="QComboBox" name="comboProfiles"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonProfilesSave">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="buttonProfilesNew">
|
<widget class="QPushButton" name="buttonProfilesNew">
|
||||||
@ -77,13 +84,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="buttonProfilesRename">
|
|
||||||
<property name="text">
|
|
||||||
<string>Rename</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="buttonProfilesDelete">
|
<widget class="QPushButton" name="buttonProfilesDelete">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -120,37 +120,23 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent,
|
|||||||
ConfigureMotionTouch::~ConfigureMotionTouch() = default;
|
ConfigureMotionTouch::~ConfigureMotionTouch() = default;
|
||||||
|
|
||||||
void ConfigureMotionTouch::SetConfiguration() {
|
void ConfigureMotionTouch::SetConfiguration() {
|
||||||
const Common::ParamPackage motion_param(Settings::values.current_input_profile.motion_device);
|
const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
|
||||||
const Common::ParamPackage touch_param(Settings::values.current_input_profile.touch_device);
|
|
||||||
const std::string motion_engine = motion_param.Get("engine", "motion_emu");
|
|
||||||
const std::string touch_engine = touch_param.Get("engine", "emu_window");
|
|
||||||
|
|
||||||
ui->motion_provider->setCurrentIndex(
|
|
||||||
ui->motion_provider->findData(QString::fromStdString(motion_engine)));
|
|
||||||
ui->touch_provider->setCurrentIndex(
|
|
||||||
ui->touch_provider->findData(QString::fromStdString(touch_engine)));
|
|
||||||
ui->touch_from_button_checkbox->setChecked(
|
|
||||||
Settings::values.current_input_profile.use_touch_from_button);
|
|
||||||
touch_from_button_maps = Settings::values.touch_from_button_maps;
|
touch_from_button_maps = Settings::values.touch_from_button_maps;
|
||||||
for (const auto& touch_map : touch_from_button_maps) {
|
for (const auto& touch_map : touch_from_button_maps) {
|
||||||
ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name));
|
ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name));
|
||||||
}
|
}
|
||||||
ui->touch_from_button_map->setCurrentIndex(
|
ui->touch_from_button_map->setCurrentIndex(
|
||||||
Settings::values.current_input_profile.touch_from_button_map_index);
|
Settings::values.touch_from_button_map_index.GetValue());
|
||||||
ui->motion_sensitivity->setValue(motion_param.Get("sensitivity", 0.01f));
|
|
||||||
|
|
||||||
guid = motion_param.Get("guid", "0");
|
|
||||||
port = motion_param.Get("port", 0);
|
|
||||||
|
|
||||||
min_x = touch_param.Get("min_x", 100);
|
min_x = touch_param.Get("min_x", 100);
|
||||||
min_y = touch_param.Get("min_y", 50);
|
min_y = touch_param.Get("min_y", 50);
|
||||||
max_x = touch_param.Get("max_x", 1800);
|
max_x = touch_param.Get("max_x", 1800);
|
||||||
max_y = touch_param.Get("max_y", 850);
|
max_y = touch_param.Get("max_y", 850);
|
||||||
|
|
||||||
ui->udp_server->setText(
|
ui->udp_server->setText(QString::fromStdString(Settings::values.udp_input_address.GetValue()));
|
||||||
QString::fromStdString(Settings::values.current_input_profile.udp_input_address));
|
ui->udp_port->setText(QString::number(Settings::values.udp_input_port.GetValue()));
|
||||||
ui->udp_port->setText(QString::number(Settings::values.current_input_profile.udp_input_port));
|
ui->udp_pad_index->setCurrentIndex(Settings::values.udp_pad_index.GetValue());
|
||||||
ui->udp_pad_index->setCurrentIndex(Settings::values.current_input_profile.udp_pad_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureMotionTouch::UpdateUiDisplay() {
|
void ConfigureMotionTouch::UpdateUiDisplay() {
|
||||||
@ -326,19 +312,12 @@ void ConfigureMotionTouch::ApplyConfiguration() {
|
|||||||
touch_param.Set("max_y", max_y);
|
touch_param.Set("max_y", max_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::values.current_input_profile.motion_device = motion_param.Serialize();
|
Settings::values.touch_device = touch_param.Serialize();
|
||||||
Settings::values.current_input_profile.touch_device = touch_param.Serialize();
|
Settings::values.touch_from_button_map_index = ui->touch_from_button_map->currentIndex();
|
||||||
Settings::values.current_input_profile.use_touch_from_button =
|
|
||||||
ui->touch_from_button_checkbox->isChecked();
|
|
||||||
Settings::values.current_input_profile.touch_from_button_map_index =
|
|
||||||
ui->touch_from_button_map->currentIndex();
|
|
||||||
Settings::values.touch_from_button_maps = touch_from_button_maps;
|
Settings::values.touch_from_button_maps = touch_from_button_maps;
|
||||||
Settings::values.current_input_profile.udp_input_address = ui->udp_server->text().toStdString();
|
Settings::values.udp_input_address = ui->udp_server->text().toStdString();
|
||||||
Settings::values.current_input_profile.udp_input_port =
|
Settings::values.udp_input_port = static_cast<u16>(ui->udp_port->text().toInt());
|
||||||
static_cast<u16>(ui->udp_port->text().toInt());
|
Settings::values.udp_pad_index = static_cast<u8>(ui->udp_pad_index->currentIndex());
|
||||||
Settings::values.current_input_profile.udp_pad_index =
|
|
||||||
static_cast<u8>(ui->udp_pad_index->currentIndex());
|
|
||||||
Settings::SaveProfile(Settings::values.current_input_profile_index);
|
|
||||||
input_subsystem->ReloadInputDevices();
|
input_subsystem->ReloadInputDevices();
|
||||||
|
|
||||||
accept();
|
accept();
|
||||||
|
127
src/citra_qt/configuration/input_profiles.cpp
Normal file
127
src/citra_qt/configuration/input_profiles.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "citra_qt/configuration/config.h"
|
||||||
|
#include "citra_qt/configuration/input_profiles.h"
|
||||||
|
#include "common/common_paths.h"
|
||||||
|
#include "common/file_util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool ProfileExistsInFilesystem(std::string_view profile_name) {
|
||||||
|
return FileUtil::Exists(FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "input" +
|
||||||
|
DIR_SEP + fmt::format("{}.ini", profile_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsINI(const std::string& filename) {
|
||||||
|
return filename.ends_with(".ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetNameWithoutExtension(const std::string& filename) {
|
||||||
|
const auto last_dot = filename.find_last_of(".");
|
||||||
|
if (last_dot == std::string::npos) {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
return filename.substr(0, last_dot);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
InputProfiles::InputProfiles() {
|
||||||
|
const auto input_profile_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "input";
|
||||||
|
|
||||||
|
if (!FileUtil::IsDirectory(input_profile_loc)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileUtil::ForeachDirectoryEntry(
|
||||||
|
nullptr, input_profile_loc,
|
||||||
|
[this](u64* num_entries_out, const std::string& directory, const std::string& filename) {
|
||||||
|
const auto name_without_ext = GetNameWithoutExtension(filename);
|
||||||
|
|
||||||
|
if (IsINI(filename) && IsProfileNameValid(name_without_ext)) {
|
||||||
|
map_profiles.insert_or_assign(
|
||||||
|
name_without_ext,
|
||||||
|
std::make_unique<Config>(name_without_ext, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stable_sort(profile_names.begin(), profile_names.end());
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::DeleteProfile(const std::string& profile_name) {
|
||||||
|
if (!ProfileExistsInMap(profile_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ProfileExistsInFilesystem(profile_name) ||
|
||||||
|
FileUtil::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) {
|
||||||
|
if (!ProfileExistsInMap(profile_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ProfileExistsInFilesystem(profile_name)) {
|
||||||
|
map_profiles.erase(profile_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_profiles[profile_name]->ReadControlPlayerValues();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::SaveProfile(const std::string& profile_name) {
|
||||||
|
if (!ProfileExistsInMap(profile_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_profiles[profile_name]->SaveControlPlayerValues();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputProfiles::ProfileExistsInMap(const std::string& profile_name) const {
|
||||||
|
return map_profiles.find(profile_name) != map_profiles.end();
|
||||||
|
}
|
34
src/citra_qt/configuration/input_profiles.h
Normal file
34
src/citra_qt/configuration/input_profiles.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
bool DeleteProfile(const std::string& profile_name);
|
||||||
|
bool LoadProfile(const std::string& profile_name);
|
||||||
|
bool SaveProfile(const std::string& profile_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ProfileExistsInMap(const std::string& profile_name) const;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<Config>> map_profiles;
|
||||||
|
};
|
@ -1966,17 +1966,17 @@ void GMainWindow::OnLoadState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnConfigure() {
|
void GMainWindow::OnConfigure() {
|
||||||
|
const auto old_theme = UISettings::values.theme;
|
||||||
|
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
||||||
|
const auto old_touch_from_button_maps = Settings::values.touch_from_button_maps;
|
||||||
|
|
||||||
game_list->SetDirectoryWatcherEnabled(false);
|
game_list->SetDirectoryWatcherEnabled(false);
|
||||||
Settings::SetConfiguringGlobal(true);
|
Settings::SetConfiguringGlobal(true);
|
||||||
ConfigureDialog configureDialog(this, hotkey_registry, input_subsystem.get(),
|
ConfigureDialog configureDialog(this, hotkey_registry, input_subsystem.get(),
|
||||||
!multiplayer_state->IsHostingPublicRoom());
|
!multiplayer_state->IsHostingPublicRoom());
|
||||||
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
||||||
&GMainWindow::OnLanguageChanged);
|
&GMainWindow::OnLanguageChanged);
|
||||||
auto old_theme = UISettings::values.theme;
|
|
||||||
const int old_input_profile_index = Settings::values.current_input_profile_index;
|
|
||||||
const auto old_input_profiles = Settings::values.input_profiles;
|
|
||||||
const auto old_touch_from_button_maps = Settings::values.touch_from_button_maps;
|
|
||||||
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
|
||||||
auto result = configureDialog.exec();
|
auto result = configureDialog.exec();
|
||||||
game_list->SetDirectoryWatcherEnabled(true);
|
game_list->SetDirectoryWatcherEnabled(true);
|
||||||
if (result == QDialog::Accepted) {
|
if (result == QDialog::Accepted) {
|
||||||
@ -2001,9 +2001,7 @@ void GMainWindow::OnConfigure() {
|
|||||||
UpdateSecondaryWindowVisibility();
|
UpdateSecondaryWindowVisibility();
|
||||||
UpdateBootHomeMenuState();
|
UpdateBootHomeMenuState();
|
||||||
} else {
|
} else {
|
||||||
Settings::values.input_profiles = old_input_profiles;
|
|
||||||
Settings::values.touch_from_button_maps = old_touch_from_button_maps;
|
Settings::values.touch_from_button_maps = old_touch_from_button_maps;
|
||||||
Settings::LoadProfile(old_input_profile_index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ bool CreateDir(const std::string& filename);
|
|||||||
bool CreateFullPath(const std::string& fullPath);
|
bool CreateFullPath(const std::string& fullPath);
|
||||||
|
|
||||||
// Deletes a given filename, return true on success
|
// Deletes a given filename, return true on success
|
||||||
// Doesn't supports deleting a directory
|
// Doesn't support deleting a directory
|
||||||
bool Delete(const std::string& filename);
|
bool Delete(const std::string& filename);
|
||||||
|
|
||||||
// Deletes a directory filename, returns true on success
|
// Deletes a directory filename, returns true on success
|
||||||
|
@ -101,7 +101,6 @@ void Apply() {
|
|||||||
Core::DSP().SetSink(values.output_type.GetValue(), values.output_device.GetValue());
|
Core::DSP().SetSink(values.output_type.GetValue(), values.output_device.GetValue());
|
||||||
Core::DSP().EnableStretching(values.enable_audio_stretching.GetValue());
|
Core::DSP().EnableStretching(values.enable_audio_stretching.GetValue());
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
auto hid = Service::HID::GetModule(system);
|
auto hid = Service::HID::GetModule(system);
|
||||||
if (hid) {
|
if (hid) {
|
||||||
hid->ReloadInputDevices();
|
hid->ReloadInputDevices();
|
||||||
@ -120,8 +119,6 @@ void Apply() {
|
|||||||
if (ir_rst)
|
if (ir_rst)
|
||||||
ir_rst->ReloadInputDevices();
|
ir_rst->ReloadInputDevices();
|
||||||
|
|
||||||
=======
|
|
||||||
>>>>>>> 811fc4f3a (Stash "DONE")
|
|
||||||
auto cam = Service::CAM::GetModule(system);
|
auto cam = Service::CAM::GetModule(system);
|
||||||
if (cam) {
|
if (cam) {
|
||||||
cam->ReloadCameraDevices();
|
cam->ReloadCameraDevices();
|
||||||
@ -255,31 +252,4 @@ void RestoreGlobalState(bool is_powered_on) {
|
|||||||
values.preload_textures.SetGlobal(true);
|
values.preload_textures.SetGlobal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadProfile(int index) {
|
|
||||||
Settings::values.current_input_profile = Settings::values.input_profiles[index];
|
|
||||||
Settings::values.current_input_profile_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveProfile(int index) {
|
|
||||||
Settings::values.input_profiles[index] = Settings::values.current_input_profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateProfile(std::string name) {
|
|
||||||
Settings::InputProfile profile = values.current_input_profile;
|
|
||||||
profile.name = std::move(name);
|
|
||||||
Settings::values.input_profiles.push_back(std::move(profile));
|
|
||||||
Settings::values.current_input_profile_index =
|
|
||||||
static_cast<int>(Settings::values.input_profiles.size()) - 1;
|
|
||||||
Settings::LoadProfile(Settings::values.current_input_profile_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteProfile(int index) {
|
|
||||||
Settings::values.input_profiles.erase(Settings::values.input_profiles.begin() + index);
|
|
||||||
Settings::LoadProfile(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenameCurrentProfile(std::string new_name) {
|
|
||||||
Settings::values.current_input_profile.name = std::move(new_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
@ -113,7 +113,7 @@ constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
|
|||||||
constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
|
constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
|
||||||
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
||||||
|
|
||||||
static const std::array<const char*, NumButtons> mapping = {{
|
constexpr std::array<const char*, NumButtons> mapping = {{
|
||||||
"button_a",
|
"button_a",
|
||||||
"button_b",
|
"button_b",
|
||||||
"button_x",
|
"button_x",
|
||||||
@ -132,13 +132,13 @@ static const std::array<const char*, NumButtons> mapping = {{
|
|||||||
"button_zr",
|
"button_zr",
|
||||||
"button_home",
|
"button_home",
|
||||||
}};
|
}};
|
||||||
|
|
||||||
} // namespace NativeButton
|
} // namespace NativeButton
|
||||||
|
|
||||||
namespace NativeAnalog {
|
namespace NativeAnalog {
|
||||||
enum Values {
|
enum Values {
|
||||||
CirclePad,
|
CirclePad,
|
||||||
CStick,
|
CStick,
|
||||||
|
|
||||||
NumAnalogs,
|
NumAnalogs,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -160,9 +160,24 @@ constexpr int MOTION_HID_BEGIN = MotionLeft;
|
|||||||
constexpr int MOTION_HID_END = NumMotions;
|
constexpr int MOTION_HID_END = NumMotions;
|
||||||
constexpr int NUM_MOTIONS_HID = NumMotions;
|
constexpr int NUM_MOTIONS_HID = NumMotions;
|
||||||
|
|
||||||
extern const std::array<const char*, NumMotions> mapping;
|
constexpr std::array<const char*, NumMotions> mapping = {{
|
||||||
|
"motionleft",
|
||||||
|
"motionright",
|
||||||
|
}};
|
||||||
} // namespace NativeMotion
|
} // namespace NativeMotion
|
||||||
|
|
||||||
|
using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>;
|
||||||
|
using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
|
||||||
|
using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>;
|
||||||
|
|
||||||
|
struct PlayerInput {
|
||||||
|
ButtonsRaw buttons;
|
||||||
|
AnalogsRaw analogs;
|
||||||
|
MotionsRaw motions;
|
||||||
|
|
||||||
|
std::string profile_name;
|
||||||
|
};
|
||||||
|
|
||||||
/** The Setting class is a simple resource manager. It defines a label and default value alongside
|
/** The Setting class is a simple resource manager. It defines a label and default value alongside
|
||||||
* the actual value of the setting for simpler and less-error prone use with frontend
|
* the actual value of the setting for simpler and less-error prone use with frontend
|
||||||
* configurations. Specifying a default value and label is required. A minimum and maximum range can
|
* configurations. Specifying a default value and label is required. A minimum and maximum range can
|
||||||
@ -393,18 +408,36 @@ protected:
|
|||||||
Type custom{}; ///< The custom value of the setting
|
Type custom{}; ///< The custom value of the setting
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputProfile {
|
/**
|
||||||
std::string name;
|
* The InputSetting class allows for getting a reference to either the global or custom members.
|
||||||
std::array<std::string, NativeButton::NumButtons> buttons;
|
* This is required as we cannot easily modify the values of user-defined types within containers
|
||||||
std::array<std::string, NativeAnalog::NumAnalogs> analogs;
|
* using the SetValue() member function found in the Setting class. The primary purpose of this
|
||||||
std::array<std::string, NativeMotion::NumMotions> motions;
|
* class is to store an array of 10 PlayerInput structs for both the global and custom setting and
|
||||||
std::string motion_device;
|
* allows for easily accessing and modifying both settings.
|
||||||
std::string touch_device;
|
*/
|
||||||
bool use_touch_from_button;
|
template <typename Type>
|
||||||
int touch_from_button_map_index;
|
class InputSetting final {
|
||||||
std::string udp_input_address;
|
public:
|
||||||
u16 udp_input_port;
|
InputSetting() = default;
|
||||||
u8 udp_pad_index;
|
explicit InputSetting(Type val) : Setting<Type>(val) {}
|
||||||
|
~InputSetting() = default;
|
||||||
|
void SetGlobal(bool to_global) {
|
||||||
|
use_global = to_global;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool UsingGlobal() const {
|
||||||
|
return use_global;
|
||||||
|
}
|
||||||
|
[[nodiscard]] Type& GetValue(bool need_global = false) {
|
||||||
|
if (use_global || need_global) {
|
||||||
|
return global;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool use_global{true}; ///< The setting's global state
|
||||||
|
Type global{}; ///< The setting
|
||||||
|
Type custom{}; ///< The custom setting value
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TouchFromButtonMap {
|
struct TouchFromButtonMap {
|
||||||
@ -418,11 +451,16 @@ static constexpr s32 REGION_VALUE_AUTO_SELECT = -1;
|
|||||||
|
|
||||||
struct Values {
|
struct Values {
|
||||||
// Controls
|
// Controls
|
||||||
InputProfile current_input_profile; ///< The current input profile
|
InputSetting<PlayerInput> players;
|
||||||
int current_input_profile_index; ///< The current input profile index
|
|
||||||
std::vector<InputProfile> input_profiles; ///< The list of input profiles
|
Setting<std::string> touch_device{"min_x:100,min_y:50,max_x:1800,max_y:850", "touch_device"};
|
||||||
|
Setting<int> touch_from_button_map_index{0, "touch_from_button_map"};
|
||||||
std::vector<TouchFromButtonMap> touch_from_button_maps;
|
std::vector<TouchFromButtonMap> touch_from_button_maps;
|
||||||
|
|
||||||
|
Setting<std::string> udp_input_address{"127.0.0.1", "udp_input_address"};
|
||||||
|
Setting<u16> udp_input_port{26760, "udp_input_port"};
|
||||||
|
Setting<u8> udp_pad_index{0, "udp_pad_index"};
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
Setting<bool> use_cpu_jit{true, "use_cpu_jit"};
|
Setting<bool> use_cpu_jit{true, "use_cpu_jit"};
|
||||||
SwitchableSetting<s32, true> cpu_clock_percentage{100, 5, 400, "cpu_clock_percentage"};
|
SwitchableSetting<s32, true> cpu_clock_percentage{100, 5, 400, "cpu_clock_percentage"};
|
||||||
@ -541,11 +579,4 @@ void LogSettings();
|
|||||||
// Restore the global state of all applicable settings in the Values struct
|
// Restore the global state of all applicable settings in the Values struct
|
||||||
void RestoreGlobalState(bool is_powered_on);
|
void RestoreGlobalState(bool is_powered_on);
|
||||||
|
|
||||||
// Input profiles
|
|
||||||
void LoadProfile(int index);
|
|
||||||
void SaveProfile(int index);
|
|
||||||
void CreateProfile(std::string name);
|
|
||||||
void DeleteProfile(int index);
|
|
||||||
void RenameCurrentProfile(std::string new_name);
|
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
@ -280,7 +280,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
|||||||
auto n3ds_mode = app_loader->LoadKernelN3dsMode();
|
auto n3ds_mode = app_loader->LoadKernelN3dsMode();
|
||||||
ASSERT(n3ds_mode.first);
|
ASSERT(n3ds_mode.first);
|
||||||
u32 num_cores = 2;
|
u32 num_cores = 2;
|
||||||
if (Settings::values.is_new_3ds) {
|
if (Settings::values.is_new_3ds.GetValue()) {
|
||||||
num_cores = 4;
|
num_cores = 4;
|
||||||
}
|
}
|
||||||
ResultStatus init_result{
|
ResultStatus init_result{
|
||||||
|
@ -12,7 +12,7 @@ EmulatedConsole::~EmulatedConsole() = default;
|
|||||||
|
|
||||||
void EmulatedConsole::ReloadFromSettings() {
|
void EmulatedConsole::ReloadFromSettings() {
|
||||||
// Using first motion device from player 1. No need to assign any unique config at the moment
|
// Using first motion device from player 1. No need to assign any unique config at the moment
|
||||||
const auto& player = Settings::values.current_input_profile;
|
const auto& player = Settings::values.players.GetValue();
|
||||||
motion_params = Common::ParamPackage(player.motions[0]);
|
motion_params = Common::ParamPackage(player.motions[0]);
|
||||||
|
|
||||||
ReloadInput();
|
ReloadInput();
|
||||||
@ -42,7 +42,7 @@ void EmulatedConsole::SetTouchParams() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto button_index =
|
const auto button_index =
|
||||||
static_cast<u64>(Settings::values.current_input_profile.touch_from_button_map_index);
|
static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
|
||||||
const auto& touch_buttons = Settings::values.touch_from_button_maps[button_index].buttons;
|
const auto& touch_buttons = Settings::values.touch_from_button_maps[button_index].buttons;
|
||||||
|
|
||||||
// Map the rest of the fingers from touch from button configuration
|
// Map the rest of the fingers from touch from button configuration
|
||||||
|
@ -168,7 +168,7 @@ void EmulatedController::ReloadInput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::ReloadFromSettings() {
|
void EmulatedController::ReloadFromSettings() {
|
||||||
const auto& player = Settings::values.current_input_profile;
|
const auto& player = Settings::values.players.GetValue();
|
||||||
for (std::size_t i = 0; i < player.buttons.size(); i++) {
|
for (std::size_t i = 0; i < player.buttons.size(); i++) {
|
||||||
button_params[i] = Common::ParamPackage(player.buttons[i]);
|
button_params[i] = Common::ParamPackage(player.buttons[i]);
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ void EmulatedController::ReloadFromSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::SaveCurrentConfig() {
|
void EmulatedController::SaveCurrentConfig() {
|
||||||
auto& player = Settings::values.current_input_profile;
|
auto& player = Settings::values.players.GetValue();
|
||||||
for (std::size_t index = 0; index < player.buttons.size(); ++index) {
|
for (std::size_t index = 0; index < player.buttons.size(); ++index) {
|
||||||
player.buttons[index] = button_params[index].Serialize();
|
player.buttons[index] = button_params[index].Serialize();
|
||||||
}
|
}
|
||||||
|
@ -151,10 +151,10 @@ UDPClient::ClientConnection::~ClientConnection() = default;
|
|||||||
void UDPClient::ReloadSockets() {
|
void UDPClient::ReloadSockets() {
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
const std::string& host = Settings::values.current_input_profile.udp_input_address;
|
const std::string& host = Settings::values.udp_input_address.GetValue();
|
||||||
const u16 udp_input_port = Settings::values.current_input_profile.udp_input_port;
|
const u16 udp_input_port = Settings::values.udp_input_port.GetValue();
|
||||||
// TODO: Hook it up again
|
// TODO: Hook it up again!!!!!!!!!
|
||||||
const u8 pad_index = Settings::values.current_input_profile.udp_pad_index;
|
const u8 pad_index = Settings::values.udp_pad_index.GetValue();
|
||||||
|
|
||||||
const std::size_t client_number = GetClientNumber(host, udp_input_port);
|
const std::size_t client_number = GetClientNumber(host, udp_input_port);
|
||||||
if (client_number != MAX_UDP_CLIENTS) {
|
if (client_number != MAX_UDP_CLIENTS) {
|
||||||
|
Reference in New Issue
Block a user