mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-24 11:43:05 +01:00
overlays: get localized values in home menu settings
This commit is contained in:
parent
1211acd59c
commit
070add461f
@ -15,8 +15,10 @@ void fmt_class_string<cfg::node>::format(std::string& out, u64 arg)
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
u32 _base::id_counter = 0;
|
||||
|
||||
_base::_base(type _type)
|
||||
: m_type(_type)
|
||||
: m_type(_type), m_id(id_counter++)
|
||||
{
|
||||
if (_type != type::node)
|
||||
{
|
||||
@ -25,7 +27,7 @@ namespace cfg
|
||||
}
|
||||
|
||||
_base::_base(type _type, node* owner, std::string name, bool dynamic)
|
||||
: m_type(_type), m_dynamic(dynamic), m_name(std::move(name))
|
||||
: m_type(_type), m_parent(owner), m_dynamic(dynamic), m_name(std::move(name)), m_id(id_counter++)
|
||||
{
|
||||
for (const auto& node : owner->m_nodes)
|
||||
{
|
||||
|
@ -51,9 +51,13 @@ namespace cfg
|
||||
const type m_type{};
|
||||
|
||||
protected:
|
||||
_base* m_parent = nullptr;
|
||||
bool m_dynamic = true;
|
||||
const std::string m_name{};
|
||||
|
||||
static u32 id_counter;
|
||||
u32 m_id = 0;
|
||||
|
||||
// Ownerless entry constructor
|
||||
_base(type _type);
|
||||
|
||||
@ -67,9 +71,16 @@ namespace cfg
|
||||
|
||||
virtual ~_base() = default;
|
||||
|
||||
// Get unique ID
|
||||
u32 get_id() const { return m_id; }
|
||||
|
||||
// Get parent
|
||||
_base* get_parent() const { return m_parent; }
|
||||
|
||||
// Get type
|
||||
type get_type() const { return m_type; }
|
||||
|
||||
// Get name
|
||||
const std::string& get_name() const { return m_name; }
|
||||
|
||||
// Get dynamic property for reloading configs during games
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Emu/RSX/Overlays/overlays.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Utilities/Config.h"
|
||||
|
||||
namespace rsx
|
||||
@ -102,7 +103,8 @@ namespace rsx
|
||||
|
||||
if (!this->is_compiled)
|
||||
{
|
||||
m_dropdown.set_text(fmt::format("%s", this->m_last_value));
|
||||
const std::string value_text = Emu.GetCallbacks().get_localized_setting(home_menu_setting<T, cfg::_enum<T>>::m_setting, static_cast<u32>(this->m_last_value));
|
||||
m_dropdown.set_text(value_text);
|
||||
m_dropdown.set_pos(m_dropdown.x, this->y + (this->h - m_dropdown.h) / 2);
|
||||
|
||||
this->compiled_resources = horizontal_layout::get_compiled();
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include "overlay_home_menu_components.h"
|
||||
#include "Emu/system_config.h"
|
||||
|
||||
// TODO: Localization of the dropdown values
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace overlays
|
||||
|
@ -61,7 +61,7 @@ namespace rsx
|
||||
if (setting)
|
||||
{
|
||||
usz new_index = 0;
|
||||
T value = setting->get();
|
||||
const T value = setting->get();
|
||||
const std::string val = fmt::format("%s", value);
|
||||
const std::vector<std::string> list = setting->to_list();
|
||||
|
||||
|
@ -24,6 +24,11 @@ class spu_thread;
|
||||
template <typename T>
|
||||
class named_thread;
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
class _base;
|
||||
}
|
||||
|
||||
enum class system_state : u32
|
||||
{
|
||||
stopped,
|
||||
@ -93,6 +98,7 @@ struct EmuCallbacks
|
||||
std::function<std::unique_ptr<class TrophyNotificationBase>()> get_trophy_notification_dialog;
|
||||
std::function<std::string(localized_string_id, const char*)> get_localized_string;
|
||||
std::function<std::u32string(localized_string_id, const char*)> get_localized_u32string;
|
||||
std::function<std::string(const cfg::_base*, u32)> get_localized_setting;
|
||||
std::function<void(const std::string&)> play_sound;
|
||||
std::function<bool(const std::string&, std::string&, s32&, s32&, s32&)> get_image_info; // (filename, sub_type, width, height, CellSearchOrientation)
|
||||
std::function<bool(const std::string&, s32, s32, s32&, s32&, u8*, bool)> get_scaled_image; // (filename, target_width, target_height, width, height, dst, force_fit)
|
||||
|
@ -161,6 +161,7 @@ void headless_application::InitializeCallbacks()
|
||||
|
||||
callbacks.get_localized_string = [](localized_string_id, const char*) -> std::string { return {}; };
|
||||
callbacks.get_localized_u32string = [](localized_string_id, const char*) -> std::u32string { return {}; };
|
||||
callbacks.get_localized_setting = [](const cfg::_base*, u32) -> std::string { return {}; };
|
||||
|
||||
callbacks.play_sound = [](const std::string&){};
|
||||
callbacks.add_breakpoint = [](u32 /*addr*/){};
|
||||
|
@ -189,7 +189,7 @@ bool emu_settings::ValidateSettings(bool cleanup)
|
||||
|
||||
for (const auto& yml_entry : yml_node)
|
||||
{
|
||||
const std::string key = yml_entry.first.Scalar();
|
||||
const std::string& key = yml_entry.first.Scalar();
|
||||
cfg::_base* cfg_node = nullptr;
|
||||
|
||||
keys.resize(next_level);
|
||||
@ -253,13 +253,13 @@ bool emu_settings::ValidateSettings(bool cleanup)
|
||||
}
|
||||
};
|
||||
|
||||
cfg_root root;
|
||||
std::unique_ptr<cfg_root> root = std::make_unique<cfg_root>();
|
||||
std::vector<std::string> keys;
|
||||
|
||||
do
|
||||
{
|
||||
is_clean = true;
|
||||
search_level(0, m_current_settings, keys, &root);
|
||||
search_level(0, m_current_settings, keys, root.get());
|
||||
}
|
||||
while (cleanup && !is_clean);
|
||||
|
||||
@ -885,6 +885,64 @@ void emu_settings::SetSetting(emu_settings_type type, const std::string& val) co
|
||||
cfg_adapter::get_node(m_current_settings, ::at32(settings_location, type)) = val;
|
||||
}
|
||||
|
||||
emu_settings_type emu_settings::FindSettingsType(const cfg::_base* node) const
|
||||
{
|
||||
// Add key and value to static map on first use
|
||||
static std::map<u32, emu_settings_type> id_to_type;
|
||||
static std::mutex mtx;
|
||||
std::lock_guard lock(mtx);
|
||||
|
||||
if (!node) [[unlikely]]
|
||||
{
|
||||
// Provoke error. Don't use ensure or we will get a nullptr deref warning in VS
|
||||
return ::at32(id_to_type, umax);
|
||||
}
|
||||
|
||||
std::vector<std::string> node_location;
|
||||
if (!id_to_type.contains(node->get_id()))
|
||||
{
|
||||
for (const cfg::_base* n = node; n; n = n->get_parent())
|
||||
{
|
||||
if (!n->get_name().empty())
|
||||
{
|
||||
node_location.push_back(n->get_name());
|
||||
}
|
||||
}
|
||||
|
||||
std::reverse(node_location.begin(), node_location.end());
|
||||
|
||||
for (const auto& [type, loc]: settings_location)
|
||||
{
|
||||
if (node_location.size() != loc.size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool is_match = true;
|
||||
for (usz i = 0; i < node_location.size(); i++)
|
||||
{
|
||||
if (node_location[i] != loc[i])
|
||||
{
|
||||
is_match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_match && !id_to_type.try_emplace(node->get_id(), type).second)
|
||||
{
|
||||
cfg_log.error("'%s' already exists", loc.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!id_to_type.contains(node->get_id()))
|
||||
{
|
||||
fmt::throw_exception("Node '%s' not represented in emu_settings_type", node->get_name());
|
||||
}
|
||||
|
||||
return ::at32(id_to_type, node->get_id());
|
||||
}
|
||||
|
||||
void emu_settings::OpenCorrectionDialog(QWidget* parent)
|
||||
{
|
||||
if (!m_broken_types.empty() && QMessageBox::question(parent, tr("Fix invalid settings?"),
|
||||
@ -1166,6 +1224,16 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_
|
||||
case detail_level::high: return tr("High", "Detail Level");
|
||||
}
|
||||
break;
|
||||
case emu_settings_type::PerfOverlayFramerateDetailLevel:
|
||||
case emu_settings_type::PerfOverlayFrametimeDetailLevel:
|
||||
switch (static_cast<perf_graph_detail_level>(index))
|
||||
{
|
||||
case perf_graph_detail_level::minimal: return tr("Minimal", "Perf Graph Detail Level");
|
||||
case perf_graph_detail_level::show_min_max: return tr("Show Min And Max", "Perf Graph Detail Level");
|
||||
case perf_graph_detail_level::show_one_percent_avg: return tr("Show 1% Low And Average", "Perf Graph Detail Level");
|
||||
case perf_graph_detail_level::show_all: return tr("Show All", "Perf Graph Detail Level");
|
||||
}
|
||||
break;
|
||||
case emu_settings_type::PerfOverlayPosition:
|
||||
switch (static_cast<screen_quadrant>(index))
|
||||
{
|
||||
@ -1386,3 +1454,15 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_
|
||||
|
||||
return original;
|
||||
}
|
||||
|
||||
std::string emu_settings::GetLocalizedSetting(const std::string& original, emu_settings_type type, int index, bool strict) const
|
||||
{
|
||||
return GetLocalizedSetting(QString::fromStdString(original), type, index, strict).toStdString();
|
||||
}
|
||||
|
||||
std::string emu_settings::GetLocalizedSetting(const cfg::_base* node, u32 index) const
|
||||
{
|
||||
const emu_settings_type type = FindSettingsType(node);
|
||||
const std::vector<std::string> settings = GetSettingOptions(type);
|
||||
return GetLocalizedSetting(::at32(settings, index), type, index, true);
|
||||
}
|
||||
|
@ -18,6 +18,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
class _base;
|
||||
}
|
||||
|
||||
constexpr auto qstr = QString::fromStdString;
|
||||
|
||||
class emu_settings : public QObject
|
||||
{
|
||||
/** A settings class for Emulator specific settings. This class is a refactored version of the wx version. It is much nicer
|
||||
@ -76,6 +83,9 @@ public:
|
||||
/** Sets the setting type to a given value.*/
|
||||
void SetSetting(emu_settings_type type, const std::string& val) const;
|
||||
|
||||
/** Try to find the settings type for a given string.*/
|
||||
emu_settings_type FindSettingsType(const cfg::_base* node) const;
|
||||
|
||||
/** Gets all the renderer info for gpu settings.*/
|
||||
render_creator* m_render_creator = nullptr;
|
||||
|
||||
@ -94,6 +104,12 @@ public:
|
||||
/** Get a localized and therefore freely adjustable version of the string used in config.yml.*/
|
||||
QString GetLocalizedSetting(const QString& original, emu_settings_type type, int index, bool strict) const;
|
||||
|
||||
/** Get a localized and therefore freely adjustable version of the string used in config.yml.*/
|
||||
std::string GetLocalizedSetting(const std::string& original, emu_settings_type type, int index, bool strict) const;
|
||||
|
||||
/** Get a localized and therefore freely adjustable version of the string used in config.yml.*/
|
||||
std::string GetLocalizedSetting(const cfg::_base* node, u32 index) const;
|
||||
|
||||
/** Validates the settings and logs unused entries or cleans up the yaml*/
|
||||
bool ValidateSettings(bool cleanup);
|
||||
|
||||
|
@ -111,6 +111,8 @@ enum class emu_settings_type
|
||||
PerfOverlayFramerateDatapoints,
|
||||
PerfOverlayFrametimeDatapoints,
|
||||
PerfOverlayDetailLevel,
|
||||
PerfOverlayFramerateDetailLevel,
|
||||
PerfOverlayFrametimeDetailLevel,
|
||||
PerfOverlayPosition,
|
||||
PerfOverlayUpdateInterval,
|
||||
PerfOverlayFontSize,
|
||||
@ -306,6 +308,8 @@ inline static const std::map<emu_settings_type, cfg_location> settings_location
|
||||
{ emu_settings_type::PerfOverlayFramerateDatapoints, { "Video", "Performance Overlay", "Framerate datapoints" } },
|
||||
{ emu_settings_type::PerfOverlayFrametimeDatapoints, { "Video", "Performance Overlay", "Frametime datapoints" } },
|
||||
{ emu_settings_type::PerfOverlayDetailLevel, { "Video", "Performance Overlay", "Detail level" } },
|
||||
{ emu_settings_type::PerfOverlayFramerateDetailLevel, { "Video", "Performance Overlay", "Framerate graph detail level" } },
|
||||
{ emu_settings_type::PerfOverlayFrametimeDetailLevel, { "Video", "Performance Overlay", "Frametime graph detail level" } },
|
||||
{ emu_settings_type::PerfOverlayPosition, { "Video", "Performance Overlay", "Position" } },
|
||||
{ emu_settings_type::PerfOverlayUpdateInterval, { "Video", "Performance Overlay", "Metrics update interval (ms)" } },
|
||||
{ emu_settings_type::PerfOverlayFontSize, { "Video", "Performance Overlay", "Font size (px)" } },
|
||||
|
@ -606,6 +606,12 @@ void gui_application::InitializeCallbacks()
|
||||
return localized_emu::get_u32string(id, args);
|
||||
};
|
||||
|
||||
callbacks.get_localized_setting = [this](const cfg::_base* node, u32 enum_index) -> std::string
|
||||
{
|
||||
ensure(!!m_emu_settings);
|
||||
return m_emu_settings->GetLocalizedSetting(node, enum_index);
|
||||
};
|
||||
|
||||
callbacks.play_sound = [this](const std::string& path)
|
||||
{
|
||||
Emu.CallFromMainThread([this, path]()
|
||||
|
@ -448,9 +448,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
|
||||
r_creator->update_names(
|
||||
{
|
||||
m_emu_settings->GetLocalizedSetting("Vulkan", emu_settings_type::Renderer, static_cast<int>(video_renderer::vulkan), true),
|
||||
m_emu_settings->GetLocalizedSetting("OpenGl", emu_settings_type::Renderer, static_cast<int>(video_renderer::opengl), true),
|
||||
m_emu_settings->GetLocalizedSetting("Null", emu_settings_type::Renderer, static_cast<int>(video_renderer::null), true)
|
||||
m_emu_settings->GetLocalizedSetting(QString("Vulkan"), emu_settings_type::Renderer, static_cast<int>(video_renderer::vulkan), true),
|
||||
m_emu_settings->GetLocalizedSetting(QString("OpenGl"), emu_settings_type::Renderer, static_cast<int>(video_renderer::opengl), true),
|
||||
m_emu_settings->GetLocalizedSetting(QString("Null"), emu_settings_type::Renderer, static_cast<int>(video_renderer::null), true)
|
||||
});
|
||||
|
||||
// Comboboxes
|
||||
@ -1098,7 +1098,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
};
|
||||
for (const audio_format_flag& audio_fmt : audio_formats)
|
||||
{
|
||||
const QString audio_format_name = m_emu_settings->GetLocalizedSetting("", emu_settings_type::AudioFormats, static_cast<int>(audio_fmt), true);
|
||||
const QString audio_format_name = m_emu_settings->GetLocalizedSetting(QString(), emu_settings_type::AudioFormats, static_cast<int>(audio_fmt), true);
|
||||
QListWidgetItem* item = new QListWidgetItem(audio_format_name, ui->list_audio_formats);
|
||||
item->setData(Qt::UserRole, static_cast<u32>(audio_fmt));
|
||||
if (audio_fmt == audio_format_flag::lpcm_2_48khz)
|
||||
|
Loading…
Reference in New Issue
Block a user