mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 07:21:25 +12:00
Qt/Loader: Let users choose which packages to install
This commit is contained in:
parent
c3b7229fbb
commit
66e1cf96e2
6 changed files with 111 additions and 44 deletions
|
@ -1645,17 +1645,19 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> pkgs;
|
||||||
|
|
||||||
if (!lock_file && !ins_dir.empty())
|
if (!lock_file && !ins_dir.empty())
|
||||||
{
|
{
|
||||||
sys_log.notice("Found INSDIR: %s", ins_dir);
|
sys_log.notice("Found INSDIR: %s", ins_dir);
|
||||||
|
|
||||||
for (auto&& entry : fs::dir{ins_dir})
|
for (auto&& entry : fs::dir{ins_dir})
|
||||||
{
|
{
|
||||||
const std::string pkg = ins_dir + entry.name;
|
const std::string pkg_file = ins_dir + entry.name;
|
||||||
if (!entry.is_directory && entry.name.ends_with(".PKG") && !rpcs3::utils::install_pkg(pkg))
|
|
||||||
|
if (!entry.is_directory && entry.name.ends_with(".PKG"))
|
||||||
{
|
{
|
||||||
sys_log.error("Failed to install %s", pkg);
|
pkgs.push_back(pkg_file);
|
||||||
return game_boot_result::install_failed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1670,10 +1672,9 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||||
{
|
{
|
||||||
const std::string pkg_file = pkg_dir + entry.name + "/INSTALL.PKG";
|
const std::string pkg_file = pkg_dir + entry.name + "/INSTALL.PKG";
|
||||||
|
|
||||||
if (fs::is_file(pkg_file) && !rpcs3::utils::install_pkg(pkg_file))
|
if (fs::is_file(pkg_file))
|
||||||
{
|
{
|
||||||
sys_log.error("Failed to install %s", pkg_file);
|
pkgs.push_back(pkg_file);
|
||||||
return game_boot_result::install_failed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1689,14 +1690,30 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||||
{
|
{
|
||||||
const std::string pkg_file = extra_dir + entry.name + "/DATA000.PKG";
|
const std::string pkg_file = extra_dir + entry.name + "/DATA000.PKG";
|
||||||
|
|
||||||
if (fs::is_file(pkg_file) && !rpcs3::utils::install_pkg(pkg_file))
|
if (fs::is_file(pkg_file))
|
||||||
{
|
{
|
||||||
sys_log.error("Failed to install %s", pkg_file);
|
pkgs.push_back(pkg_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pkgs.empty())
|
||||||
|
{
|
||||||
|
bool install_success = true;
|
||||||
|
BlockingCallFromMainThread([this, &pkgs, &install_success]()
|
||||||
|
{
|
||||||
|
if (!GetCallbacks().on_install_pkgs(pkgs))
|
||||||
|
{
|
||||||
|
install_success = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!install_success)
|
||||||
|
{
|
||||||
|
sys_log.error("Failed to install packages");
|
||||||
return game_boot_result::install_failed;
|
return game_boot_result::install_failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lock_file)
|
if (!lock_file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,6 +95,7 @@ struct EmuCallbacks
|
||||||
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)
|
||||||
std::string(*resolve_path)(std::string_view) = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt
|
std::string(*resolve_path)(std::string_view) = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt
|
||||||
std::function<std::vector<std::string>()> get_font_dirs;
|
std::function<std::vector<std::string>()> get_font_dirs;
|
||||||
|
std::function<bool(const std::vector<std::string>&)> on_install_pkgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
|
|
|
@ -348,5 +348,18 @@ EmuCallbacks main_application::CreateCallbacks()
|
||||||
return font_dirs;
|
return font_dirs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
callbacks.on_install_pkgs = [](const std::vector<std::string>& pkgs)
|
||||||
|
{
|
||||||
|
for (const std::string& pkg : pkgs)
|
||||||
|
{
|
||||||
|
if (!rpcs3::utils::install_pkg(pkg))
|
||||||
|
{
|
||||||
|
sys_log.error("Failed to install %s", pkg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
return callbacks;
|
return callbacks;
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,6 +554,21 @@ void gui_application::InitializeCallbacks()
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (m_show_gui) // If this is false, we already have a fallback in the main_application.
|
||||||
|
{
|
||||||
|
callbacks.on_install_pkgs = [this](const std::vector<std::string>& pkgs)
|
||||||
|
{
|
||||||
|
ensure(m_main_window);
|
||||||
|
ensure(!pkgs.empty());
|
||||||
|
QStringList pkg_list;
|
||||||
|
for (const std::string& pkg : pkgs)
|
||||||
|
{
|
||||||
|
pkg_list << QString::fromStdString(pkg);
|
||||||
|
}
|
||||||
|
return m_main_window->InstallPackages(pkg_list, true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Emu.SetCallbacks(std::move(callbacks));
|
Emu.SetCallbacks(std::move(callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -710,10 +710,12 @@ bool main_window::InstallFileInExData(const std::string& extension, const QStrin
|
||||||
return to.commit();
|
return to.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_window::InstallPackages(QStringList file_paths)
|
bool main_window::InstallPackages(QStringList file_paths, bool from_boot)
|
||||||
{
|
{
|
||||||
if (file_paths.isEmpty())
|
if (file_paths.isEmpty())
|
||||||
{
|
{
|
||||||
|
ensure(!from_boot);
|
||||||
|
|
||||||
// If this function was called without a path, ask the user for files to install.
|
// If this function was called without a path, ask the user for files to install.
|
||||||
const QString path_last_pkg = m_gui_settings->GetValue(gui::fd_install_pkg).toString();
|
const QString path_last_pkg = m_gui_settings->GetValue(gui::fd_install_pkg).toString();
|
||||||
const QStringList paths = QFileDialog::getOpenFileNames(this, tr("Select packages and/or rap files to install"),
|
const QStringList paths = QFileDialog::getOpenFileNames(this, tr("Select packages and/or rap files to install"),
|
||||||
|
@ -721,7 +723,7 @@ void main_window::InstallPackages(QStringList file_paths)
|
||||||
|
|
||||||
if (paths.isEmpty())
|
if (paths.isEmpty())
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_paths.append(paths);
|
file_paths.append(paths);
|
||||||
|
@ -739,7 +741,7 @@ void main_window::InstallPackages(QStringList file_paths)
|
||||||
if (!info.is_valid)
|
if (!info.is_valid)
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, tr("Invalid package!"), tr("The selected package is invalid!\n\nPath:\n%0").arg(file_path));
|
QMessageBox::warning(this, tr("Invalid package!"), tr("The selected package is invalid!\n\nPath:\n%0").arg(file_path));
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.type != compat::package_type::other)
|
if (info.type != compat::package_type::other)
|
||||||
|
@ -780,21 +782,10 @@ void main_window::InstallPackages(QStringList file_paths)
|
||||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
gui_log.notice("PKG: Cancelled installation from drop.\n%s", sstr(info_string));
|
gui_log.notice("PKG: Cancelled installation from drop.\n%s", sstr(info_string));
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_gui_settings->GetBootConfirmation(this))
|
|
||||||
{
|
|
||||||
// Last chance to cancel the operation
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Emu.IsStopped())
|
|
||||||
{
|
|
||||||
Emu.GracefulShutdown(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install rap files if available
|
// Install rap files if available
|
||||||
int installed_rap_and_edat_count = 0;
|
int installed_rap_and_edat_count = 0;
|
||||||
|
|
||||||
|
@ -818,8 +809,22 @@ void main_window::InstallPackages(QStringList file_paths)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!from_boot)
|
||||||
|
{
|
||||||
|
if (!m_gui_settings->GetBootConfirmation(this))
|
||||||
|
{
|
||||||
|
// Last chance to cancel the operation
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Emu.IsStopped())
|
||||||
|
{
|
||||||
|
Emu.GracefulShutdown(false);
|
||||||
|
}
|
||||||
|
|
||||||
install_filetype("rap");
|
install_filetype("rap");
|
||||||
install_filetype("edat");
|
install_filetype("edat");
|
||||||
|
}
|
||||||
|
|
||||||
if (installed_rap_and_edat_count > 0)
|
if (installed_rap_and_edat_count > 0)
|
||||||
{
|
{
|
||||||
|
@ -830,21 +835,30 @@ void main_window::InstallPackages(QStringList file_paths)
|
||||||
// Find remaining package files
|
// Find remaining package files
|
||||||
file_paths = file_paths.filter(QRegularExpression(".*\\.pkg", QRegularExpression::PatternOption::CaseInsensitiveOption));
|
file_paths = file_paths.filter(QRegularExpression(".*\\.pkg", QRegularExpression::PatternOption::CaseInsensitiveOption));
|
||||||
|
|
||||||
if (!file_paths.isEmpty())
|
if (file_paths.isEmpty())
|
||||||
{
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from_boot)
|
||||||
|
{
|
||||||
|
return HandlePackageInstallation(file_paths, true);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing.
|
// Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing.
|
||||||
QTimer::singleShot(0, [this, paths = std::move(file_paths)]()
|
QTimer::singleShot(0, [this, paths = std::move(file_paths)]()
|
||||||
{
|
{
|
||||||
HandlePackageInstallation(paths);
|
HandlePackageInstallation(paths, false);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_window::HandlePackageInstallation(QStringList file_paths)
|
bool main_window::HandlePackageInstallation(QStringList file_paths, bool from_boot)
|
||||||
{
|
{
|
||||||
if (file_paths.empty())
|
if (file_paths.empty())
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<compat::package_info> packages;
|
std::vector<compat::package_info> packages;
|
||||||
|
@ -868,15 +882,18 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||||
|
|
||||||
if (packages.empty())
|
if (packages.empty())
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!from_boot)
|
||||||
|
{
|
||||||
if (!m_gui_settings->GetBootConfirmation(this))
|
if (!m_gui_settings->GetBootConfirmation(this))
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Emu.GracefulShutdown(false);
|
Emu.GracefulShutdown(false);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> path_vec;
|
std::vector<std::string> path_vec;
|
||||||
for (const compat::package_info& pkg : packages)
|
for (const compat::package_info& pkg : packages)
|
||||||
|
@ -973,7 +990,9 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worker())
|
const bool success = worker();
|
||||||
|
|
||||||
|
if (success)
|
||||||
{
|
{
|
||||||
pdlg.SetValue(pdlg.maximum());
|
pdlg.SetValue(pdlg.maximum());
|
||||||
std::this_thread::sleep_for(100ms);
|
std::this_thread::sleep_for(100ms);
|
||||||
|
@ -1032,7 +1051,7 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||||
if (bootable_paths_installed.empty())
|
if (bootable_paths_installed.empty())
|
||||||
{
|
{
|
||||||
m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this);
|
m_gui_settings->ShowInfoBox(tr("Success!"), tr("Successfully installed software from package(s)!"), gui::ib_pkg_success, this);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dlg = new QDialog(this);
|
auto dlg = new QDialog(this);
|
||||||
|
@ -1144,6 +1163,8 @@ void main_window::HandlePackageInstallation(QStringList file_paths)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_window::ExtractMSELF()
|
void main_window::ExtractMSELF()
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
bool Init(bool with_cli_boot);
|
bool Init(bool with_cli_boot);
|
||||||
QIcon GetAppIcon() const;
|
QIcon GetAppIcon() const;
|
||||||
bool OnMissingFw();
|
bool OnMissingFw();
|
||||||
void InstallPackages(QStringList file_paths = QStringList());
|
bool InstallPackages(QStringList file_paths = {}, bool from_boot = false);
|
||||||
void InstallPup(QString file_path = "");
|
void InstallPup(QString file_path = "");
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
@ -149,7 +149,7 @@ private:
|
||||||
|
|
||||||
static bool InstallFileInExData(const std::string& extension, const QString& path, const std::string& filename);
|
static bool InstallFileInExData(const std::string& extension, const QString& path, const std::string& filename);
|
||||||
|
|
||||||
void HandlePackageInstallation(QStringList file_paths);
|
bool HandlePackageInstallation(QStringList file_paths, bool from_boot);
|
||||||
|
|
||||||
void HandlePupInstallation(const QString& file_path, const QString& dir_path = "");
|
void HandlePupInstallation(const QString& file_path, const QString& dir_path = "");
|
||||||
void ExtractPup();
|
void ExtractPup();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue