1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-21 10:12:32 +01:00

overlays: get localized values in home menu settings

This commit is contained in:
Megamouse 2024-11-14 23:48:51 +01:00
parent 1211acd59c
commit 070add461f
12 changed files with 139 additions and 13 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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();

View File

@ -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)

View File

@ -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*/){};

View File

@ -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);
}

View File

@ -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);

View File

@ -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)" } },

View File

@ -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]()

View File

@ -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)