VFS: Add device_info to vfs config

This commit is contained in:
Megamouse 2022-05-08 00:13:21 +02:00
parent de988f6a76
commit b888a6ba37
7 changed files with 180 additions and 23 deletions

View file

@ -262,6 +262,22 @@ void cfg::encode(YAML::Emitter& out, const cfg::_base& rhs)
out << YAML::EndMap;
return;
}
case type::device:
{
out << YAML::BeginMap;
for (const auto& [key, info] : static_cast<const device_entry&>(rhs).get_map())
{
out << YAML::Key << key;
out << YAML::BeginMap;
out << YAML::Key << "Path" << YAML::Value << info.path;
out << YAML::Key << "Serial" << YAML::Value << info.serial;
out << YAML::Key << "VID" << YAML::Value << info.vid;
out << YAML::Key << "PID" << YAML::Value << info.pid;
out << YAML::EndMap;
}
out << YAML::EndMap;
return;
}
default:
{
out << rhs.to_string();
@ -355,6 +371,44 @@ void cfg::decode(const YAML::Node& data, cfg::_base& rhs, bool dynamic)
static_cast<log_entry&>(rhs).set_map(std::move(values));
break;
}
case type::device:
{
if (!data.IsMap())
{
return; // ???
}
map_of_type<device_info> values;
for (const auto& pair : data)
{
if (!pair.first.IsScalar() || !pair.second.IsMap()) continue;
device_info info{};
for (const auto& key_value : pair.second)
{
if (!key_value.first.IsScalar() || !key_value.second.IsScalar()) continue;
if (key_value.first.Scalar() == "Path")
info.path = key_value.second.Scalar();
if (key_value.first.Scalar() == "Serial")
info.serial = key_value.second.Scalar();
if (key_value.first.Scalar() == "VID")
info.vid = key_value.second.Scalar();
if (key_value.first.Scalar() == "PID")
info.pid = key_value.second.Scalar();
}
values.emplace(pair.first.Scalar(), std::move(info));
}
static_cast<device_entry&>(rhs).set_map(std::move(values));
break;
}
default:
{
std::string value;
@ -456,3 +510,13 @@ void cfg::log_entry::from_default()
{
set_map({});
}
void cfg::device_entry::set_map(map_of_type<device_info>&& map)
{
m_map = std::move(map);
}
void cfg::device_entry::from_default()
{
m_map = m_def;
}

View file

@ -37,7 +37,8 @@ namespace cfg
string, // cfg::string type
set, // cfg::set_entry type
map, // cfg::map_entry type
log,
log, // cfg::log_entry type
device, // cfg::device_entry type
};
// Config tree entry abstract base class
@ -521,4 +522,40 @@ namespace cfg
void from_default() override;
};
struct device_info
{
std::string path;
std::string serial;
std::string vid;
std::string pid;
};
class device_entry final : public _base
{
map_of_type<device_info> m_map{};
map_of_type<device_info> m_def{};
public:
device_entry(node* owner, const std::string& name, map_of_type<device_info> def = {})
: _base(type::device, owner, name, true)
, m_map(std::move(def))
{
m_def = m_map;
}
const map_of_type<device_info>& get_map() const
{
return m_map;
}
const map_of_type<device_info>& get_default() const
{
return m_def;
}
void set_map(map_of_type<device_info>&& map);
void from_default() override;
};
}

View file

@ -164,15 +164,40 @@ void Emulator::Init(bool add_only)
// Mount all devices
const std::string emu_dir = rpcs3::utils::get_emu_dir();
const std::string elf_dir = fs::get_parent_dir(m_path);
const std::string dev_hdd0 = g_cfg_vfs.get(g_cfg_vfs.dev_hdd0, emu_dir);
const std::string dev_hdd1 = g_cfg_vfs.get(g_cfg_vfs.dev_hdd1, emu_dir);
const std::string dev_flsh = g_cfg_vfs.get_dev_flash();
const std::string dev_flsh2 = g_cfg_vfs.get_dev_flash2();
const std::string dev_flsh3 = g_cfg_vfs.get_dev_flash3();
vfs::mount("/dev_hdd0", g_cfg_vfs.get(g_cfg_vfs.dev_hdd0, emu_dir));
vfs::mount("/dev_flash", g_cfg_vfs.get_dev_flash());
vfs::mount("/dev_flash2", g_cfg_vfs.get_dev_flash2());
vfs::mount("/dev_flash3", g_cfg_vfs.get_dev_flash3());
vfs::mount("/dev_usb", g_cfg_vfs.get(g_cfg_vfs.dev_usb000, emu_dir));
vfs::mount("/dev_usb000", g_cfg_vfs.get(g_cfg_vfs.dev_usb000, emu_dir));
vfs::mount("/dev_hdd0", dev_hdd0);
vfs::mount("/dev_flash", dev_flsh);
vfs::mount("/dev_flash2", dev_flsh2);
vfs::mount("/dev_flash3", dev_flsh3);
vfs::mount("/app_home", g_cfg_vfs.app_home.to_string().empty() ? elf_dir + '/' : g_cfg_vfs.get(g_cfg_vfs.app_home, emu_dir));
std::string dev_usb;
for (const auto& [key, value] : g_cfg_vfs.dev_usb.get_map())
{
const cfg::device_info usb_info = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, key, emu_dir);
if (key.size() != 11 || !key.starts_with("/dev_usb00"sv) || key.back() < '0' || key.back() > '7')
{
sys_log.error("Trying to mount unsupported usb device: %s", key);
continue;
}
vfs::mount(key, usb_info.path);
if (key == "/dev_usb000"sv)
{
dev_usb = usb_info.path;
}
}
ensure(!dev_usb.empty());
if (!hdd1.empty())
{
vfs::mount("/dev_hdd1", hdd1);
@ -229,13 +254,6 @@ void Emulator::Init(bool add_only)
}
// Create directories (can be disabled if necessary)
const std::string dev_hdd0 = rpcs3::utils::get_hdd0_dir();
const std::string dev_hdd1 = g_cfg_vfs.get(g_cfg_vfs.dev_hdd1, emu_dir);
const std::string dev_usb = g_cfg_vfs.get(g_cfg_vfs.dev_usb000, emu_dir);
const std::string dev_flsh = g_cfg_vfs.get_dev_flash();
const std::string dev_flsh2 = g_cfg_vfs.get_dev_flash2();
const std::string dev_flsh3 = g_cfg_vfs.get_dev_flash3();
auto make_path_verbose = [](const std::string& path)
{
if (!fs::create_path(path))

View file

@ -8,6 +8,11 @@ LOG_CHANNEL(vfs_log, "VFS");
cfg_vfs g_cfg_vfs{};
std::string cfg_vfs::get(const cfg::string& _cfg, std::string_view emu_dir) const
{
return get(_cfg.to_string(), _cfg.def, emu_dir);
}
std::string cfg_vfs::get(const std::string& _cfg, const std::string& def, std::string_view emu_dir) const
{
std::string _emu_dir; // Storage only
@ -29,12 +34,12 @@ std::string cfg_vfs::get(const cfg::string& _cfg, std::string_view emu_dir) cons
emu_dir = _emu_dir;
}
std::string path = _cfg.to_string();
std::string path = _cfg;
if (path.empty())
{
// Fallback
path = _cfg.def;
path = def;
}
path = fmt::replace_all(path, "$(EmulatorDir)", emu_dir);
@ -48,6 +53,34 @@ std::string cfg_vfs::get(const cfg::string& _cfg, std::string_view emu_dir) cons
return path;
}
cfg::device_info cfg_vfs::get_device(const cfg::device_entry& _cfg, std::string_view key, std::string_view emu_dir) const
{
return get_device_info(_cfg, key, emu_dir);
}
cfg::device_info cfg_vfs::get_device_info(const cfg::device_entry& _cfg, std::string_view key, std::string_view emu_dir) const
{
const auto& device_map = _cfg.get_map();
if (auto it = device_map.find(key); it != device_map.cend())
{
// Make sure the path is properly resolved
cfg::device_info info = it->second;
const auto& def_map = _cfg.get_default();
std::string def_path;
if (auto def_it = def_map.find(key); def_it != def_map.cend())
{
def_path = def_it->second.path;
}
info.path = get(info.path, def_path, emu_dir);
return info;
}
return {};
}
void cfg_vfs::load()
{
const std::string path = cfg_vfs::get_path();

View file

@ -4,7 +4,7 @@
struct cfg_vfs : cfg::node
{
std::string get(const cfg::string&, std::string_view emu_dir = {}) const;
std::string get(const cfg::string& _cfg, std::string_view emu_dir = {}) const;
void load();
void save() const;
static std::string get_path();
@ -15,10 +15,14 @@ struct cfg_vfs : cfg::node
cfg::string dev_flash{ this, "/dev_flash/", "$(EmulatorDir)dev_flash/" };
cfg::string dev_flash2{ this, "/dev_flash2/", "$(EmulatorDir)dev_flash2/" };
cfg::string dev_flash3{ this, "/dev_flash3/", "$(EmulatorDir)dev_flash3/" };
cfg::string dev_usb000{ this, "/dev_usb000/", "$(EmulatorDir)dev_usb000/" };
cfg::string dev_bdvd{ this, "/dev_bdvd/" }; // Not mounted
cfg::string app_home{ this, "/app_home/" }; // Not mounted
cfg::device_entry dev_usb{ this, "/dev_usb***/",
{
{ "/dev_usb000", cfg::device_info{.path = "$(EmulatorDir)dev_usb000/"} }
}};
std::string get_dev_flash() const
{
return get(dev_flash);
@ -33,6 +37,12 @@ struct cfg_vfs : cfg::node
{
return get(dev_flash3);
}
cfg::device_info get_device(const cfg::device_entry& _cfg, std::string_view key, std::string_view emu_dir = {}) const;
private:
std::string get(const std::string& _cfg, const std::string& def, std::string_view emu_dir) const;
cfg::device_info get_device_info(const cfg::device_entry& _cfg, std::string_view key, std::string_view emu_dir = {}) const;
};
extern cfg_vfs g_cfg_vfs;

View file

@ -182,7 +182,6 @@ namespace gui
const gui_save fs_dev_flash_list = gui_save(fs, "dev_flash_list", QStringList());
const gui_save fs_dev_flash2_list = gui_save(fs, "dev_flash2_list", QStringList());
const gui_save fs_dev_flash3_list = gui_save(fs, "dev_flash3_list", QStringList());
const gui_save fs_dev_usb000_list = gui_save(fs, "dev_usb000_list", QStringList());
const gui_save l_tty = gui_save(logger, "TTY", true);
const gui_save l_level = gui_save(logger, "level", static_cast<uchar>(logs::level::success));

View file

@ -40,16 +40,12 @@ vfs_dialog::vfs_dialog(std::shared_ptr<gui_settings> guiSettings, std::shared_pt
vfs_dialog_tab* dev_flash3_tab = new vfs_dialog_tab({ "dev_flash3", gui::fs_dev_flash3_list, &g_cfg_vfs.dev_flash3 },
m_gui_settings, this);
vfs_dialog_tab* dev_usb000_tab = new vfs_dialog_tab({ "dev_usb000", gui::fs_dev_usb000_list, &g_cfg_vfs.dev_usb000 },
m_gui_settings, this);
tabs->addTab(emulator_tab, "$(EmulatorDir)");
tabs->addTab(dev_hdd0_tab, "dev_hdd0");
tabs->addTab(dev_hdd1_tab, "dev_hdd1");
tabs->addTab(dev_flash_tab, "dev_flash");
tabs->addTab(dev_flash2_tab, "dev_flash2");
tabs->addTab(dev_flash3_tab, "dev_flash3");
tabs->addTab(dev_usb000_tab, "dev_usb000");
// Create buttons
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Close | QDialogButtonBox::Save | QDialogButtonBox::RestoreDefaults);