mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
settings: enable dynamic reload of some emu values
This commit is contained in:
parent
f2b530823b
commit
d91f8193b0
@ -17,8 +17,8 @@ namespace cfg
|
||||
}
|
||||
}
|
||||
|
||||
_base::_base(type _type, node* owner, const std::string& name)
|
||||
: m_type(_type)
|
||||
_base::_base(type _type, node* owner, const std::string& name, bool dynamic)
|
||||
: m_type(_type), m_dynamic(dynamic)
|
||||
{
|
||||
for (const auto& pair : owner->m_nodes)
|
||||
{
|
||||
@ -31,7 +31,7 @@ namespace cfg
|
||||
owner->m_nodes.emplace_back(name, this);
|
||||
}
|
||||
|
||||
bool _base::from_string(const std::string&)
|
||||
bool _base::from_string(const std::string&, bool)
|
||||
{
|
||||
fmt::throw_exception("from_string() purecall" HERE);
|
||||
}
|
||||
@ -46,7 +46,7 @@ namespace cfg
|
||||
|
||||
// Incrementally load config entries from YAML::Node.
|
||||
// The config value is preserved if the corresponding YAML node doesn't exist.
|
||||
static void decode(const YAML::Node& data, class _base& rhs);
|
||||
static void decode(const YAML::Node& data, class _base& rhs, bool dynamic = false);
|
||||
}
|
||||
|
||||
std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
|
||||
@ -212,8 +212,13 @@ void cfg::encode(YAML::Emitter& out, const cfg::_base& rhs)
|
||||
}
|
||||
}
|
||||
|
||||
void cfg::decode(const YAML::Node& data, cfg::_base& rhs)
|
||||
void cfg::decode(const YAML::Node& data, cfg::_base& rhs, bool dynamic)
|
||||
{
|
||||
if (dynamic && !rhs.get_is_dynamic())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (rhs.get_type())
|
||||
{
|
||||
case type::node:
|
||||
@ -232,7 +237,7 @@ void cfg::decode(const YAML::Node& data, cfg::_base& rhs)
|
||||
{
|
||||
if (_pair.first == pair.first.Scalar())
|
||||
{
|
||||
decode(pair.second, *_pair.second);
|
||||
decode(pair.second, *_pair.second, dynamic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -295,9 +300,9 @@ std::string cfg::node::to_string() const
|
||||
return {out.c_str(), out.size()};
|
||||
}
|
||||
|
||||
bool cfg::node::from_string(const std::string& value) try
|
||||
bool cfg::node::from_string(const std::string& value, bool dynamic) try
|
||||
{
|
||||
cfg::decode(YAML::Load(value), *this);
|
||||
cfg::decode(YAML::Load(value), *this, dynamic);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
@ -42,11 +42,13 @@ namespace cfg
|
||||
const type m_type;
|
||||
|
||||
protected:
|
||||
bool m_dynamic = true;
|
||||
|
||||
// Ownerless entry constructor
|
||||
_base(type _type);
|
||||
|
||||
// Owned entry constructor
|
||||
_base(type _type, class node* owner, const std::string& name);
|
||||
_base(type _type, class node* owner, const std::string& name, bool dynamic = true);
|
||||
|
||||
public:
|
||||
_base(const _base&) = delete;
|
||||
@ -56,6 +58,9 @@ namespace cfg
|
||||
// Get type
|
||||
type get_type() const { return m_type; }
|
||||
|
||||
// Get dynamic property for reloading configs during games
|
||||
bool get_is_dynamic() const { return m_dynamic; };
|
||||
|
||||
// Reset defaults
|
||||
virtual void from_default() = 0;
|
||||
|
||||
@ -66,7 +71,7 @@ namespace cfg
|
||||
}
|
||||
|
||||
// Try to convert from string (optional)
|
||||
virtual bool from_string(const std::string&);
|
||||
virtual bool from_string(const std::string&, bool /*dynamic*/ = false);
|
||||
|
||||
// Get string list (optional)
|
||||
virtual std::vector<std::string> to_list() const
|
||||
@ -93,8 +98,8 @@ namespace cfg
|
||||
}
|
||||
|
||||
// Registered node constructor
|
||||
node(node* owner, const std::string& name)
|
||||
: _base(type::node, owner, name)
|
||||
node(node* owner, const std::string& name, bool dynamic = true)
|
||||
: _base(type::node, owner, name, dynamic)
|
||||
{
|
||||
}
|
||||
|
||||
@ -108,7 +113,7 @@ namespace cfg
|
||||
std::string to_string() const override;
|
||||
|
||||
// Deserialize node
|
||||
bool from_string(const std::string& value) override;
|
||||
bool from_string(const std::string& value, bool dynamic = false) override;
|
||||
|
||||
// Set default values
|
||||
void from_default() override;
|
||||
@ -121,8 +126,8 @@ namespace cfg
|
||||
public:
|
||||
bool def;
|
||||
|
||||
_bool(node* owner, const std::string& name, bool def = false)
|
||||
: _base(type::_bool, owner, name)
|
||||
_bool(node* owner, const std::string& name, bool def = false, bool dynamic = false)
|
||||
: _base(type::_bool, owner, name, dynamic)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
{
|
||||
@ -145,7 +150,7 @@ namespace cfg
|
||||
return m_value ? "true" : "false";
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
if (value == "false")
|
||||
m_value = false;
|
||||
@ -172,8 +177,8 @@ namespace cfg
|
||||
public:
|
||||
const T def;
|
||||
|
||||
_enum(node* owner, const std::string& name, T value = {})
|
||||
: _base(type::_enum, owner, name)
|
||||
_enum(node* owner, const std::string& name, T value = {}, bool dynamic = false)
|
||||
: _base(type::_enum, owner, name, dynamic)
|
||||
, m_value(value)
|
||||
, def(value)
|
||||
{
|
||||
@ -201,7 +206,7 @@ namespace cfg
|
||||
return result; // TODO: ???
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
u64 result;
|
||||
|
||||
@ -239,8 +244,8 @@ namespace cfg
|
||||
static const s64 max = Max;
|
||||
static const s64 min = Min;
|
||||
|
||||
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)))
|
||||
: _base(type::_int, owner, name)
|
||||
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)), bool dynamic = false)
|
||||
: _base(type::_int, owner, name, dynamic)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
{
|
||||
@ -266,7 +271,7 @@ namespace cfg
|
||||
return std::to_string(m_value);
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
s64 result;
|
||||
if (try_to_int64(&result, value, Min, Max))
|
||||
@ -304,8 +309,8 @@ namespace cfg
|
||||
public:
|
||||
std::string def;
|
||||
|
||||
string(node* owner, const std::string& name, const std::string& def = {})
|
||||
: _base(type::string, owner, name)
|
||||
string(node* owner, const std::string& name, const std::string& def = {}, bool dynamic = false)
|
||||
: _base(type::string, owner, name, dynamic)
|
||||
, m_name(name)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
@ -339,7 +344,7 @@ namespace cfg
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool from_string(const std::string& value) override
|
||||
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
m_value = value;
|
||||
return true;
|
||||
@ -353,8 +358,8 @@ namespace cfg
|
||||
|
||||
public:
|
||||
// Default value is empty list in current implementation
|
||||
set_entry(node* owner, const std::string& name)
|
||||
: _base(type::set, owner, name)
|
||||
set_entry(node* owner, const std::string& name, bool dynamic = false)
|
||||
: _base(type::set, owner, name, dynamic)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1081,7 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
|
||||
// If not, the data has no NPDRM layer.
|
||||
if (!ctrl)
|
||||
{
|
||||
LOG_NOTICE(LOADER, "SELF: No NPDRM control info found!");
|
||||
LOG_TRACE(LOADER, "SELF: No NPDRM control info found!");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -331,6 +331,7 @@ void Emulator::Init()
|
||||
if (const fs::file cfg_file{cfg_path, fs::read + fs::create})
|
||||
{
|
||||
g_cfg.from_string(cfg_file.to_string());
|
||||
g_cfg.name = cfg_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1021,6 +1022,7 @@ void Emulator::Load(const std::string& title_id, bool add_only, bool force_globa
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Applying custom config: %s", config_path_new);
|
||||
g_cfg.from_string(cfg_file.to_string());
|
||||
g_cfg.name = config_path_new;
|
||||
}
|
||||
|
||||
// Load custom config-3
|
||||
|
@ -514,23 +514,23 @@ struct cfg_root : cfg::node
|
||||
{
|
||||
node_perf_overlay(cfg::node* _this) : cfg::node(_this, "Performance Overlay") {}
|
||||
|
||||
cfg::_bool perf_overlay_enabled{this, "Enabled", false};
|
||||
cfg::_bool framerate_graph_enabled{ this, "Enable Framerate Graph", false };
|
||||
cfg::_bool frametime_graph_enabled{ this, "Enable Frametime Graph", false };
|
||||
cfg::_enum<detail_level> level{this, "Detail level", detail_level::medium};
|
||||
cfg::_int<30, 5000> update_interval{ this, "Metrics update interval (ms)", 350 };
|
||||
cfg::_int<4, 36> font_size{ this, "Font size (px)", 10 };
|
||||
cfg::_enum<screen_quadrant> position{this, "Position", screen_quadrant::top_left};
|
||||
cfg::string font{this, "Font", "n023055ms.ttf"};
|
||||
cfg::_int<0, 1280> margin_x{this, "Horizontal Margin (px)", 50}; // horizontal distance to the screen border relative to the screen_quadrant in px
|
||||
cfg::_int<0, 720> margin_y{this, "Vertical Margin (px)", 50}; // vertical distance to the screen border relative to the screen_quadrant in px
|
||||
cfg::_bool center_x{ this, "Center Horizontally", false };
|
||||
cfg::_bool center_y{ this, "Center Vertically", false };
|
||||
cfg::_int<0, 100> opacity{this, "Opacity (%)", 70};
|
||||
cfg::string color_body{ this, "Body Color (hex)", "#FFE138FF" };
|
||||
cfg::string background_body{ this, "Body Background (hex)", "#002339FF" };
|
||||
cfg::string color_title{ this, "Title Color (hex)", "#F26C24FF" };
|
||||
cfg::string background_title{ this, "Title Background (hex)", "#00000000" };
|
||||
cfg::_bool perf_overlay_enabled{ this, "Enabled", false, true };
|
||||
cfg::_bool framerate_graph_enabled{ this, "Enable Framerate Graph", false, true };
|
||||
cfg::_bool frametime_graph_enabled{ this, "Enable Frametime Graph", false, true };
|
||||
cfg::_enum<detail_level> level{ this, "Detail level", detail_level::medium, true };
|
||||
cfg::_int<30, 5000> update_interval{ this, "Metrics update interval (ms)", 350, true };
|
||||
cfg::_int<4, 36> font_size{ this, "Font size (px)", 10, true };
|
||||
cfg::_enum<screen_quadrant> position{ this, "Position", screen_quadrant::top_left, true };
|
||||
cfg::string font{ this, "Font", "n023055ms.ttf", true };
|
||||
cfg::_int<0, 1280> margin_x{ this, "Horizontal Margin (px)", 50, true }; // horizontal distance to the screen border relative to the screen_quadrant in px
|
||||
cfg::_int<0, 720> margin_y{ this, "Vertical Margin (px)", 50, true }; // vertical distance to the screen border relative to the screen_quadrant in px
|
||||
cfg::_bool center_x{ this, "Center Horizontally", false, true };
|
||||
cfg::_bool center_y{ this, "Center Vertically", false, true };
|
||||
cfg::_int<0, 100> opacity{ this, "Opacity (%)", 70, true };
|
||||
cfg::string color_body{ this, "Body Color (hex)", "#FFE138FF", true };
|
||||
cfg::string background_body{ this, "Body Background (hex)", "#002339FF", true };
|
||||
cfg::string color_title{ this, "Title Color (hex)", "#F26C24FF", true };
|
||||
cfg::string background_title{ this, "Title Background (hex)", "#00000000", true };
|
||||
|
||||
} perf_overlay{this};
|
||||
|
||||
@ -538,8 +538,8 @@ struct cfg_root : cfg::node
|
||||
{
|
||||
node_shader_compilation_hint(cfg::node* _this) : cfg::node(_this, "Shader Compilation Hint") {}
|
||||
|
||||
cfg::_int<0, 1280> pos_x{this, "Position X (px)", 20}; // horizontal position starting from the upper border in px
|
||||
cfg::_int<0, 720> pos_y{this, "Position Y (px)", 690}; // vertical position starting from the left border in px
|
||||
cfg::_int<0, 1280> pos_x{ this, "Position X (px)", 20, true }; // horizontal position starting from the upper border in px
|
||||
cfg::_int<0, 720> pos_y{ this, "Position Y (px)", 690, true }; // vertical position starting from the left border in px
|
||||
|
||||
} shader_compilation_hint{this};
|
||||
|
||||
@ -547,9 +547,9 @@ struct cfg_root : cfg::node
|
||||
{
|
||||
node_shader_preloading_dialog(cfg::node* _this) : cfg::node(_this, "Shader Loading Dialog"){}
|
||||
|
||||
cfg::_bool use_custom_background{this, "Allow custom background", true};
|
||||
cfg::_int<0, 100> darkening_strength{this, "Darkening effect strength", 30};
|
||||
cfg::_int<0, 100> blur_strength{this, "Blur effect strength", 0};
|
||||
cfg::_bool use_custom_background{ this, "Allow custom background", true, true };
|
||||
cfg::_int<0, 100> darkening_strength{ this, "Darkening effect strength", 30, true };
|
||||
cfg::_int<0, 100> blur_strength{ this, "Blur effect strength", 0, true };
|
||||
|
||||
} shader_preloading_dialog{this};
|
||||
|
||||
@ -581,7 +581,6 @@ struct cfg_root : cfg::node
|
||||
|
||||
cfg::_enum<keyboard_handler> keyboard{this, "Keyboard", keyboard_handler::null};
|
||||
cfg::_enum<mouse_handler> mouse{this, "Mouse", mouse_handler::basic};
|
||||
cfg::_enum<pad_handler> pad{this, "Pad", pad_handler::keyboard};
|
||||
cfg::_enum<camera_handler> camera{this, "Camera", camera_handler::null};
|
||||
cfg::_enum<fake_camera_type> camera_type{this, "Camera type", fake_camera_type::unknown};
|
||||
cfg::_enum<move_handler> move{this, "Move", move_handler::null};
|
||||
@ -610,19 +609,21 @@ struct cfg_root : cfg::node
|
||||
{
|
||||
node_misc(cfg::node* _this) : cfg::node(_this, "Miscellaneous") {}
|
||||
|
||||
cfg::_bool autostart{this, "Automatically start games after boot", true};
|
||||
cfg::_bool autoexit{this, "Exit RPCS3 when process finishes"};
|
||||
cfg::_bool start_fullscreen{ this, "Start games in fullscreen mode" };
|
||||
cfg::_bool autostart{ this, "Automatically start games after boot", true, true };
|
||||
cfg::_bool autoexit{ this, "Exit RPCS3 when process finishes", false, true };
|
||||
cfg::_bool start_fullscreen{ this, "Start games in fullscreen mode", false, true };
|
||||
cfg::_bool prevent_display_sleep{ this, "Prevent display sleep while running games", true};
|
||||
cfg::_bool show_fps_in_title{ this, "Show FPS counter in window title", true};
|
||||
cfg::_bool show_trophy_popups{ this, "Show trophy popups", true};
|
||||
cfg::_bool show_shader_compilation_hint{ this, "Show shader compilation hint", true };
|
||||
cfg::_bool show_fps_in_title{ this, "Show FPS counter in window title", true, true };
|
||||
cfg::_bool show_trophy_popups{ this, "Show trophy popups", true, true };
|
||||
cfg::_bool show_shader_compilation_hint{ this, "Show shader compilation hint", true, true };
|
||||
cfg::_bool use_native_interface{ this, "Use native user interface", true };
|
||||
cfg::string gdb_server{this, "GDB Server", "127.0.0.1:2345"};
|
||||
|
||||
} misc{this};
|
||||
|
||||
cfg::log_entry log{this, "Log"};
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
||||
extern cfg_root g_cfg;
|
||||
|
@ -296,19 +296,36 @@ void emu_settings::SaveSettings()
|
||||
YAML::Emitter out;
|
||||
emitData(out, m_currentSettings);
|
||||
|
||||
if (!m_title_id.empty())
|
||||
std::string config_name;
|
||||
|
||||
if (m_title_id.empty())
|
||||
{
|
||||
config = fs::file(Emulator::GetCustomConfigPath(m_title_id), fs::read + fs::write + fs::create);
|
||||
config_name = fs::get_config_dir() + "/config.yml";
|
||||
}
|
||||
else
|
||||
{
|
||||
config = fs::file(fs::get_config_dir() + "/config.yml", fs::read + fs::write + fs::create);
|
||||
config_name = Emulator::GetCustomConfigPath(m_title_id);
|
||||
}
|
||||
|
||||
config = fs::file(config_name, fs::read + fs::write + fs::create);
|
||||
|
||||
// Save config
|
||||
config.seek(0);
|
||||
config.trunc(0);
|
||||
config.write(out.c_str(), out.size());
|
||||
|
||||
// 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
|
||||
g_cfg.from_string(config.to_string(), true);
|
||||
|
||||
if (!Emu.IsStopped()) // Don't spam the log while emulation is stopped. The config will be logged on boot anyway.
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Updated configuration:\n%s\n", g_cfg.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
config.close();
|
||||
}
|
||||
|
||||
|
@ -967,10 +967,14 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
connect(configure, &QAction::triggered, [=]
|
||||
{
|
||||
settings_dialog dlg(m_gui_settings, m_emu_settings, 0, this, &currGame);
|
||||
if (dlg.exec() == QDialog::Accepted && !gameinfo->hasCustomConfig)
|
||||
if (dlg.exec() == QDialog::Accepted)
|
||||
{
|
||||
gameinfo->hasCustomConfig = true;
|
||||
ShowCustomConfigIcon(item);
|
||||
if (!gameinfo->hasCustomConfig)
|
||||
{
|
||||
gameinfo->hasCustomConfig = true;
|
||||
ShowCustomConfigIcon(item);
|
||||
}
|
||||
Q_EMIT NotifyEmuSettingsChange();
|
||||
}
|
||||
});
|
||||
connect(pad_configure, &QAction::triggered, [=]
|
||||
|
@ -230,6 +230,7 @@ Q_SIGNALS:
|
||||
void GameListFrameClosed();
|
||||
void RequestBoot(const game_info& game, bool force_global_config = false);
|
||||
void RequestIconSizeChange(const int& val);
|
||||
void NotifyEmuSettingsChange();
|
||||
protected:
|
||||
/** Override inherited method from Qt to allow signalling when close happened.*/
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
@ -1593,6 +1593,8 @@ void main_window::CreateDockWindows()
|
||||
{
|
||||
Boot(game->info.path, game->info.serial, false, false, force_global_config);
|
||||
});
|
||||
|
||||
connect(m_gameListFrame, &game_list_frame::NotifyEmuSettingsChange, this, &main_window::NotifyEmuSettingsChange);
|
||||
}
|
||||
|
||||
void main_window::ConfigureGuiFromSettings(bool configure_all)
|
||||
|
Loading…
Reference in New Issue
Block a user