mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
764 lines
24 KiB
C++
764 lines
24 KiB
C++
#include "emu_settings.h"
|
|
#include "config_adapter.h"
|
|
|
|
#include <QMessageBox>
|
|
#include <QLineEdit>
|
|
|
|
#include "Emu/System.h"
|
|
#include "Emu/system_config.h"
|
|
|
|
#include "util/yaml.hpp"
|
|
|
|
LOG_CHANNEL(cfg_log, "CFG");
|
|
|
|
extern std::string g_cfg_defaults; //! Default settings grabbed from Utilities/Config.h
|
|
|
|
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
|
|
inline std::string sstr(const QVariant& _in) { return sstr(_in.toString()); }
|
|
|
|
// Emit sorted YAML
|
|
namespace
|
|
{
|
|
static NEVER_INLINE void emitData(YAML::Emitter& out, const YAML::Node& node)
|
|
{
|
|
// TODO
|
|
out << node;
|
|
}
|
|
|
|
// Incrementally load YAML
|
|
static NEVER_INLINE void operator +=(YAML::Node& left, const YAML::Node& node)
|
|
{
|
|
if (node && !node.IsNull())
|
|
{
|
|
if (node.IsMap())
|
|
{
|
|
for (const auto& pair : node)
|
|
{
|
|
if (pair.first.IsScalar())
|
|
{
|
|
auto&& lhs = left[pair.first.Scalar()];
|
|
lhs += pair.second;
|
|
}
|
|
else
|
|
{
|
|
// Exotic case (TODO: probably doesn't work)
|
|
auto&& lhs = left[YAML::Clone(pair.first)];
|
|
lhs += pair.second;
|
|
}
|
|
}
|
|
}
|
|
else if (node.IsScalar() || node.IsSequence())
|
|
{
|
|
// Scalars and sequences are replaced completely, but this may change in future.
|
|
// This logic may be overwritten by custom demands of every specific cfg:: node.
|
|
left = node;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
emu_settings::emu_settings()
|
|
: QObject()
|
|
, m_render_creator(new render_creator(this))
|
|
{
|
|
}
|
|
|
|
emu_settings::~emu_settings()
|
|
{
|
|
}
|
|
|
|
void emu_settings::LoadSettings(const std::string& title_id)
|
|
{
|
|
m_title_id = title_id;
|
|
|
|
// Create config path if necessary
|
|
fs::create_path(title_id.empty() ? fs::get_config_dir() : Emulator::GetCustomConfigDir());
|
|
|
|
// Load default config
|
|
auto [default_config, default_error] = yaml_load(g_cfg_defaults);
|
|
|
|
if (default_error.empty())
|
|
{
|
|
m_defaultSettings = default_config;
|
|
m_currentSettings = YAML::Clone(default_config);
|
|
}
|
|
else
|
|
{
|
|
cfg_log.fatal("Failed to load default config:\n%s", default_error);
|
|
QMessageBox::critical(nullptr, tr("Config Error"), tr("Failed to load default config:\n%0")
|
|
.arg(QString::fromStdString(default_error)), QMessageBox::Ok);
|
|
}
|
|
|
|
// Add global config
|
|
const std::string global_config_path = fs::get_config_dir() + "config.yml";
|
|
fs::file config(global_config_path, fs::read + fs::write + fs::create);
|
|
auto [global_config, global_error] = yaml_load(config.to_string());
|
|
config.close();
|
|
|
|
if (global_error.empty())
|
|
{
|
|
m_currentSettings += global_config;
|
|
}
|
|
else
|
|
{
|
|
cfg_log.fatal("Failed to load global config %s:\n%s", global_config_path, global_error);
|
|
QMessageBox::critical(nullptr, tr("Config Error"), tr("Failed to load global config:\nFile: %0\nError: %1")
|
|
.arg(QString::fromStdString(global_config_path)).arg(QString::fromStdString(global_error)), QMessageBox::Ok);
|
|
}
|
|
|
|
// Add game config
|
|
if (!title_id.empty())
|
|
{
|
|
const std::string config_path_new = Emulator::GetCustomConfigPath(m_title_id);
|
|
const std::string config_path_old = Emulator::GetCustomConfigPath(m_title_id, true);
|
|
std::string custom_config_path;
|
|
|
|
if (fs::is_file(config_path_new))
|
|
{
|
|
custom_config_path = config_path_new;
|
|
}
|
|
else if (fs::is_file(config_path_old))
|
|
{
|
|
custom_config_path = config_path_old;
|
|
}
|
|
|
|
if (!custom_config_path.empty())
|
|
{
|
|
if (config = fs::file(custom_config_path, fs::read + fs::write))
|
|
{
|
|
auto [custom_config, custom_error] = yaml_load(config.to_string());
|
|
config.close();
|
|
|
|
if (custom_error.empty())
|
|
{
|
|
m_currentSettings += custom_config;
|
|
}
|
|
else
|
|
{
|
|
cfg_log.fatal("Failed to load custom config %s:\n%s", custom_config_path, custom_error);
|
|
QMessageBox::critical(nullptr, tr("Config Error"), tr("Failed to load custom config:\nFile: %0\nError: %1")
|
|
.arg(QString::fromStdString(custom_config_path)).arg(QString::fromStdString(custom_error)), QMessageBox::Ok);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void emu_settings::SaveSettings()
|
|
{
|
|
YAML::Emitter out;
|
|
emitData(out, m_currentSettings);
|
|
|
|
std::string config_name;
|
|
|
|
if (m_title_id.empty())
|
|
{
|
|
config_name = fs::get_config_dir() + "/config.yml";
|
|
}
|
|
else
|
|
{
|
|
config_name = Emulator::GetCustomConfigPath(m_title_id);
|
|
}
|
|
|
|
// Save config atomically
|
|
fs::file(config_name + ".tmp", fs::rewrite).write(out.c_str(), out.size());
|
|
fs::rename(config_name + ".tmp", config_name, true);
|
|
|
|
// Check if the running config/title is the same as the edited config/title.
|
|
if (config_name == g_cfg.name || m_title_id == Emu.GetTitleID())
|
|
{
|
|
// Update current config
|
|
if (!g_cfg.from_string({out.c_str(), out.size()}, !Emu.IsStopped()))
|
|
{
|
|
cfg_log.fatal("Failed to update configuration");
|
|
}
|
|
else if (!Emu.IsStopped()) // Don't spam the log while emulation is stopped. The config will be logged on boot anyway.
|
|
{
|
|
cfg_log.notice("Updated configuration:\n%s\n", g_cfg.to_string());
|
|
}
|
|
}
|
|
}
|
|
|
|
void emu_settings::EnhanceComboBox(QComboBox* combobox, emu_settings_type type, bool is_ranged, bool use_max, int max, bool sorted)
|
|
{
|
|
if (!combobox)
|
|
{
|
|
cfg_log.fatal("EnhanceComboBox '%s' was used with an invalid object", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
if (is_ranged)
|
|
{
|
|
if (sorted)
|
|
{
|
|
cfg_log.warning("EnhanceCombobox '%s': ignoring sorting request on ranged combo box", cfg_adapter::get_setting_name(type));
|
|
}
|
|
|
|
const QStringList range = GetSettingOptions(type);
|
|
|
|
const int max_item = use_max ? max : range.last().toInt();
|
|
|
|
for (int i = range.first().toInt(); i <= max_item; i++)
|
|
{
|
|
combobox->addItem(QString::number(i), i);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const QStringList settings = GetSettingOptions(type);
|
|
|
|
for (int i = 0; i < settings.count(); i++)
|
|
{
|
|
const QString localized_setting = GetLocalizedSetting(settings[i], type, combobox->count());
|
|
combobox->addItem(localized_setting, QVariant({settings[i], i}));
|
|
}
|
|
|
|
if (sorted)
|
|
{
|
|
combobox->model()->sort(0, Qt::AscendingOrder);
|
|
}
|
|
}
|
|
|
|
const std::string selected = GetSetting(type);
|
|
const QString selected_q = qstr(selected);
|
|
int index = -1;
|
|
|
|
if (is_ranged)
|
|
{
|
|
index = combobox->findData(selected_q);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < combobox->count(); i++)
|
|
{
|
|
const QVariantList var_list = combobox->itemData(i).toList();
|
|
ASSERT(var_list.size() == 2 && var_list[0].canConvert<QString>());
|
|
|
|
if (selected_q == var_list[0].toString())
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (index == -1)
|
|
{
|
|
const std::string def = GetSettingDefault(type);
|
|
cfg_log.fatal("EnhanceComboBox '%s' tried to set an invalid value: %s. Setting to default: %s", cfg_adapter::get_setting_name(type), selected, def);
|
|
combobox->setCurrentIndex(combobox->findData(qstr(def)));
|
|
m_broken_types.insert(type);
|
|
}
|
|
else
|
|
{
|
|
combobox->setCurrentIndex(index);
|
|
}
|
|
|
|
connect(combobox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=, this](int index)
|
|
{
|
|
if (is_ranged)
|
|
{
|
|
SetSetting(type, sstr(combobox->itemData(index)));
|
|
}
|
|
else
|
|
{
|
|
const QVariantList var_list = combobox->itemData(index).toList();
|
|
ASSERT(var_list.size() == 2 && var_list[0].canConvert<QString>());
|
|
SetSetting(type, sstr(var_list[0]));
|
|
}
|
|
});
|
|
}
|
|
|
|
void emu_settings::EnhanceCheckBox(QCheckBox* checkbox, emu_settings_type type)
|
|
{
|
|
if (!checkbox)
|
|
{
|
|
cfg_log.fatal("EnhanceCheckBox '%s' was used with an invalid object", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
std::string def = GetSettingDefault(type);
|
|
std::transform(def.begin(), def.end(), def.begin(), ::tolower);
|
|
|
|
if (def != "true" && def != "false")
|
|
{
|
|
cfg_log.fatal("EnhanceCheckBox '%s' was used with an invalid emu_settings_type", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
std::string selected = GetSetting(type);
|
|
std::transform(selected.begin(), selected.end(), selected.begin(), ::tolower);
|
|
|
|
if (selected == "true")
|
|
{
|
|
checkbox->setChecked(true);
|
|
}
|
|
else if (selected != "false")
|
|
{
|
|
cfg_log.fatal("EnhanceCheckBox '%s' tried to set an invalid value: %s. Setting to default: %s", cfg_adapter::get_setting_name(type), selected, def);
|
|
checkbox->setChecked(def == "true");
|
|
m_broken_types.insert(type);
|
|
}
|
|
|
|
connect(checkbox, &QCheckBox::stateChanged, [type, this](int val)
|
|
{
|
|
const std::string str = val != 0 ? "true" : "false";
|
|
SetSetting(type, str);
|
|
});
|
|
}
|
|
|
|
void emu_settings::EnhanceSlider(QSlider* slider, emu_settings_type type)
|
|
{
|
|
if (!slider)
|
|
{
|
|
cfg_log.fatal("EnhanceSlider '%s' was used with an invalid object", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const QStringList range = GetSettingOptions(type);
|
|
bool ok_def, ok_sel, ok_min, ok_max;
|
|
|
|
const int def = qstr(GetSettingDefault(type)).toInt(&ok_def);
|
|
const int min = range.first().toInt(&ok_min);
|
|
const int max = range.last().toInt(&ok_max);
|
|
|
|
if (!ok_def || !ok_min || !ok_max)
|
|
{
|
|
cfg_log.fatal("EnhanceSlider '%s' was used with an invalid emu_settings_type", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const QString selected = qstr(GetSetting(type));
|
|
int val = selected.toInt(&ok_sel);
|
|
|
|
if (!ok_sel || val < min || val > max)
|
|
{
|
|
cfg_log.fatal("EnhanceSlider '%s' tried to set an invalid value: %d. Setting to default: %d. Allowed range: [%d, %d]", cfg_adapter::get_setting_name(type), val, def, min, max);
|
|
val = def;
|
|
m_broken_types.insert(type);
|
|
}
|
|
|
|
slider->setRange(min, max);
|
|
slider->setValue(val);
|
|
|
|
connect(slider, &QSlider::valueChanged, [type, this](int value)
|
|
{
|
|
SetSetting(type, sstr(value));
|
|
});
|
|
}
|
|
|
|
void emu_settings::EnhanceSpinBox(QSpinBox* spinbox, emu_settings_type type, const QString& prefix, const QString& suffix)
|
|
{
|
|
if (!spinbox)
|
|
{
|
|
cfg_log.fatal("EnhanceSpinBox '%s' was used with an invalid object", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const QStringList range = GetSettingOptions(type);
|
|
bool ok_def, ok_sel, ok_min, ok_max;
|
|
|
|
const int def = qstr(GetSettingDefault(type)).toInt(&ok_def);
|
|
const int min = range.first().toInt(&ok_min);
|
|
const int max = range.last().toInt(&ok_max);
|
|
|
|
if (!ok_def || !ok_min || !ok_max)
|
|
{
|
|
cfg_log.fatal("EnhanceSpinBox '%s' was used with an invalid type", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const std::string selected = GetSetting(type);
|
|
int val = qstr(selected).toInt(&ok_sel);
|
|
|
|
if (!ok_sel || val < min || val > max)
|
|
{
|
|
cfg_log.fatal("EnhanceSpinBox '%s' tried to set an invalid value: %d. Setting to default: %d. Allowed range: [%d, %d]", cfg_adapter::get_setting_name(type), selected, def, min, max);
|
|
val = def;
|
|
m_broken_types.insert(type);
|
|
}
|
|
|
|
spinbox->setPrefix(prefix);
|
|
spinbox->setSuffix(suffix);
|
|
spinbox->setRange(min, max);
|
|
spinbox->setValue(val);
|
|
|
|
connect(spinbox, &QSpinBox::textChanged, [=, this](const QString&/* text*/)
|
|
{
|
|
SetSetting(type, sstr(spinbox->cleanText()));
|
|
});
|
|
}
|
|
|
|
void emu_settings::EnhanceDoubleSpinBox(QDoubleSpinBox* spinbox, emu_settings_type type, const QString& prefix, const QString& suffix)
|
|
{
|
|
if (!spinbox)
|
|
{
|
|
cfg_log.fatal("EnhanceDoubleSpinBox '%s' was used with an invalid object", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const QStringList range = GetSettingOptions(type);
|
|
bool ok_def, ok_sel, ok_min, ok_max;
|
|
|
|
const double def = qstr(GetSettingDefault(type)).toDouble(&ok_def);
|
|
const double min = range.first().toDouble(&ok_min);
|
|
const double max = range.last().toDouble(&ok_max);
|
|
|
|
if (!ok_def || !ok_min || !ok_max)
|
|
{
|
|
cfg_log.fatal("EnhanceDoubleSpinBox '%s' was used with an invalid type", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const std::string selected = GetSetting(type);
|
|
double val = qstr(selected).toDouble(&ok_sel);
|
|
|
|
if (!ok_sel || val < min || val > max)
|
|
{
|
|
cfg_log.fatal("EnhanceDoubleSpinBox '%s' tried to set an invalid value: %f. Setting to default: %f. Allowed range: [%f, %f]", cfg_adapter::get_setting_name(type), val, def, min, max);
|
|
val = def;
|
|
m_broken_types.insert(type);
|
|
}
|
|
|
|
spinbox->setPrefix(prefix);
|
|
spinbox->setSuffix(suffix);
|
|
spinbox->setRange(min, max);
|
|
spinbox->setValue(val);
|
|
|
|
connect(spinbox, &QDoubleSpinBox::textChanged, [=, this](const QString&/* text*/)
|
|
{
|
|
SetSetting(type, sstr(spinbox->cleanText()));
|
|
});
|
|
}
|
|
|
|
void emu_settings::EnhanceLineEdit(QLineEdit* edit, emu_settings_type type)
|
|
{
|
|
if (!edit)
|
|
{
|
|
cfg_log.fatal("EnhanceEdit '%s' was used with an invalid object", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const std::string set_text = GetSetting(type);
|
|
edit->setText(qstr(set_text));
|
|
|
|
connect(edit, &QLineEdit::textChanged, [type, this](const QString &text)
|
|
{
|
|
SetSetting(type, sstr(text));
|
|
});
|
|
}
|
|
|
|
void emu_settings::EnhanceRadioButton(QButtonGroup* button_group, emu_settings_type type)
|
|
{
|
|
if (!button_group)
|
|
{
|
|
cfg_log.fatal("EnhanceRadioButton '%s' was used with an invalid object", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
const QString selected = qstr(GetSetting(type));
|
|
const QStringList options = GetSettingOptions(type);
|
|
|
|
if (button_group->buttons().count() < options.size())
|
|
{
|
|
cfg_log.fatal("EnhanceRadioButton '%s': wrong button count", cfg_adapter::get_setting_name(type));
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < options.count(); i++)
|
|
{
|
|
const QString localized_setting = GetLocalizedSetting(options[i], type, i);
|
|
|
|
button_group->button(i)->setText(localized_setting);
|
|
|
|
if (options[i] == selected)
|
|
{
|
|
button_group->button(i)->setChecked(true);
|
|
}
|
|
|
|
connect(button_group->button(i), &QAbstractButton::clicked, [=, this]()
|
|
{
|
|
SetSetting(type, sstr(options[i]));
|
|
});
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> emu_settings::GetLoadedLibraries()
|
|
{
|
|
return m_currentSettings["Core"]["Load libraries"].as<std::vector<std::string>, std::initializer_list<std::string>>({});
|
|
}
|
|
|
|
void emu_settings::SaveSelectedLibraries(const std::vector<std::string>& libs)
|
|
{
|
|
m_currentSettings["Core"]["Load libraries"] = libs;
|
|
}
|
|
|
|
QStringList emu_settings::GetSettingOptions(emu_settings_type type) const
|
|
{
|
|
return cfg_adapter::get_options(const_cast<cfg_location&&>(settings_location[type]));
|
|
}
|
|
|
|
std::string emu_settings::GetSettingDefault(emu_settings_type type) const
|
|
{
|
|
if (auto node = cfg_adapter::get_node(m_defaultSettings, settings_location[type]); node && node.IsScalar())
|
|
{
|
|
return node.Scalar();
|
|
}
|
|
|
|
cfg_log.fatal("GetSettingDefault(type=%d) could not retrieve the requested node", static_cast<int>(type));
|
|
return "";
|
|
}
|
|
|
|
std::string emu_settings::GetSetting(emu_settings_type type) const
|
|
{
|
|
if (auto node = cfg_adapter::get_node(m_currentSettings, settings_location[type]); node && node.IsScalar())
|
|
{
|
|
return node.Scalar();
|
|
}
|
|
|
|
cfg_log.fatal("GetSetting(type=%d) could not retrieve the requested node", static_cast<int>(type));
|
|
return "";
|
|
}
|
|
|
|
void emu_settings::SetSetting(emu_settings_type type, const std::string& val)
|
|
{
|
|
cfg_adapter::get_node(m_currentSettings, settings_location[type]) = val;
|
|
}
|
|
|
|
void emu_settings::OpenCorrectionDialog(QWidget* parent)
|
|
{
|
|
if (!m_broken_types.empty() && QMessageBox::question(parent, tr("Fix invalid settings?"),
|
|
tr(
|
|
"Your config file contained one or more unrecognized values for settings.\n"
|
|
"Their default value will be used until they are corrected.\n"
|
|
"Consider that a correction might render them invalid for other versions of RPCS3.\n"
|
|
"\n"
|
|
"Do you wish to let the program correct them for you?\n"
|
|
"This change will only be final when you save the config."
|
|
),
|
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
|
|
{
|
|
for (const auto& type : m_broken_types)
|
|
{
|
|
const std::string def = GetSettingDefault(type);
|
|
const std::string old = GetSetting(type);
|
|
SetSetting(type, def);
|
|
cfg_log.success("The config entry '%s' was corrected from '%s' to '%s'", cfg_adapter::get_setting_name(type), old, def);
|
|
}
|
|
|
|
m_broken_types.clear();
|
|
cfg_log.success("You need to save the settings in order to make these changes permanent!");
|
|
}
|
|
}
|
|
|
|
QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_type type, int index) const
|
|
{
|
|
switch (type)
|
|
{
|
|
case emu_settings_type::SPUBlockSize:
|
|
switch (static_cast<spu_block_size_type>(index))
|
|
{
|
|
case spu_block_size_type::safe: return tr("Safe", "SPU block size");
|
|
case spu_block_size_type::mega: return tr("Mega", "SPU block size");
|
|
case spu_block_size_type::giga: return tr("Giga", "SPU block size");
|
|
}
|
|
break;
|
|
case emu_settings_type::EnableTSX:
|
|
switch (static_cast<tsx_usage>(index))
|
|
{
|
|
case tsx_usage::disabled: return tr("Disabled", "Enable TSX");
|
|
case tsx_usage::enabled: return tr("Enabled", "Enable TSX");
|
|
case tsx_usage::forced: return tr("Forced", "Enable TSX");
|
|
}
|
|
break;
|
|
case emu_settings_type::Renderer:
|
|
switch (static_cast<video_renderer>(index))
|
|
{
|
|
case video_renderer::null: return tr("Disable Video Output", "Video renderer");
|
|
case video_renderer::opengl: return tr("OpenGL", "Video renderer");
|
|
case video_renderer::vulkan: return tr("Vulkan", "Video renderer");
|
|
}
|
|
break;
|
|
case emu_settings_type::ShaderMode:
|
|
switch (static_cast<shader_mode>(index))
|
|
{
|
|
case shader_mode::recompiler: return tr("Legacy (single threaded)", "Shader Mode");
|
|
case shader_mode::async_recompiler: return tr("Async (multi threaded)", "Shader Mode");
|
|
case shader_mode::async_with_interpreter: return tr("Async with Shader Interpreter", "Shader Mode");
|
|
case shader_mode::interpreter_only: return tr("Shader Interpreter only", "Shader Mode");
|
|
}
|
|
break;
|
|
case emu_settings_type::FrameLimit:
|
|
switch (static_cast<frame_limit_type>(index))
|
|
{
|
|
case frame_limit_type::none: return tr("Off", "Frame limit");
|
|
case frame_limit_type::_59_94: return tr("59.94", "Frame limit");
|
|
case frame_limit_type::_50: return tr("50", "Frame limit");
|
|
case frame_limit_type::_60: return tr("60", "Frame limit");
|
|
case frame_limit_type::_30: return tr("30", "Frame limit");
|
|
case frame_limit_type::_auto: return tr("Auto", "Frame limit");
|
|
}
|
|
break;
|
|
case emu_settings_type::MSAA:
|
|
switch (static_cast<msaa_level>(index))
|
|
{
|
|
case msaa_level::none: return tr("Disabled", "MSAA");
|
|
case msaa_level::_auto: return tr("Auto", "MSAA");
|
|
}
|
|
break;
|
|
case emu_settings_type::AudioRenderer:
|
|
switch (static_cast<audio_renderer>(index))
|
|
{
|
|
case audio_renderer::null: return tr("Disable Audio Output", "Audio renderer");
|
|
#ifdef _WIN32
|
|
case audio_renderer::xaudio: return tr("XAudio2", "Audio renderer");
|
|
#endif
|
|
#ifdef HAVE_ALSA
|
|
case audio_renderer::alsa: return tr("ALSA", "Audio renderer");
|
|
#endif
|
|
#ifdef HAVE_PULSE
|
|
case audio_renderer::pulse: return tr("PulseAudio", "Audio renderer");
|
|
#endif
|
|
case audio_renderer::openal: return tr("OpenAL", "Audio renderer");
|
|
#ifdef HAVE_FAUDIO
|
|
case audio_renderer::faudio: return tr("FAudio", "Audio renderer");
|
|
#endif
|
|
}
|
|
break;
|
|
case emu_settings_type::MicrophoneType:
|
|
switch (static_cast<microphone_handler>(index))
|
|
{
|
|
case microphone_handler::null: return tr("Disabled", "Microphone handler");
|
|
case microphone_handler::standard: return tr("Standard", "Microphone handler");
|
|
case microphone_handler::singstar: return tr("SingStar", "Microphone handler");
|
|
case microphone_handler::real_singstar: return tr("Real SingStar", "Microphone handler");
|
|
case microphone_handler::rocksmith: return tr("Rocksmith", "Microphone handler");
|
|
}
|
|
break;
|
|
case emu_settings_type::KeyboardHandler:
|
|
switch (static_cast<keyboard_handler>(index))
|
|
{
|
|
case keyboard_handler::null: return tr("Null", "Keyboard handler");
|
|
case keyboard_handler::basic: return tr("Basic", "Keyboard handler");
|
|
}
|
|
break;
|
|
case emu_settings_type::MouseHandler:
|
|
switch (static_cast<mouse_handler>(index))
|
|
{
|
|
case mouse_handler::null: return tr("Null", "Mouse handler");
|
|
case mouse_handler::basic: return tr("Basic", "Mouse handler");
|
|
}
|
|
break;
|
|
case emu_settings_type::CameraType:
|
|
switch (static_cast<fake_camera_type>(index))
|
|
{
|
|
case fake_camera_type::unknown: return tr("Unknown", "Camera type");
|
|
case fake_camera_type::eyetoy: return tr("EyeToy", "Camera type");
|
|
case fake_camera_type::eyetoy2: return tr("PS Eye", "Camera type");
|
|
case fake_camera_type::uvc1_1: return tr("UVC 1.1", "Camera type");
|
|
}
|
|
break;
|
|
case emu_settings_type::Camera:
|
|
switch (static_cast<camera_handler>(index))
|
|
{
|
|
case camera_handler::null: return tr("Null", "Camera handler");
|
|
case camera_handler::fake: return tr("Fake", "Camera handler");
|
|
}
|
|
break;
|
|
case emu_settings_type::Move:
|
|
switch (static_cast<move_handler>(index))
|
|
{
|
|
case move_handler::null: return tr("Null", "Move handler");
|
|
case move_handler::fake: return tr("Fake", "Move handler");
|
|
case move_handler::mouse: return tr("Mouse", "Move handler");
|
|
}
|
|
break;
|
|
case emu_settings_type::InternetStatus:
|
|
switch (static_cast<np_internet_status>(index))
|
|
{
|
|
case np_internet_status::disabled: return tr("Disconnected", "Internet Status");
|
|
case np_internet_status::enabled: return tr("Connected", "Internet Status");
|
|
}
|
|
break;
|
|
case emu_settings_type::PSNStatus:
|
|
switch (static_cast<np_psn_status>(index))
|
|
{
|
|
case np_psn_status::disabled: return tr("Disconnected", "PSN Status");
|
|
case np_psn_status::fake: return tr("Simulated", "PSN Status");
|
|
}
|
|
break;
|
|
case emu_settings_type::SleepTimersAccuracy:
|
|
switch (static_cast<sleep_timers_accuracy_level>(index))
|
|
{
|
|
case sleep_timers_accuracy_level::_as_host: return tr("As Host", "Sleep timers accuracy");
|
|
case sleep_timers_accuracy_level::_usleep: return tr("Usleep Only", "Sleep timers accuracy");
|
|
case sleep_timers_accuracy_level::_all_timers: return tr("All Timers", "Sleep timers accuracy");
|
|
}
|
|
break;
|
|
case emu_settings_type::PerfOverlayDetailLevel:
|
|
switch (static_cast<detail_level>(index))
|
|
{
|
|
case detail_level::minimal: return tr("Minimal", "Detail Level");
|
|
case detail_level::low: return tr("Low", "Detail Level");
|
|
case detail_level::medium: return tr("Medium", "Detail Level");
|
|
case detail_level::high: return tr("High", "Detail Level");
|
|
}
|
|
break;
|
|
case emu_settings_type::PerfOverlayPosition:
|
|
switch (static_cast<screen_quadrant>(index))
|
|
{
|
|
case screen_quadrant::top_left: return tr("Top Left", "Performance overlay position");
|
|
case screen_quadrant::top_right: return tr("Top Right", "Performance overlay position");
|
|
case screen_quadrant::bottom_left: return tr("Bottom Left", "Performance overlay position");
|
|
case screen_quadrant::bottom_right: return tr("Bottom Right", "Performance overlay position");
|
|
}
|
|
break;
|
|
case emu_settings_type::LibLoadOptions:
|
|
switch (static_cast<lib_loading_type>(index))
|
|
{
|
|
case lib_loading_type::manual: return tr("Manually load selected libraries", "Libraries");
|
|
case lib_loading_type::hybrid: return tr("Load automatic and manual selection", "Libraries");
|
|
case lib_loading_type::liblv2only: return tr("Load liblv2.sprx only", "Libraries");
|
|
case lib_loading_type::liblv2both: return tr("Load liblv2.sprx and manual selection", "Libraries");
|
|
case lib_loading_type::liblv2list: return tr("Load liblv2.sprx and strict selection", "Libraries");
|
|
}
|
|
break;
|
|
case emu_settings_type::PPUDecoder:
|
|
switch (static_cast<ppu_decoder_type>(index))
|
|
{
|
|
case ppu_decoder_type::precise: return tr("Interpreter (precise)", "PPU decoder");
|
|
case ppu_decoder_type::fast: return tr("Interpreter (fast)", "PPU decoder");
|
|
case ppu_decoder_type::llvm: return tr("Recompiler (LLVM)", "PPU decoder");
|
|
}
|
|
break;
|
|
case emu_settings_type::SPUDecoder:
|
|
switch (static_cast<spu_decoder_type>(index))
|
|
{
|
|
case spu_decoder_type::precise: return tr("Interpreter (precise)", "SPU decoder");
|
|
case spu_decoder_type::fast: return tr("Interpreter (fast)", "SPU decoder");
|
|
case spu_decoder_type::asmjit: return tr("Recompiler (ASMJIT)", "SPU decoder");
|
|
case spu_decoder_type::llvm: return tr("Recompiler (LLVM)", "SPU decoder");
|
|
}
|
|
break;
|
|
case emu_settings_type::EnterButtonAssignment:
|
|
switch (static_cast<enter_button_assign>(index))
|
|
{
|
|
case enter_button_assign::circle: return tr("Enter with circle", "Enter button assignment");
|
|
case enter_button_assign::cross: return tr("Enter with cross", "Enter button assignment");
|
|
}
|
|
break;
|
|
case emu_settings_type::AudioChannels:
|
|
switch (static_cast<audio_downmix>(index))
|
|
{
|
|
case audio_downmix::no_downmix: return tr("Surround 7.1", "Audio downmix");
|
|
case audio_downmix::downmix_to_stereo: return tr("Downmix to Stereo", "Audio downmix");
|
|
case audio_downmix::downmix_to_5_1: return tr("Downmix to 5.1", "Audio downmix");
|
|
case audio_downmix::use_application_settings: return tr("Use application settings", "Audio downmix");
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return original;
|
|
}
|