mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +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
|
namespace cfg
|
||||||
{
|
{
|
||||||
|
u32 _base::id_counter = 0;
|
||||||
|
|
||||||
_base::_base(type _type)
|
_base::_base(type _type)
|
||||||
: m_type(_type)
|
: m_type(_type), m_id(id_counter++)
|
||||||
{
|
{
|
||||||
if (_type != type::node)
|
if (_type != type::node)
|
||||||
{
|
{
|
||||||
@ -25,7 +27,7 @@ namespace cfg
|
|||||||
}
|
}
|
||||||
|
|
||||||
_base::_base(type _type, node* owner, std::string name, bool dynamic)
|
_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)
|
for (const auto& node : owner->m_nodes)
|
||||||
{
|
{
|
||||||
|
@ -51,9 +51,13 @@ namespace cfg
|
|||||||
const type m_type{};
|
const type m_type{};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
_base* m_parent = nullptr;
|
||||||
bool m_dynamic = true;
|
bool m_dynamic = true;
|
||||||
const std::string m_name{};
|
const std::string m_name{};
|
||||||
|
|
||||||
|
static u32 id_counter;
|
||||||
|
u32 m_id = 0;
|
||||||
|
|
||||||
// Ownerless entry constructor
|
// Ownerless entry constructor
|
||||||
_base(type _type);
|
_base(type _type);
|
||||||
|
|
||||||
@ -67,9 +71,16 @@ namespace cfg
|
|||||||
|
|
||||||
virtual ~_base() = default;
|
virtual ~_base() = default;
|
||||||
|
|
||||||
|
// Get unique ID
|
||||||
|
u32 get_id() const { return m_id; }
|
||||||
|
|
||||||
|
// Get parent
|
||||||
|
_base* get_parent() const { return m_parent; }
|
||||||
|
|
||||||
// Get type
|
// Get type
|
||||||
type get_type() const { return m_type; }
|
type get_type() const { return m_type; }
|
||||||
|
|
||||||
|
// Get name
|
||||||
const std::string& get_name() const { return m_name; }
|
const std::string& get_name() const { return m_name; }
|
||||||
|
|
||||||
// Get dynamic property for reloading configs during games
|
// Get dynamic property for reloading configs during games
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Emu/RSX/Overlays/overlays.h"
|
#include "Emu/RSX/Overlays/overlays.h"
|
||||||
|
#include "Emu/System.h"
|
||||||
#include "Utilities/Config.h"
|
#include "Utilities/Config.h"
|
||||||
|
|
||||||
namespace rsx
|
namespace rsx
|
||||||
@ -102,7 +103,8 @@ namespace rsx
|
|||||||
|
|
||||||
if (!this->is_compiled)
|
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);
|
m_dropdown.set_pos(m_dropdown.x, this->y + (this->h - m_dropdown.h) / 2);
|
||||||
|
|
||||||
this->compiled_resources = horizontal_layout::get_compiled();
|
this->compiled_resources = horizontal_layout::get_compiled();
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include "overlay_home_menu_components.h"
|
#include "overlay_home_menu_components.h"
|
||||||
#include "Emu/system_config.h"
|
#include "Emu/system_config.h"
|
||||||
|
|
||||||
// TODO: Localization of the dropdown values
|
|
||||||
|
|
||||||
namespace rsx
|
namespace rsx
|
||||||
{
|
{
|
||||||
namespace overlays
|
namespace overlays
|
||||||
|
@ -61,7 +61,7 @@ namespace rsx
|
|||||||
if (setting)
|
if (setting)
|
||||||
{
|
{
|
||||||
usz new_index = 0;
|
usz new_index = 0;
|
||||||
T value = setting->get();
|
const T value = setting->get();
|
||||||
const std::string val = fmt::format("%s", value);
|
const std::string val = fmt::format("%s", value);
|
||||||
const std::vector<std::string> list = setting->to_list();
|
const std::vector<std::string> list = setting->to_list();
|
||||||
|
|
||||||
|
@ -24,6 +24,11 @@ class spu_thread;
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class named_thread;
|
class named_thread;
|
||||||
|
|
||||||
|
namespace cfg
|
||||||
|
{
|
||||||
|
class _base;
|
||||||
|
}
|
||||||
|
|
||||||
enum class system_state : u32
|
enum class system_state : u32
|
||||||
{
|
{
|
||||||
stopped,
|
stopped,
|
||||||
@ -93,6 +98,7 @@ struct EmuCallbacks
|
|||||||
std::function<std::unique_ptr<class TrophyNotificationBase>()> get_trophy_notification_dialog;
|
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::string(localized_string_id, const char*)> get_localized_string;
|
||||||
std::function<std::u32string(localized_string_id, const char*)> get_localized_u32string;
|
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<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&, 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)
|
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_string = [](localized_string_id, const char*) -> std::string { return {}; };
|
||||||
callbacks.get_localized_u32string = [](localized_string_id, const char*) -> std::u32string { 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.play_sound = [](const std::string&){};
|
||||||
callbacks.add_breakpoint = [](u32 /*addr*/){};
|
callbacks.add_breakpoint = [](u32 /*addr*/){};
|
||||||
|
@ -189,7 +189,7 @@ bool emu_settings::ValidateSettings(bool cleanup)
|
|||||||
|
|
||||||
for (const auto& yml_entry : yml_node)
|
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;
|
cfg::_base* cfg_node = nullptr;
|
||||||
|
|
||||||
keys.resize(next_level);
|
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;
|
std::vector<std::string> keys;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
is_clean = true;
|
is_clean = true;
|
||||||
search_level(0, m_current_settings, keys, &root);
|
search_level(0, m_current_settings, keys, root.get());
|
||||||
}
|
}
|
||||||
while (cleanup && !is_clean);
|
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;
|
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)
|
void emu_settings::OpenCorrectionDialog(QWidget* parent)
|
||||||
{
|
{
|
||||||
if (!m_broken_types.empty() && QMessageBox::question(parent, tr("Fix invalid settings?"),
|
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");
|
case detail_level::high: return tr("High", "Detail Level");
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case emu_settings_type::PerfOverlayPosition:
|
||||||
switch (static_cast<screen_quadrant>(index))
|
switch (static_cast<screen_quadrant>(index))
|
||||||
{
|
{
|
||||||
@ -1386,3 +1454,15 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_
|
|||||||
|
|
||||||
return original;
|
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 <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace cfg
|
||||||
|
{
|
||||||
|
class _base;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto qstr = QString::fromStdString;
|
||||||
|
|
||||||
class emu_settings : public QObject
|
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
|
/** 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.*/
|
/** Sets the setting type to a given value.*/
|
||||||
void SetSetting(emu_settings_type type, const std::string& val) const;
|
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.*/
|
/** Gets all the renderer info for gpu settings.*/
|
||||||
render_creator* m_render_creator = nullptr;
|
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.*/
|
/** 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;
|
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*/
|
/** Validates the settings and logs unused entries or cleans up the yaml*/
|
||||||
bool ValidateSettings(bool cleanup);
|
bool ValidateSettings(bool cleanup);
|
||||||
|
|
||||||
|
@ -111,6 +111,8 @@ enum class emu_settings_type
|
|||||||
PerfOverlayFramerateDatapoints,
|
PerfOverlayFramerateDatapoints,
|
||||||
PerfOverlayFrametimeDatapoints,
|
PerfOverlayFrametimeDatapoints,
|
||||||
PerfOverlayDetailLevel,
|
PerfOverlayDetailLevel,
|
||||||
|
PerfOverlayFramerateDetailLevel,
|
||||||
|
PerfOverlayFrametimeDetailLevel,
|
||||||
PerfOverlayPosition,
|
PerfOverlayPosition,
|
||||||
PerfOverlayUpdateInterval,
|
PerfOverlayUpdateInterval,
|
||||||
PerfOverlayFontSize,
|
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::PerfOverlayFramerateDatapoints, { "Video", "Performance Overlay", "Framerate datapoints" } },
|
||||||
{ emu_settings_type::PerfOverlayFrametimeDatapoints, { "Video", "Performance Overlay", "Frametime datapoints" } },
|
{ emu_settings_type::PerfOverlayFrametimeDatapoints, { "Video", "Performance Overlay", "Frametime datapoints" } },
|
||||||
{ emu_settings_type::PerfOverlayDetailLevel, { "Video", "Performance Overlay", "Detail level" } },
|
{ 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::PerfOverlayPosition, { "Video", "Performance Overlay", "Position" } },
|
||||||
{ emu_settings_type::PerfOverlayUpdateInterval, { "Video", "Performance Overlay", "Metrics update interval (ms)" } },
|
{ emu_settings_type::PerfOverlayUpdateInterval, { "Video", "Performance Overlay", "Metrics update interval (ms)" } },
|
||||||
{ emu_settings_type::PerfOverlayFontSize, { "Video", "Performance Overlay", "Font size (px)" } },
|
{ 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);
|
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)
|
callbacks.play_sound = [this](const std::string& path)
|
||||||
{
|
{
|
||||||
Emu.CallFromMainThread([this, 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(
|
r_creator->update_names(
|
||||||
{
|
{
|
||||||
m_emu_settings->GetLocalizedSetting("Vulkan", emu_settings_type::Renderer, static_cast<int>(video_renderer::vulkan), true),
|
m_emu_settings->GetLocalizedSetting(QString("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(QString("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("Null"), emu_settings_type::Renderer, static_cast<int>(video_renderer::null), true)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Comboboxes
|
// 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)
|
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);
|
QListWidgetItem* item = new QListWidgetItem(audio_format_name, ui->list_audio_formats);
|
||||||
item->setData(Qt::UserRole, static_cast<u32>(audio_fmt));
|
item->setData(Qt::UserRole, static_cast<u32>(audio_fmt));
|
||||||
if (audio_fmt == audio_format_flag::lpcm_2_48khz)
|
if (audio_fmt == audio_format_flag::lpcm_2_48khz)
|
||||||
|
Loading…
Reference in New Issue
Block a user