[qt_common] reorg, move more stuff out of main
Some checks failed
eden-license / license-header (pull_request) Failing after 30s
Some checks failed
eden-license / license-header (pull_request) Failing after 30s
Signed-off-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
parent
e5ca953f59
commit
d9cbb6f0a4
20 changed files with 923 additions and 680 deletions
|
@ -1,6 +1,7 @@
|
|||
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
|
||||
add_library(qt_common STATIC
|
||||
|
@ -18,11 +19,15 @@ add_library(qt_common STATIC
|
|||
qt_path_util.h qt_path_util.cpp
|
||||
qt_game_util.h qt_game_util.cpp
|
||||
qt_frontend_util.h qt_frontend_util.cpp
|
||||
qt_meta.h qt_meta.cpp
|
||||
qt_content_util.h qt_content_util.cpp
|
||||
qt_rom_util.h qt_rom_util.cpp
|
||||
)
|
||||
|
||||
create_target_directory_groups(qt_common)
|
||||
target_link_libraries(qt_common PUBLIC core Qt6::Widgets SimpleIni::SimpleIni QuaZip::QuaZip)
|
||||
target_link_libraries(qt_common PRIVATE Qt6::Core)
|
||||
target_link_libraries(qt_common PRIVATE Qt6::Core)
|
||||
|
||||
if (NOT WIN32)
|
||||
target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
|
|
|
@ -2,11 +2,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "qt_common.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "frontend_common/firmware_manager.h"
|
||||
#include "uisettings.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QStringLiteral>
|
||||
|
@ -16,7 +11,6 @@
|
|||
#include <QFile>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include "qt_frontend_util.h"
|
||||
|
||||
#include <JlCompress.h>
|
||||
|
||||
|
@ -27,19 +21,9 @@
|
|||
#endif
|
||||
|
||||
namespace QtCommon {
|
||||
MetadataResult ResetMetadata()
|
||||
{
|
||||
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir)
|
||||
/ "game_list/")) {
|
||||
return MetadataResult::Empty;
|
||||
} else if (Common::FS::RemoveDirRecursively(
|
||||
Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) {
|
||||
return MetadataResult::Success;
|
||||
UISettings::values.is_game_list_reload_pending.exchange(true);
|
||||
} else {
|
||||
return MetadataResult::Failure;
|
||||
}
|
||||
}
|
||||
|
||||
QObject *rootObject = nullptr;
|
||||
Core::System *system = nullptr;
|
||||
|
||||
Core::Frontend::WindowSystemType GetWindowSystemType()
|
||||
{
|
||||
|
@ -86,157 +70,14 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window)
|
|||
return wsi;
|
||||
}
|
||||
|
||||
FirmwareInstallResult InstallFirmware(
|
||||
const QString& location,
|
||||
bool recursive,
|
||||
std::function<bool(std::size_t, std::size_t)> QtProgressCallback,
|
||||
Core::System* system,
|
||||
FileSys::VfsFilesystem* vfs,
|
||||
QWidget* parent)
|
||||
const QString tr(const char* str)
|
||||
{
|
||||
static constexpr const char* failedTitle = "Firmware Install Failed";
|
||||
static constexpr const char* successTitle = "Firmware Install Failed";
|
||||
static constexpr QMessageBox::StandardButtons buttons = QMessageBox::Ok;
|
||||
|
||||
QMessageBox::Icon icon;
|
||||
FirmwareInstallResult result;
|
||||
|
||||
const auto ShowMessage = [&]() {
|
||||
QtCommon::Frontend::ShowMessage(icon,
|
||||
failedTitle,
|
||||
GetFirmwareInstallResultString(result),
|
||||
buttons,
|
||||
parent);
|
||||
};
|
||||
|
||||
LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString());
|
||||
|
||||
// Check for a reasonable number of .nca files (don't hardcode them, just see if there's some in
|
||||
// there.)
|
||||
std::filesystem::path firmware_source_path = location.toStdString();
|
||||
if (!Common::FS::IsDir(firmware_source_path)) {
|
||||
return FirmwareInstallResult::NoOp;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> out;
|
||||
const Common::FS::DirEntryCallable callback =
|
||||
[&out](const std::filesystem::directory_entry& entry) {
|
||||
if (entry.path().has_extension() && entry.path().extension() == ".nca") {
|
||||
out.emplace_back(entry.path());
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
QtProgressCallback(100, 10);
|
||||
|
||||
if (recursive) {
|
||||
Common::FS::IterateDirEntriesRecursively(firmware_source_path,
|
||||
callback,
|
||||
Common::FS::DirEntryFilter::File);
|
||||
} else {
|
||||
Common::FS::IterateDirEntries(firmware_source_path,
|
||||
callback,
|
||||
Common::FS::DirEntryFilter::File);
|
||||
}
|
||||
|
||||
if (out.size() <= 0) {
|
||||
result = FirmwareInstallResult::NoNCAs;
|
||||
icon = QMessageBox::Warning;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Locate and erase the content of nand/system/Content/registered/*.nca, if any.
|
||||
auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory();
|
||||
if (sysnand_content_vdir->IsWritable()
|
||||
&& !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
|
||||
result = FirmwareInstallResult::FailedDelete;
|
||||
icon = QMessageBox::Critical;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
LOG_INFO(Frontend,
|
||||
"Cleaned nand/system/Content/registered folder in preparation for new firmware.");
|
||||
|
||||
QtProgressCallback(100, 20);
|
||||
|
||||
auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered");
|
||||
|
||||
bool success = true;
|
||||
int i = 0;
|
||||
for (const auto& firmware_src_path : out) {
|
||||
i++;
|
||||
auto firmware_src_vfile = vfs->OpenFile(firmware_src_path.generic_string(),
|
||||
FileSys::OpenMode::Read);
|
||||
auto firmware_dst_vfile = firmware_vdir
|
||||
->CreateFileRelative(firmware_src_path.filename().string());
|
||||
|
||||
if (!VfsRawCopy(firmware_src_vfile, firmware_dst_vfile)) {
|
||||
LOG_ERROR(Frontend,
|
||||
"Failed to copy firmware file {} to {} in registered folder!",
|
||||
firmware_src_path.generic_string(),
|
||||
firmware_src_path.filename().string());
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (QtProgressCallback(100,
|
||||
20
|
||||
+ static_cast<int>(((i) / static_cast<float>(out.size()))
|
||||
* 70.0))) {
|
||||
result = FirmwareInstallResult::FailedCorrupted;
|
||||
icon = QMessageBox::Warning;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
result = FirmwareInstallResult::FailedCopy;
|
||||
icon = QMessageBox::Critical;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Re-scan VFS for the newly placed firmware files.
|
||||
system->GetFileSystemController().CreateFactories(*vfs);
|
||||
|
||||
const auto pair = FirmwareManager::GetFirmwareVersion(*system);
|
||||
const auto firmware_data = pair.first;
|
||||
const std::string display_version(firmware_data.display_version.data());
|
||||
|
||||
result = FirmwareInstallResult::Success;
|
||||
QtCommon::Frontend::ShowMessage(QMessageBox::Information,
|
||||
qApp->tr(successTitle),
|
||||
qApp->tr(GetFirmwareInstallResultString(result))
|
||||
.arg(QString::fromStdString(display_version)),
|
||||
buttons,
|
||||
parent);
|
||||
return result;
|
||||
return QGuiApplication::tr(str);
|
||||
}
|
||||
|
||||
QString UnzipFirmwareToTmp(const QString& location)
|
||||
const QString tr(const std::string& str)
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
fs::path tmp{fs::temp_directory_path()};
|
||||
|
||||
if (!fs::create_directories(tmp / "eden" / "firmware")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
tmp /= "eden";
|
||||
tmp /= "firmware";
|
||||
|
||||
QString qCacheDir = QString::fromStdString(tmp.string());
|
||||
|
||||
QFile zip(location);
|
||||
|
||||
QStringList result = JlCompress::extractDir(&zip, qCacheDir);
|
||||
if (result.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return qCacheDir;
|
||||
return QGuiApplication::tr(str.c_str());
|
||||
}
|
||||
|
||||
} // namespace QtCommon
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#ifndef QT_COMMON_H
|
||||
#define QT_COMMON_H
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <QWindow>
|
||||
#include "core/core.h"
|
||||
#include <core/frontend/emu_window.h>
|
||||
|
@ -13,68 +11,28 @@
|
|||
#include <core/file_sys/vfs/vfs_real.h>
|
||||
|
||||
namespace QtCommon {
|
||||
static constexpr std::array<const char *, 3> METADATA_RESULTS = {
|
||||
"The operation completed successfully.",
|
||||
"The metadata cache couldn't be deleted. It might be in use or non-existent.",
|
||||
"The metadata cache is already empty.",
|
||||
};
|
||||
|
||||
enum class MetadataResult {
|
||||
Success,
|
||||
Failure,
|
||||
Empty,
|
||||
};
|
||||
/**
|
||||
* @brief ResetMetadata Reset game list metadata.
|
||||
* @return A result code.
|
||||
*/
|
||||
MetadataResult ResetMetadata();
|
||||
extern QObject *rootObject;
|
||||
extern Core::System *system;
|
||||
|
||||
/**
|
||||
* \brief Get a string representation of a result from ResetMetadata.
|
||||
* \param result The result code.
|
||||
* \return A string representation of the passed result code.
|
||||
*/
|
||||
inline constexpr const char *GetResetMetadataResultString(MetadataResult result)
|
||||
{
|
||||
return METADATA_RESULTS.at(static_cast<std::size_t>(result));
|
||||
}
|
||||
|
||||
static constexpr std::array<const char *, 6> FIRMWARE_RESULTS
|
||||
= {"Successfully installed firmware version %1",
|
||||
"",
|
||||
"Unable to locate potential firmware NCA files",
|
||||
"Failed to delete one or more firmware files.",
|
||||
"One or more firmware files failed to copy into NAND.",
|
||||
"Firmware installation cancelled, firmware may be in a bad state or corrupted."
|
||||
"Restart Eden or re-install firmware."};
|
||||
|
||||
enum class FirmwareInstallResult {
|
||||
Success,
|
||||
NoOp,
|
||||
NoNCAs,
|
||||
FailedDelete,
|
||||
FailedCopy,
|
||||
FailedCorrupted,
|
||||
};
|
||||
|
||||
FirmwareInstallResult InstallFirmware(
|
||||
const QString &location,
|
||||
bool recursive,
|
||||
std::function<bool(std::size_t, std::size_t)> QtProgressCallback,
|
||||
Core::System *system,
|
||||
FileSys::VfsFilesystem *vfs,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
QString UnzipFirmwareToTmp(const QString &location);
|
||||
|
||||
inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result)
|
||||
{
|
||||
return FIRMWARE_RESULTS.at(static_cast<std::size_t>(result));
|
||||
}
|
||||
typedef std::function<bool(std::size_t, std::size_t)> QtProgressCallback;
|
||||
|
||||
Core::Frontend::WindowSystemType GetWindowSystemType();
|
||||
|
||||
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window);
|
||||
|
||||
static inline void SetRootObject(QObject *parent)
|
||||
{
|
||||
rootObject = parent;
|
||||
}
|
||||
|
||||
static inline void SetSystem(Core::System *newSystem)
|
||||
{
|
||||
system = newSystem;
|
||||
}
|
||||
|
||||
const QString tr(const char *str);
|
||||
const QString tr(const std::string &str);
|
||||
|
||||
} // namespace QtCommon
|
||||
#endif
|
||||
|
|
202
src/qt_common/qt_content_util.cpp
Normal file
202
src/qt_common/qt_content_util.cpp
Normal file
|
@ -0,0 +1,202 @@
|
|||
#include "qt_content_util.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include "frontend_common/firmware_manager.h"
|
||||
#include "qt_common/qt_game_util.h"
|
||||
#include "qt_frontend_util.h"
|
||||
|
||||
#include <JlCompress.h>
|
||||
|
||||
namespace QtCommon::Content {
|
||||
|
||||
bool CheckGameFirmware(u64 program_id, Core::System &system, QObject *parent)
|
||||
{
|
||||
if (FirmwareManager::GameRequiresFirmware(program_id)
|
||||
&& !FirmwareManager::CheckFirmwarePresence(system)) {
|
||||
auto result = QtCommon::Frontend::ShowMessage(
|
||||
QMessageBox::Warning,
|
||||
"Game Requires Firmware",
|
||||
"The game you are trying to launch requires firmware to boot or to get past the "
|
||||
"opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>"
|
||||
"dump and install firmware</a>, or press \"OK\" to launch anyways.",
|
||||
QMessageBox::Ok | QMessageBox::Cancel,
|
||||
parent);
|
||||
|
||||
return result == QMessageBox::Ok;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FirmwareInstallResult InstallFirmware(
|
||||
const QString& location,
|
||||
bool recursive,
|
||||
QtProgressCallback callback,
|
||||
FileSys::VfsFilesystem* vfs)
|
||||
{
|
||||
static constexpr const char* failedTitle = "Firmware Install Failed";
|
||||
static constexpr const char* successTitle = "Firmware Install Failed";
|
||||
static constexpr QMessageBox::StandardButtons buttons = QMessageBox::Ok;
|
||||
|
||||
QMessageBox::Icon icon;
|
||||
FirmwareInstallResult result;
|
||||
|
||||
const auto ShowMessage = [&]() {
|
||||
QtCommon::Frontend::ShowMessage(icon,
|
||||
failedTitle,
|
||||
GetFirmwareInstallResultString(result),
|
||||
buttons,
|
||||
rootObject);
|
||||
};
|
||||
|
||||
LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString());
|
||||
|
||||
// Check for a reasonable number of .nca files (don't hardcode them, just see if there's some in
|
||||
// there.)
|
||||
std::filesystem::path firmware_source_path = location.toStdString();
|
||||
if (!Common::FS::IsDir(firmware_source_path)) {
|
||||
return FirmwareInstallResult::NoOp;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> out;
|
||||
const Common::FS::DirEntryCallable dir_callback =
|
||||
[&out](const std::filesystem::directory_entry& entry) {
|
||||
if (entry.path().has_extension() && entry.path().extension() == ".nca") {
|
||||
out.emplace_back(entry.path());
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
callback(100, 10);
|
||||
|
||||
if (recursive) {
|
||||
Common::FS::IterateDirEntriesRecursively(firmware_source_path,
|
||||
dir_callback,
|
||||
Common::FS::DirEntryFilter::File);
|
||||
} else {
|
||||
Common::FS::IterateDirEntries(firmware_source_path,
|
||||
dir_callback,
|
||||
Common::FS::DirEntryFilter::File);
|
||||
}
|
||||
|
||||
if (out.size() <= 0) {
|
||||
result = FirmwareInstallResult::NoNCAs;
|
||||
icon = QMessageBox::Warning;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Locate and erase the content of nand/system/Content/registered/*.nca, if any.
|
||||
auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory();
|
||||
if (sysnand_content_vdir->IsWritable()
|
||||
&& !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
|
||||
result = FirmwareInstallResult::FailedDelete;
|
||||
icon = QMessageBox::Critical;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
LOG_INFO(Frontend,
|
||||
"Cleaned nand/system/Content/registered folder in preparation for new firmware.");
|
||||
|
||||
callback(100, 20);
|
||||
|
||||
auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered");
|
||||
|
||||
bool success = true;
|
||||
int i = 0;
|
||||
for (const auto& firmware_src_path : out) {
|
||||
i++;
|
||||
auto firmware_src_vfile = vfs->OpenFile(firmware_src_path.generic_string(),
|
||||
FileSys::OpenMode::Read);
|
||||
auto firmware_dst_vfile = firmware_vdir
|
||||
->CreateFileRelative(firmware_src_path.filename().string());
|
||||
|
||||
if (!VfsRawCopy(firmware_src_vfile, firmware_dst_vfile)) {
|
||||
LOG_ERROR(Frontend,
|
||||
"Failed to copy firmware file {} to {} in registered folder!",
|
||||
firmware_src_path.generic_string(),
|
||||
firmware_src_path.filename().string());
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (callback(100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) {
|
||||
result = FirmwareInstallResult::FailedCorrupted;
|
||||
icon = QMessageBox::Warning;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
result = FirmwareInstallResult::FailedCopy;
|
||||
icon = QMessageBox::Critical;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Re-scan VFS for the newly placed firmware files.
|
||||
system->GetFileSystemController().CreateFactories(*vfs);
|
||||
|
||||
const auto pair = FirmwareManager::GetFirmwareVersion(*system);
|
||||
const auto firmware_data = pair.first;
|
||||
const std::string display_version(firmware_data.display_version.data());
|
||||
|
||||
result = FirmwareInstallResult::Success;
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
tr(successTitle),
|
||||
tr(GetFirmwareInstallResultString(result))
|
||||
.arg(QString::fromStdString(display_version)),
|
||||
buttons);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString UnzipFirmwareToTmp(const QString& location)
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
fs::path tmp{fs::temp_directory_path()};
|
||||
|
||||
if (!fs::create_directories(tmp / "eden" / "firmware")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
tmp /= "eden";
|
||||
tmp /= "firmware";
|
||||
|
||||
QString qCacheDir = QString::fromStdString(tmp.string());
|
||||
|
||||
QFile zip(location);
|
||||
|
||||
QStringList result = JlCompress::extractDir(&zip, qCacheDir);
|
||||
if (result.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return qCacheDir;
|
||||
}
|
||||
|
||||
// Content //
|
||||
void VerifyGameContents(const std::string& game_path, QtProgressCallback callback) {
|
||||
const auto result = ContentManager::VerifyGameContents(*system, game_path, callback);
|
||||
|
||||
switch (result) {
|
||||
case ContentManager::GameVerificationResult::Success:
|
||||
QtCommon::Frontend::Information(rootObject, tr("Integrity verification succeeded!"),
|
||||
tr("The operation completed successfully."));
|
||||
break;
|
||||
case ContentManager::GameVerificationResult::Failed:
|
||||
QtCommon::Frontend::Critical(rootObject, tr("Integrity verification failed!"),
|
||||
tr("File contents may be corrupt or missing."));
|
||||
break;
|
||||
case ContentManager::GameVerificationResult::NotImplemented:
|
||||
QtCommon::Frontend::Warning(
|
||||
rootObject,
|
||||
tr("Integrity verification couldn't be performed"),
|
||||
tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. "
|
||||
"File contents could not be checked for validity."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
48
src/qt_common/qt_content_util.h
Normal file
48
src/qt_common/qt_content_util.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#ifndef QT_CONTENT_UTIL_H
|
||||
#define QT_CONTENT_UTIL_H
|
||||
|
||||
#include <QObject>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
#include "qt_common/qt_common.h"
|
||||
|
||||
namespace QtCommon::Content {
|
||||
|
||||
//
|
||||
bool CheckGameFirmware(u64 program_id, Core::System &system, QObject *parent);
|
||||
|
||||
static constexpr std::array<const char *, 6> FIRMWARE_RESULTS
|
||||
= {"Successfully installed firmware version %1",
|
||||
"",
|
||||
"Unable to locate potential firmware NCA files",
|
||||
"Failed to delete one or more firmware files.",
|
||||
"One or more firmware files failed to copy into NAND.",
|
||||
"Firmware installation cancelled, firmware may be in a bad state or corrupted."
|
||||
"Restart Eden or re-install firmware."};
|
||||
|
||||
enum class FirmwareInstallResult {
|
||||
Success,
|
||||
NoOp,
|
||||
NoNCAs,
|
||||
FailedDelete,
|
||||
FailedCopy,
|
||||
FailedCorrupted,
|
||||
};
|
||||
|
||||
FirmwareInstallResult InstallFirmware(
|
||||
const QString &location,
|
||||
bool recursive,
|
||||
QtProgressCallback callback,
|
||||
FileSys::VfsFilesystem *vfs);
|
||||
|
||||
QString UnzipFirmwareToTmp(const QString &location);
|
||||
|
||||
inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result)
|
||||
{
|
||||
return FIRMWARE_RESULTS.at(static_cast<std::size_t>(result));
|
||||
}
|
||||
|
||||
// Content //
|
||||
void VerifyGameContents(const std::string &game_path, QtProgressCallback callback);
|
||||
}
|
||||
#endif // QT_CONTENT_UTIL_H
|
|
@ -4,27 +4,84 @@
|
|||
#include "qt_frontend_util.h"
|
||||
|
||||
namespace QtCommon::Frontend {
|
||||
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QWidget *parent)
|
||||
QObject *parent)
|
||||
{
|
||||
#ifdef YUZU_QT_WIDGETS
|
||||
QMessageBox *box = new QMessageBox(icon, title, text, buttons, parent);
|
||||
QMessageBox *box = new QMessageBox(icon, title, text, buttons, (QWidget *) parent);
|
||||
return static_cast<QMessageBox::StandardButton>(box->exec());
|
||||
#endif
|
||||
// TODO(crueter): If Qt Widgets is disabled...
|
||||
// need a way to reference icon/buttons too
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QWidget *parent)
|
||||
QMessageBox::StandardButton Information(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(icon, qApp->tr(title), qApp->tr(text), buttons, parent);
|
||||
return ShowMessage(QMessageBox::Information, title, text, buttons, parent);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton Warning(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(QMessageBox::Warning, title, text, buttons, parent);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton Critical(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(QMessageBox::Critical, title, text, buttons, parent);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton Question(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(QMessageBox::Question, title, text, buttons, parent);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton Information(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(QMessageBox::Information, parent->tr(title), parent->tr(text), buttons, parent);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton Warning(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(QMessageBox::Warning, parent->tr(title), parent->tr(text), buttons, parent);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton Critical(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(QMessageBox::Critical, parent->tr(title), parent->tr(text), buttons, parent);
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton Question(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons)
|
||||
{
|
||||
return ShowMessage(QMessageBox::Question, parent->tr(title), parent->tr(text), buttons, parent);
|
||||
}
|
||||
|
||||
|
||||
} // namespace QtCommon::Frontend
|
||||
|
|
|
@ -17,16 +17,52 @@
|
|||
namespace QtCommon::Frontend {
|
||||
Q_NAMESPACE
|
||||
|
||||
// TODO(crueter) widgets-less impl, choices et al.
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
|
||||
QWidget *parent = nullptr);
|
||||
QObject *parent = nullptr);
|
||||
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
QMessageBox::StandardButton Information(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
QMessageBox::StandardButton Warning(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
QMessageBox::StandardButton Critical(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
QMessageBox::StandardButton Question(QObject *parent,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
QMessageBox::StandardButton Information(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
|
||||
QWidget *parent = nullptr);
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
QMessageBox::StandardButton Warning(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
QMessageBox::StandardButton Critical(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
QMessageBox::StandardButton Question(QObject *parent,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok);
|
||||
|
||||
} // namespace QtCommon::Frontend
|
||||
#endif // QT_FRONTEND_UTIL_H
|
||||
|
|
|
@ -4,40 +4,50 @@
|
|||
#include "qt_game_util.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include "qt_common.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "qt_frontend_util.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <shlobj.h>
|
||||
#include <windows.h>
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/string_util.h"
|
||||
#include <shlobj.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include "fmt/ostream.h"
|
||||
#include <fstream>
|
||||
#include "fmt/ostream.h"
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
namespace QtCommon {
|
||||
namespace QtCommon::Game {
|
||||
|
||||
bool CreateShortcutLink(const std::filesystem::path& shortcut_path,
|
||||
const std::string& comment,
|
||||
const std::filesystem::path& icon_path,
|
||||
const std::filesystem::path& command,
|
||||
const std::string& arguments, const std::string& categories,
|
||||
const std::string& keywords, const std::string& name) try {
|
||||
const std::string& comment,
|
||||
const std::filesystem::path& icon_path,
|
||||
const std::filesystem::path& command,
|
||||
const std::string& arguments,
|
||||
const std::string& categories,
|
||||
const std::string& keywords,
|
||||
const std::string& name)
|
||||
try {
|
||||
#ifdef _WIN32 // Windows
|
||||
HRESULT hr = CoInitialize(nullptr);
|
||||
if (FAILED(hr)) {
|
||||
LOG_ERROR(Frontend, "CoInitialize failed");
|
||||
return false;
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
SCOPE_EXIT
|
||||
{
|
||||
CoUninitialize();
|
||||
};
|
||||
IShellLinkW* ps1 = nullptr;
|
||||
IPersistFile* persist_file = nullptr;
|
||||
SCOPE_EXIT {
|
||||
SCOPE_EXIT
|
||||
{
|
||||
if (persist_file != nullptr) {
|
||||
persist_file->Release();
|
||||
}
|
||||
|
@ -45,7 +55,10 @@ bool CreateShortcutLink(const std::filesystem::path& shortcut_path,
|
|||
ps1->Release();
|
||||
}
|
||||
};
|
||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
|
||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IShellLinkW,
|
||||
reinterpret_cast<void**>(&ps1));
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to create IShellLinkW instance");
|
||||
|
@ -115,17 +128,18 @@ bool CreateShortcutLink(const std::filesystem::path& shortcut_path,
|
|||
fmt::print(shortcut_stream, "Keywords={}\n", keywords);
|
||||
}
|
||||
return true;
|
||||
#else // Unsupported platform
|
||||
#else // Unsupported platform
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
} catch (const std::exception& e) {
|
||||
LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
|
||||
std::filesystem::path& out_icon_path) {
|
||||
bool MakeShortcutIcoPath(const u64 program_id,
|
||||
const std::string_view game_file_name,
|
||||
std::filesystem::path& out_icon_path)
|
||||
{
|
||||
// Get path to Yuzu icons directory & icon extension
|
||||
std::string ico_extension = "png";
|
||||
#if defined(_WIN32)
|
||||
|
@ -146,12 +160,13 @@ bool MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_
|
|||
return true;
|
||||
}
|
||||
|
||||
void OpenEdenFolder(const Common::FS::EdenPath& path) {
|
||||
QDesktopServices::openUrl(QUrl(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(path))));
|
||||
void OpenEdenFolder(const Common::FS::EdenPath& path)
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl(QString::fromStdString(Common::FS::GetEdenPathString(path))));
|
||||
}
|
||||
|
||||
void OpenRootDataFolder() {
|
||||
void OpenRootDataFolder()
|
||||
{
|
||||
OpenEdenFolder(Common::FS::EdenPath::EdenDir);
|
||||
}
|
||||
|
||||
|
@ -175,4 +190,211 @@ void OpenLogFolder()
|
|||
OpenEdenFolder(Common::FS::EdenPath::LogDir);
|
||||
}
|
||||
|
||||
static QString GetGameListErrorRemoving(QtCommon::Game::InstalledEntryType type)
|
||||
{
|
||||
switch (type) {
|
||||
case QtCommon::Game::InstalledEntryType::Game:
|
||||
return tr("Error Removing Contents");
|
||||
case QtCommon::Game::InstalledEntryType::Update:
|
||||
return tr("Error Removing Update");
|
||||
case QtCommon::Game::InstalledEntryType::AddOnContent:
|
||||
return tr("Error Removing DLC");
|
||||
default:
|
||||
return QStringLiteral("Error Removing <Invalid Type>");
|
||||
}
|
||||
}
|
||||
|
||||
// Game Content //
|
||||
void RemoveBaseContent(u64 program_id, InstalledEntryType type)
|
||||
{
|
||||
const auto res = ContentManager::RemoveBaseContent(system->GetFileSystemController(),
|
||||
program_id);
|
||||
if (res) {
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
"Successfully Removed",
|
||||
"Successfully removed the installed base game.");
|
||||
} else {
|
||||
QtCommon::Frontend::Warning(
|
||||
rootObject,
|
||||
GetGameListErrorRemoving(type),
|
||||
tr("The base game is not installed in the NAND and cannot be removed."));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveUpdateContent(u64 program_id, InstalledEntryType type)
|
||||
{
|
||||
const auto res = ContentManager::RemoveUpdate(system->GetFileSystemController(), program_id);
|
||||
if (res) {
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
"Successfully Removed",
|
||||
"Successfully removed the installed update.");
|
||||
} else {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
GetGameListErrorRemoving(type),
|
||||
tr("There is no update installed for this title."));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveAddOnContent(u64 program_id, InstalledEntryType type)
|
||||
{
|
||||
const size_t count = ContentManager::RemoveAllDLC(*system, program_id);
|
||||
if (count == 0) {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
GetGameListErrorRemoving(type),
|
||||
tr("There are no DLCs installed for this title."));
|
||||
return;
|
||||
}
|
||||
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
tr("Successfully Removed"),
|
||||
tr("Successfully removed %1 installed DLC.").arg(count));
|
||||
}
|
||||
|
||||
// Global Content //
|
||||
|
||||
void RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target)
|
||||
{
|
||||
const auto target_file_name = [target] {
|
||||
switch (target) {
|
||||
case GameListRemoveTarget::GlShaderCache:
|
||||
return "opengl.bin";
|
||||
case GameListRemoveTarget::VkShaderCache:
|
||||
return "vulkan.bin";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}();
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id);
|
||||
const auto target_file = shader_cache_folder_path / target_file_name;
|
||||
|
||||
if (!Common::FS::Exists(target_file)) {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
tr("Error Removing Transferable Shader Cache"),
|
||||
tr("A shader cache for this title does not exist."));
|
||||
return;
|
||||
}
|
||||
if (Common::FS::RemoveFile(target_file)) {
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
tr("Successfully Removed"),
|
||||
tr("Successfully removed the transferable shader cache."));
|
||||
} else {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
tr("Error Removing Transferable Shader Cache"),
|
||||
tr("Failed to remove the transferable shader cache."));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveVulkanDriverPipelineCache(u64 program_id)
|
||||
{
|
||||
static constexpr std::string_view target_file_name = "vulkan_pipelines.bin";
|
||||
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id);
|
||||
const auto target_file = shader_cache_folder_path / target_file_name;
|
||||
|
||||
if (!Common::FS::Exists(target_file)) {
|
||||
return;
|
||||
}
|
||||
if (!Common::FS::RemoveFile(target_file)) {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
tr("Error Removing Vulkan Driver Pipeline Cache"),
|
||||
tr("Failed to remove the driver pipeline cache."));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveAllTransferableShaderCaches(u64 program_id)
|
||||
{
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto program_shader_cache_dir = shader_cache_dir / fmt::format("{:016x}", program_id);
|
||||
|
||||
if (!Common::FS::Exists(program_shader_cache_dir)) {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
tr("Error Removing Transferable Shader Caches"),
|
||||
tr("A shader cache for this title does not exist."));
|
||||
return;
|
||||
}
|
||||
if (Common::FS::RemoveDirRecursively(program_shader_cache_dir)) {
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
tr("Successfully Removed"),
|
||||
tr("Successfully removed the transferable shader caches."));
|
||||
} else {
|
||||
QtCommon::Frontend::Warning(
|
||||
rootObject,
|
||||
tr("Error Removing Transferable Shader Caches"),
|
||||
tr("Failed to remove the transferable shader cache directory."));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveCustomConfiguration(u64 program_id, const std::string& game_path)
|
||||
{
|
||||
const auto file_path = std::filesystem::path(Common::FS::ToU8String(game_path));
|
||||
const auto config_file_name = program_id == 0
|
||||
? Common::FS::PathToUTF8String(file_path.filename())
|
||||
.append(".ini")
|
||||
: fmt::format("{:016X}.ini", program_id);
|
||||
const auto custom_config_file_path = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir)
|
||||
/ "custom" / config_file_name;
|
||||
|
||||
if (!Common::FS::Exists(custom_config_file_path)) {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
tr("Error Removing Custom Configuration"),
|
||||
tr("A custom configuration for this title does not exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Common::FS::RemoveFile(custom_config_file_path)) {
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
tr("Successfully Removed"),
|
||||
tr("Successfully removed the custom game configuration."));
|
||||
} else {
|
||||
QtCommon::Frontend::Warning(rootObject,
|
||||
tr("Error Removing Custom Configuration"),
|
||||
tr("Failed to remove the custom game configuration."));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveCacheStorage(u64 program_id, FileSys::VfsFilesystem* vfs)
|
||||
{
|
||||
const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir);
|
||||
auto vfs_nand_dir = vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir),
|
||||
FileSys::OpenMode::Read);
|
||||
|
||||
const auto cache_storage_path
|
||||
= FileSys::SaveDataFactory::GetFullPath({},
|
||||
vfs_nand_dir,
|
||||
FileSys::SaveDataSpaceId::User,
|
||||
FileSys::SaveDataType::Cache,
|
||||
0 /* program_id */,
|
||||
{},
|
||||
0);
|
||||
|
||||
const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path);
|
||||
|
||||
// Not an error if it wasn't cleared.
|
||||
Common::FS::RemoveDirRecursively(path);
|
||||
}
|
||||
|
||||
// Metadata //
|
||||
void ResetMetadata()
|
||||
{
|
||||
const QString title = tr("Reset Metadata Cache");
|
||||
|
||||
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir)
|
||||
/ "game_list/")) {
|
||||
QtCommon::Frontend::Warning(rootObject, title, tr("The metadata cache is already empty."));
|
||||
} else if (Common::FS::RemoveDirRecursively(
|
||||
Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) {
|
||||
QtCommon::Frontend::Information(rootObject,
|
||||
title,
|
||||
tr("The operation completed successfully."));
|
||||
UISettings::values.is_game_list_reload_pending.exchange(true);
|
||||
} else {
|
||||
QtCommon::Frontend::Warning(
|
||||
rootObject,
|
||||
title,
|
||||
tr("The metadata cache couldn't be deleted. It might be in use or non-existent."));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QtCommon::Game
|
||||
|
|
|
@ -4,23 +4,25 @@
|
|||
#ifndef QT_GAME_UTIL_H
|
||||
#define QT_GAME_UTIL_H
|
||||
|
||||
#include <QObject>
|
||||
#include "common/fs/path_util.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include <array>
|
||||
#include <core/file_sys/vfs/vfs.h>
|
||||
|
||||
namespace QtCommon {
|
||||
namespace QtCommon::Game {
|
||||
|
||||
static constexpr std::array<const char *, 3> GAME_VERIFICATION_RESULTS = {
|
||||
"The operation completed successfully.",
|
||||
"File contents may be corrupt or missing..",
|
||||
"Firmware installation cancelled, firmware may be in a bad state or corrupted. "
|
||||
"File contents could not be checked for validity."
|
||||
enum class InstalledEntryType {
|
||||
Game,
|
||||
Update,
|
||||
AddOnContent,
|
||||
};
|
||||
|
||||
inline constexpr const char *GetGameVerificationResultString(ContentManager::GameVerificationResult result)
|
||||
{
|
||||
return GAME_VERIFICATION_RESULTS.at(static_cast<std::size_t>(result));
|
||||
}
|
||||
enum class GameListRemoveTarget {
|
||||
GlShaderCache,
|
||||
VkShaderCache,
|
||||
AllShaderCache,
|
||||
CustomConfiguration,
|
||||
CacheStorage,
|
||||
};
|
||||
|
||||
bool CreateShortcutLink(const std::filesystem::path& shortcut_path,
|
||||
const std::string& comment,
|
||||
|
@ -41,6 +43,20 @@ void OpenNANDFolder();
|
|||
void OpenSDMCFolder();
|
||||
void OpenModFolder();
|
||||
void OpenLogFolder();
|
||||
|
||||
void RemoveBaseContent(u64 program_id, InstalledEntryType type);
|
||||
void RemoveUpdateContent(u64 program_id, InstalledEntryType type);
|
||||
void RemoveAddOnContent(u64 program_id, InstalledEntryType type);
|
||||
|
||||
void RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target);
|
||||
void RemoveVulkanDriverPipelineCache(u64 program_id);
|
||||
void RemoveAllTransferableShaderCaches(u64 program_id);
|
||||
void RemoveCustomConfiguration(u64 program_id, const std::string& game_path);
|
||||
void RemoveCacheStorage(u64 program_id, FileSys::VfsFilesystem* vfs);
|
||||
|
||||
// Metadata //
|
||||
void ResetMetadata();
|
||||
|
||||
}
|
||||
|
||||
#endif // QT_GAME_UTIL_H
|
||||
|
|
72
src/qt_common/qt_meta.cpp
Normal file
72
src/qt_common/qt_meta.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "qt_meta.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/applets/cabinet.h"
|
||||
#include "core/frontend/applets/controller.h"
|
||||
#include "core/frontend/applets/profile_select.h"
|
||||
#include "core/frontend/applets/software_keyboard.h"
|
||||
#include "core/hle/service/am/frontend/applet_web_browser_types.h"
|
||||
|
||||
namespace QtCommon::Meta {
|
||||
|
||||
void RegisterMetaTypes()
|
||||
{
|
||||
// Register integral and floating point types
|
||||
qRegisterMetaType<u8>("u8");
|
||||
qRegisterMetaType<u16>("u16");
|
||||
qRegisterMetaType<u32>("u32");
|
||||
qRegisterMetaType<u64>("u64");
|
||||
qRegisterMetaType<u128>("u128");
|
||||
qRegisterMetaType<s8>("s8");
|
||||
qRegisterMetaType<s16>("s16");
|
||||
qRegisterMetaType<s32>("s32");
|
||||
qRegisterMetaType<s64>("s64");
|
||||
qRegisterMetaType<f32>("f32");
|
||||
qRegisterMetaType<f64>("f64");
|
||||
|
||||
// Register string types
|
||||
qRegisterMetaType<std::string>("std::string");
|
||||
qRegisterMetaType<std::wstring>("std::wstring");
|
||||
qRegisterMetaType<std::u8string>("std::u8string");
|
||||
qRegisterMetaType<std::u16string>("std::u16string");
|
||||
qRegisterMetaType<std::u32string>("std::u32string");
|
||||
qRegisterMetaType<std::string_view>("std::string_view");
|
||||
qRegisterMetaType<std::wstring_view>("std::wstring_view");
|
||||
qRegisterMetaType<std::u8string_view>("std::u8string_view");
|
||||
qRegisterMetaType<std::u16string_view>("std::u16string_view");
|
||||
qRegisterMetaType<std::u32string_view>("std::u32string_view");
|
||||
|
||||
// Register applet types
|
||||
|
||||
// Cabinet Applet
|
||||
qRegisterMetaType<Core::Frontend::CabinetParameters>("Core::Frontend::CabinetParameters");
|
||||
qRegisterMetaType<std::shared_ptr<Service::NFC::NfcDevice>>(
|
||||
"std::shared_ptr<Service::NFC::NfcDevice>");
|
||||
|
||||
// Controller Applet
|
||||
qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
|
||||
|
||||
// Profile Select Applet
|
||||
qRegisterMetaType<Core::Frontend::ProfileSelectParameters>(
|
||||
"Core::Frontend::ProfileSelectParameters");
|
||||
|
||||
// Software Keyboard Applet
|
||||
qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>(
|
||||
"Core::Frontend::KeyboardInitializeParameters");
|
||||
qRegisterMetaType<Core::Frontend::InlineAppearParameters>(
|
||||
"Core::Frontend::InlineAppearParameters");
|
||||
qRegisterMetaType<Core::Frontend::InlineTextParameters>("Core::Frontend::InlineTextParameters");
|
||||
qRegisterMetaType<Service::AM::Frontend::SwkbdResult>("Service::AM::Frontend::SwkbdResult");
|
||||
qRegisterMetaType<Service::AM::Frontend::SwkbdTextCheckResult>(
|
||||
"Service::AM::Frontend::SwkbdTextCheckResult");
|
||||
qRegisterMetaType<Service::AM::Frontend::SwkbdReplyType>(
|
||||
"Service::AM::Frontend::SwkbdReplyType");
|
||||
|
||||
// Web Browser Applet
|
||||
qRegisterMetaType<Service::AM::Frontend::WebExitReason>("Service::AM::Frontend::WebExitReason");
|
||||
|
||||
// Register loader types
|
||||
qRegisterMetaType<Core::SystemResultStatus>("Core::SystemResultStatus");
|
||||
}
|
||||
|
||||
}
|
12
src/qt_common/qt_meta.h
Normal file
12
src/qt_common/qt_meta.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef QT_META_H
|
||||
#define QT_META_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace QtCommon::Meta {
|
||||
|
||||
//
|
||||
void RegisterMetaTypes();
|
||||
|
||||
}
|
||||
#endif // QT_META_H
|
|
@ -7,17 +7,22 @@
|
|||
#include <QUrl>
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "qt_common/qt_frontend_util.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
bool QtCommon::PathUtil::OpenShaderCache(u64 program_id)
|
||||
namespace QtCommon::Path {
|
||||
|
||||
bool OpenShaderCache(u64 program_id, QObject *parent)
|
||||
{
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
|
||||
if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
|
||||
return false;
|
||||
QtCommon::Frontend::ShowMessage(QMessageBox::Warning, "Error Opening Shader Cache", "Failed to create or open shader cache for this title, ensure your app data directory has write permissions.", QMessageBox::Ok, parent);
|
||||
}
|
||||
|
||||
const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
|
||||
const auto qt_shader_cache_path = QString::fromStdString(shader_path_string);
|
||||
return QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#define QT_PATH_UTIL_H
|
||||
|
||||
#include "common/common_types.h"
|
||||
namespace QtCommon::PathUtil { bool OpenShaderCache(u64 program_id); }
|
||||
#include <QObject>
|
||||
|
||||
namespace QtCommon::Path { bool OpenShaderCache(u64 program_id, QObject *parent); }
|
||||
|
||||
#endif // QT_PATH_UTIL_H
|
||||
|
|
75
src/qt_common/qt_rom_util.cpp
Normal file
75
src/qt_common/qt_rom_util.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "qt_rom_util.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace QtCommon::ROM {
|
||||
|
||||
bool RomFSRawCopy(size_t total_size,
|
||||
size_t& read_size,
|
||||
QtProgressCallback callback,
|
||||
const FileSys::VirtualDir& src,
|
||||
const FileSys::VirtualDir& dest,
|
||||
bool full)
|
||||
{
|
||||
// TODO(crueter)
|
||||
// if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable())
|
||||
// return false;
|
||||
// if (dialog.wasCanceled())
|
||||
// return false;
|
||||
|
||||
// std::vector<u8> buffer(CopyBufferSize);
|
||||
// auto last_timestamp = std::chrono::steady_clock::now();
|
||||
|
||||
// const auto QtRawCopy = [&](const FileSys::VirtualFile& src_file,
|
||||
// const FileSys::VirtualFile& dest_file) {
|
||||
// if (src_file == nullptr || dest_file == nullptr) {
|
||||
// return false;
|
||||
// }
|
||||
// if (!dest_file->Resize(src_file->GetSize())) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// for (std::size_t i = 0; i < src_file->GetSize(); i += buffer.size()) {
|
||||
// if (dialog.wasCanceled()) {
|
||||
// dest_file->Resize(0);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// using namespace std::literals::chrono_literals;
|
||||
// const auto new_timestamp = std::chrono::steady_clock::now();
|
||||
|
||||
// if ((new_timestamp - last_timestamp) > 33ms) {
|
||||
// last_timestamp = new_timestamp;
|
||||
// dialog.setValue(
|
||||
// static_cast<int>(std::min(read_size, total_size) * 100 / total_size));
|
||||
// QCoreApplication::processEvents();
|
||||
// }
|
||||
|
||||
// const auto read = src_file->Read(buffer.data(), buffer.size(), i);
|
||||
// dest_file->Write(buffer.data(), read, i);
|
||||
|
||||
// read_size += read;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
// };
|
||||
|
||||
// if (full) {
|
||||
// for (const auto& file : src->GetFiles()) {
|
||||
// const auto out = VfsDirectoryCreateFileWrapper(dest, file->GetName());
|
||||
// if (!QtRawCopy(file, out))
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (const auto& dir : src->GetSubdirectories()) {
|
||||
// const auto out = dest->CreateSubdirectory(dir->GetName());
|
||||
// if (!RomFSRawCopy(total_size, read_size, dialog, dir, out, full))
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
17
src/qt_common/qt_rom_util.h
Normal file
17
src/qt_common/qt_rom_util.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef QT_ROM_UTIL_H
|
||||
#define QT_ROM_UTIL_H
|
||||
|
||||
#include "qt_common/qt_common.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace QtCommon::ROM {
|
||||
|
||||
bool RomFSRawCopy(size_t total_size,
|
||||
size_t& read_size,
|
||||
QtProgressCallback callback,
|
||||
const FileSys::VirtualDir& src,
|
||||
const FileSys::VirtualDir& dest,
|
||||
bool full);
|
||||
|
||||
}
|
||||
#endif // QT_ROM_UTIL_H
|
|
@ -11,6 +11,7 @@
|
|||
#include "common/fs/path_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "qt_common/qt_common.h"
|
||||
#include "qt_common/qt_game_util.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "ui_configure_filesystem.h"
|
||||
|
||||
|
@ -130,17 +131,7 @@ void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit)
|
|||
}
|
||||
|
||||
void ConfigureFilesystem::ResetMetadata() {
|
||||
auto result = QtCommon::ResetMetadata();
|
||||
const QString resultMessage = tr(QtCommon::GetResetMetadataResultString(result));
|
||||
const QString title = tr("Reset Metadata Cache");
|
||||
|
||||
switch (result) {
|
||||
case QtCommon::MetadataResult::Failure:
|
||||
QMessageBox::warning(this, title, resultMessage);
|
||||
break;
|
||||
default:
|
||||
QMessageBox::information(this, title, resultMessage);
|
||||
}
|
||||
QtCommon::Game::ResetMetadata();
|
||||
}
|
||||
|
||||
void ConfigureFilesystem::UpdateEnabledControls() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <regex>
|
||||
#include "yuzu/game_list.h"
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
@ -13,19 +13,20 @@
|
|||
#include <QMenu>
|
||||
#include <QThreadPool>
|
||||
#include <QToolButton>
|
||||
#include <fmt/ranges.h>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "qt_common/qt_game_util.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/compatibility_list.h"
|
||||
#include "yuzu/game_list.h"
|
||||
#include "yuzu/game_list_p.h"
|
||||
#include "yuzu/game_list_worker.h"
|
||||
#include "yuzu/main.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/controller_navigation.h"
|
||||
#include <fmt/ranges.h>
|
||||
#include <regex>
|
||||
|
||||
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent)
|
||||
: QObject(parent), gamelist{gamelist_} {}
|
||||
|
@ -608,30 +609,30 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
|
|||
connect(open_transferable_shader_cache, &QAction::triggered,
|
||||
[this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); });
|
||||
connect(remove_all_content, &QAction::triggered, [this, program_id]() {
|
||||
emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::Game);
|
||||
emit RemoveInstalledEntryRequested(program_id, QtCommon::Game::InstalledEntryType::Game);
|
||||
});
|
||||
connect(remove_update, &QAction::triggered, [this, program_id]() {
|
||||
emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::Update);
|
||||
emit RemoveInstalledEntryRequested(program_id, QtCommon::Game::InstalledEntryType::Update);
|
||||
});
|
||||
connect(remove_dlc, &QAction::triggered, [this, program_id]() {
|
||||
emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::AddOnContent);
|
||||
emit RemoveInstalledEntryRequested(program_id, QtCommon::Game::InstalledEntryType::AddOnContent);
|
||||
});
|
||||
connect(remove_gl_shader_cache, &QAction::triggered, [this, program_id, path]() {
|
||||
emit RemoveFileRequested(program_id, GameListRemoveTarget::GlShaderCache, path);
|
||||
emit RemoveFileRequested(program_id, QtCommon::Game::GameListRemoveTarget::GlShaderCache, path);
|
||||
});
|
||||
connect(remove_vk_shader_cache, &QAction::triggered, [this, program_id, path]() {
|
||||
emit RemoveFileRequested(program_id, GameListRemoveTarget::VkShaderCache, path);
|
||||
emit RemoveFileRequested(program_id, QtCommon::Game::GameListRemoveTarget::VkShaderCache, path);
|
||||
});
|
||||
connect(remove_shader_cache, &QAction::triggered, [this, program_id, path]() {
|
||||
emit RemoveFileRequested(program_id, GameListRemoveTarget::AllShaderCache, path);
|
||||
emit RemoveFileRequested(program_id, QtCommon::Game::GameListRemoveTarget::AllShaderCache, path);
|
||||
});
|
||||
connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() {
|
||||
emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path);
|
||||
emit RemoveFileRequested(program_id, QtCommon::Game::GameListRemoveTarget::CustomConfiguration, path);
|
||||
});
|
||||
connect(remove_play_time_data, &QAction::triggered,
|
||||
[this, program_id]() { emit RemovePlayTimeRequested(program_id); });
|
||||
connect(remove_cache_storage, &QAction::triggered, [this, program_id, path] {
|
||||
emit RemoveFileRequested(program_id, GameListRemoveTarget::CacheStorage, path);
|
||||
emit RemoveFileRequested(program_id, QtCommon::Game::GameListRemoveTarget::CacheStorage, path);
|
||||
});
|
||||
connect(dump_romfs, &QAction::triggered, [this, program_id, path]() {
|
||||
emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::Normal);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "qt_common/qt_game_util.h"
|
||||
#include "yuzu/compatibility_list.h"
|
||||
#include "yuzu/play_time_manager.h"
|
||||
|
||||
|
@ -46,14 +47,6 @@ enum class GameListOpenTarget {
|
|||
ModData,
|
||||
};
|
||||
|
||||
enum class GameListRemoveTarget {
|
||||
GlShaderCache,
|
||||
VkShaderCache,
|
||||
AllShaderCache,
|
||||
CustomConfiguration,
|
||||
CacheStorage,
|
||||
};
|
||||
|
||||
enum class DumpRomFSTarget {
|
||||
Normal,
|
||||
SDMC,
|
||||
|
@ -64,12 +57,6 @@ enum class GameListShortcutTarget {
|
|||
Applications,
|
||||
};
|
||||
|
||||
enum class InstalledEntryType {
|
||||
Game,
|
||||
Update,
|
||||
AddOnContent,
|
||||
};
|
||||
|
||||
class GameList : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -118,8 +105,8 @@ signals:
|
|||
void OpenFolderRequested(u64 program_id, GameListOpenTarget target,
|
||||
const std::string& game_path);
|
||||
void OpenTransferableShaderCacheRequested(u64 program_id);
|
||||
void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type);
|
||||
void RemoveFileRequested(u64 program_id, GameListRemoveTarget target,
|
||||
void RemoveInstalledEntryRequested(u64 program_id, QtCommon::Game::InstalledEntryType type);
|
||||
void RemoveFileRequested(u64 program_id, QtCommon::Game::GameListRemoveTarget target,
|
||||
const std::string& game_path);
|
||||
void RemovePlayTimeRequested(u64 program_id);
|
||||
void DumpRomFSRequested(u64 program_id, const std::string& game_path, DumpRomFSTarget target);
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "qt_common/qt_common.h"
|
||||
#include "qt_common/qt_game_util.h"
|
||||
#include "qt_common/qt_path_util.h"
|
||||
#include "qt_common/qt_meta.h"
|
||||
#include "qt_common/qt_content_util.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h> // for chdir
|
||||
|
@ -297,14 +299,6 @@ enum class CalloutFlag : uint32_t {
|
|||
DRDDeprecation = 0x2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Some games perform worse or straight-up don't work with updates,
|
||||
* so this tracks which games are bad in this regard.
|
||||
*/
|
||||
constexpr std::array<u64, 1> bad_update_games{
|
||||
0x0100F2C0115B6000 // Tears of the Kingdom
|
||||
};
|
||||
|
||||
const int GMainWindow::max_recent_files_item;
|
||||
|
||||
static void RemoveCachedContents() {
|
||||
|
@ -386,6 +380,7 @@ static void OverrideWindowsFont() {
|
|||
}
|
||||
#endif
|
||||
|
||||
// TODO(crueter): carboxyl does this, is it needed in qml?
|
||||
inline static bool isDarkMode() {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||
const auto scheme = QGuiApplication::styleHints()->colorScheme();
|
||||
|
@ -403,6 +398,9 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
|
|||
input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, user_data_migrator{this},
|
||||
vfs{std::make_shared<FileSys::RealVfsFilesystem>()},
|
||||
provider{std::make_unique<FileSys::ManualContentProvider>()} {
|
||||
QtCommon::SetSystem(system.get());
|
||||
QtCommon::SetRootObject(this);
|
||||
|
||||
Common::FS::CreateEdenPaths();
|
||||
this->config = std::make_unique<QtConfig>();
|
||||
|
||||
|
@ -459,7 +457,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
|
|||
|
||||
Network::Init();
|
||||
|
||||
RegisterMetaTypes();
|
||||
QtCommon::Meta::RegisterMetaTypes();
|
||||
|
||||
InitializeWidgets();
|
||||
InitializeDebugWidgets();
|
||||
|
@ -730,65 +728,6 @@ GMainWindow::~GMainWindow() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void GMainWindow::RegisterMetaTypes() {
|
||||
// Register integral and floating point types
|
||||
qRegisterMetaType<u8>("u8");
|
||||
qRegisterMetaType<u16>("u16");
|
||||
qRegisterMetaType<u32>("u32");
|
||||
qRegisterMetaType<u64>("u64");
|
||||
qRegisterMetaType<u128>("u128");
|
||||
qRegisterMetaType<s8>("s8");
|
||||
qRegisterMetaType<s16>("s16");
|
||||
qRegisterMetaType<s32>("s32");
|
||||
qRegisterMetaType<s64>("s64");
|
||||
qRegisterMetaType<f32>("f32");
|
||||
qRegisterMetaType<f64>("f64");
|
||||
|
||||
// Register string types
|
||||
qRegisterMetaType<std::string>("std::string");
|
||||
qRegisterMetaType<std::wstring>("std::wstring");
|
||||
qRegisterMetaType<std::u8string>("std::u8string");
|
||||
qRegisterMetaType<std::u16string>("std::u16string");
|
||||
qRegisterMetaType<std::u32string>("std::u32string");
|
||||
qRegisterMetaType<std::string_view>("std::string_view");
|
||||
qRegisterMetaType<std::wstring_view>("std::wstring_view");
|
||||
qRegisterMetaType<std::u8string_view>("std::u8string_view");
|
||||
qRegisterMetaType<std::u16string_view>("std::u16string_view");
|
||||
qRegisterMetaType<std::u32string_view>("std::u32string_view");
|
||||
|
||||
// Register applet types
|
||||
|
||||
// Cabinet Applet
|
||||
qRegisterMetaType<Core::Frontend::CabinetParameters>("Core::Frontend::CabinetParameters");
|
||||
qRegisterMetaType<std::shared_ptr<Service::NFC::NfcDevice>>(
|
||||
"std::shared_ptr<Service::NFC::NfcDevice>");
|
||||
|
||||
// Controller Applet
|
||||
qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
|
||||
|
||||
// Profile Select Applet
|
||||
qRegisterMetaType<Core::Frontend::ProfileSelectParameters>(
|
||||
"Core::Frontend::ProfileSelectParameters");
|
||||
|
||||
// Software Keyboard Applet
|
||||
qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>(
|
||||
"Core::Frontend::KeyboardInitializeParameters");
|
||||
qRegisterMetaType<Core::Frontend::InlineAppearParameters>(
|
||||
"Core::Frontend::InlineAppearParameters");
|
||||
qRegisterMetaType<Core::Frontend::InlineTextParameters>("Core::Frontend::InlineTextParameters");
|
||||
qRegisterMetaType<Service::AM::Frontend::SwkbdResult>("Service::AM::Frontend::SwkbdResult");
|
||||
qRegisterMetaType<Service::AM::Frontend::SwkbdTextCheckResult>(
|
||||
"Service::AM::Frontend::SwkbdTextCheckResult");
|
||||
qRegisterMetaType<Service::AM::Frontend::SwkbdReplyType>(
|
||||
"Service::AM::Frontend::SwkbdReplyType");
|
||||
|
||||
// Web Browser Applet
|
||||
qRegisterMetaType<Service::AM::Frontend::WebExitReason>("Service::AM::Frontend::WebExitReason");
|
||||
|
||||
// Register loader types
|
||||
qRegisterMetaType<Core::SystemResultStatus>("Core::SystemResultStatus");
|
||||
}
|
||||
|
||||
void GMainWindow::AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters,
|
||||
std::shared_ptr<Service::NFC::NfcDevice> nfp_device) {
|
||||
cabinet_applet =
|
||||
|
@ -1630,8 +1569,9 @@ void GMainWindow::ConnectWidgetEvents() {
|
|||
connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile);
|
||||
connect(game_list, &GameList::OpenDirectory, this, &GMainWindow::OnGameListOpenDirectory);
|
||||
connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder);
|
||||
connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this,
|
||||
&GMainWindow::OnTransferableShaderCacheOpenFile);
|
||||
connect(game_list, &GameList::OpenTransferableShaderCacheRequested, this, [this](u64 program_id) {
|
||||
QtCommon::Path::OpenShaderCache(program_id, this);
|
||||
});
|
||||
connect(game_list, &GameList::RemoveInstalledEntryRequested, this,
|
||||
&GMainWindow::OnGameListRemoveInstalledEntry);
|
||||
connect(game_list, &GameList::RemoveFileRequested, this, &GMainWindow::OnGameListRemoveFile);
|
||||
|
@ -1966,74 +1906,10 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
|
|||
nullptr, // Net Connect
|
||||
});
|
||||
|
||||
/** Game Updates check */
|
||||
/** firmware check */
|
||||
|
||||
// yuzu's configuration doesn't actually support lists so this is a bit hacky
|
||||
QSettings settings;
|
||||
QStringList currentIgnored = settings.value("ignoredBadUpdates", {}).toStringList();
|
||||
|
||||
if (std::find(bad_update_games.begin(), bad_update_games.end(), params.program_id) !=
|
||||
bad_update_games.end() &&
|
||||
!currentIgnored.contains(QString::number(params.program_id))) {
|
||||
QMessageBox* msg = new QMessageBox(this);
|
||||
msg->setWindowTitle(tr("Game Updates Warning"));
|
||||
msg->setIcon(QMessageBox::Warning);
|
||||
msg->setText(
|
||||
tr("The game you are trying to launch is known to have performance or booting "
|
||||
"issues when updates are applied. Please try increasing the memory layout to "
|
||||
"6GB or 8GB if any issues occur.<br><br>Press \"OK\" to continue launching, or "
|
||||
"\"Cancel\" to cancel the launch."));
|
||||
|
||||
msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
|
||||
QCheckBox* dontShowAgain = new QCheckBox(msg);
|
||||
dontShowAgain->setText(tr("Don't show again for this game"));
|
||||
msg->setCheckBox(dontShowAgain);
|
||||
|
||||
int result = msg->exec();
|
||||
|
||||
// wtf
|
||||
QMessageBox::ButtonRole role =
|
||||
msg->buttonRole(msg->button((QMessageBox::StandardButton)result));
|
||||
|
||||
switch (role) {
|
||||
case QMessageBox::RejectRole:
|
||||
return false;
|
||||
case QMessageBox::AcceptRole:
|
||||
default:
|
||||
if (dontShowAgain->isChecked()) {
|
||||
currentIgnored << QString::number(params.program_id);
|
||||
settings.setValue("ignoredBadUpdates", currentIgnored);
|
||||
settings.sync();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FirmwareManager::GameRequiresFirmware(params.program_id) &&
|
||||
!FirmwareManager::CheckFirmwarePresence(*system)) {
|
||||
QMessageBox* msg = new QMessageBox(this);
|
||||
msg->setWindowTitle(tr("Game Requires Firmware"));
|
||||
msg->setIcon(QMessageBox::Warning);
|
||||
msg->setText(
|
||||
tr("The game you are trying to launch requires firmware to boot or to get past the "
|
||||
"opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>"
|
||||
"dump and install firmware</a>, or press \"OK\" to launch anyways."));
|
||||
|
||||
msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
|
||||
int exec_result = msg->exec();
|
||||
|
||||
QMessageBox::ButtonRole role =
|
||||
msg->buttonRole(msg->button((QMessageBox::StandardButton)exec_result));
|
||||
|
||||
switch (role) {
|
||||
case QMessageBox::RejectRole:
|
||||
return false;
|
||||
case QMessageBox::AcceptRole:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!QtCommon::Content::CheckGameFirmware(params.program_id, *system, this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Exec */
|
||||
|
@ -2451,6 +2327,7 @@ void GMainWindow::ShutdownGame() {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO(crueter): make this common as well (frontend_common?)
|
||||
play_time_manager->Stop();
|
||||
OnShutdownBegin();
|
||||
OnEmulationStopTimeExpired();
|
||||
|
@ -2495,6 +2372,7 @@ void GMainWindow::OnGameListLoadFile(QString game_path, u64 program_id) {
|
|||
BootGame(game_path, params);
|
||||
}
|
||||
|
||||
// TODO(crueter): Common profile selector
|
||||
void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target,
|
||||
const std::string& game_path) {
|
||||
std::filesystem::path path;
|
||||
|
@ -2603,13 +2481,6 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
|
|||
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
|
||||
}
|
||||
|
||||
// TODO(crueter): Transfer ts to showmessage
|
||||
void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
|
||||
if (!QtCommon::PathUtil::OpenShaderCache(program_id)) {
|
||||
QMessageBox::warning(this, tr("Error Opening Shader Cache"), tr("Failed to create or open shader cache for this title, ensure your app data directory has write permissions."));
|
||||
}
|
||||
}
|
||||
|
||||
static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& dialog,
|
||||
const FileSys::VirtualDir& src, const FileSys::VirtualDir& dest,
|
||||
bool full) {
|
||||
|
@ -2675,26 +2546,14 @@ static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog&
|
|||
// TODO(crueter): All this can be transfered to qt_common
|
||||
// Aldoe I need to decide re: message boxes for QML
|
||||
// translations_common? strings_common? qt_strings? who knows
|
||||
QString GMainWindow::GetGameListErrorRemoving(InstalledEntryType type) const {
|
||||
switch (type) {
|
||||
case InstalledEntryType::Game:
|
||||
return tr("Error Removing Contents");
|
||||
case InstalledEntryType::Update:
|
||||
return tr("Error Removing Update");
|
||||
case InstalledEntryType::AddOnContent:
|
||||
return tr("Error Removing DLC");
|
||||
default:
|
||||
return QStringLiteral("Error Removing <Invalid Type>");
|
||||
}
|
||||
}
|
||||
void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type) {
|
||||
void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, QtCommon::Game::InstalledEntryType type) {
|
||||
const QString entry_question = [type] {
|
||||
switch (type) {
|
||||
case InstalledEntryType::Game:
|
||||
case QtCommon::Game::InstalledEntryType::Game:
|
||||
return tr("Remove Installed Game Contents?");
|
||||
case InstalledEntryType::Update:
|
||||
case QtCommon::Game::InstalledEntryType::Update:
|
||||
return tr("Remove Installed Game Update?");
|
||||
case InstalledEntryType::AddOnContent:
|
||||
case QtCommon::Game::InstalledEntryType::AddOnContent:
|
||||
return tr("Remove Installed Game DLC?");
|
||||
default:
|
||||
return QStringLiteral("Remove Installed Game <Invalid Type>?");
|
||||
|
@ -2706,18 +2565,19 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO(crueter): move this to QtCommon (populate async?)
|
||||
switch (type) {
|
||||
case InstalledEntryType::Game:
|
||||
RemoveBaseContent(program_id, type);
|
||||
case QtCommon::Game::InstalledEntryType::Game:
|
||||
QtCommon::Game::RemoveBaseContent(program_id, type);
|
||||
[[fallthrough]];
|
||||
case InstalledEntryType::Update:
|
||||
RemoveUpdateContent(program_id, type);
|
||||
if (type != InstalledEntryType::Game) {
|
||||
case QtCommon::Game::InstalledEntryType::Update:
|
||||
QtCommon::Game::RemoveUpdateContent(program_id, type);
|
||||
if (type != QtCommon::Game::InstalledEntryType::Game) {
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case InstalledEntryType::AddOnContent:
|
||||
RemoveAddOnContent(program_id, type);
|
||||
case QtCommon::Game::InstalledEntryType::AddOnContent:
|
||||
QtCommon::Game::RemoveAddOnContent(program_id, type);
|
||||
break;
|
||||
}
|
||||
Common::FS::RemoveDirRecursively(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) /
|
||||
|
@ -2725,55 +2585,19 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
|
|||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveBaseContent(u64 program_id, InstalledEntryType type) {
|
||||
const auto res =
|
||||
ContentManager::RemoveBaseContent(system->GetFileSystemController(), program_id);
|
||||
if (res) {
|
||||
QMessageBox::information(this, tr("Successfully Removed"),
|
||||
tr("Successfully removed the installed base game."));
|
||||
} else {
|
||||
QMessageBox::warning(
|
||||
this, GetGameListErrorRemoving(type),
|
||||
tr("The base game is not installed in the NAND and cannot be removed."));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveUpdateContent(u64 program_id, InstalledEntryType type) {
|
||||
const auto res = ContentManager::RemoveUpdate(system->GetFileSystemController(), program_id);
|
||||
if (res) {
|
||||
QMessageBox::information(this, tr("Successfully Removed"),
|
||||
tr("Successfully removed the installed update."));
|
||||
} else {
|
||||
QMessageBox::warning(this, GetGameListErrorRemoving(type),
|
||||
tr("There is no update installed for this title."));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveAddOnContent(u64 program_id, InstalledEntryType type) {
|
||||
const size_t count = ContentManager::RemoveAllDLC(*system, program_id);
|
||||
if (count == 0) {
|
||||
QMessageBox::warning(this, GetGameListErrorRemoving(type),
|
||||
tr("There are no DLC installed for this title."));
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox::information(this, tr("Successfully Removed"),
|
||||
tr("Successfully removed %1 installed DLC.").arg(count));
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
|
||||
void GMainWindow::OnGameListRemoveFile(u64 program_id, QtCommon::Game::GameListRemoveTarget target,
|
||||
const std::string& game_path) {
|
||||
const QString question = [target] {
|
||||
switch (target) {
|
||||
case GameListRemoveTarget::GlShaderCache:
|
||||
case QtCommon::Game::GameListRemoveTarget::GlShaderCache:
|
||||
return tr("Delete OpenGL Transferable Shader Cache?");
|
||||
case GameListRemoveTarget::VkShaderCache:
|
||||
case QtCommon::Game::GameListRemoveTarget::VkShaderCache:
|
||||
return tr("Delete Vulkan Transferable Shader Cache?");
|
||||
case GameListRemoveTarget::AllShaderCache:
|
||||
case QtCommon::Game::GameListRemoveTarget::AllShaderCache:
|
||||
return tr("Delete All Transferable Shader Caches?");
|
||||
case GameListRemoveTarget::CustomConfiguration:
|
||||
case QtCommon::Game::GameListRemoveTarget::CustomConfiguration:
|
||||
return tr("Remove Custom Game Configuration?");
|
||||
case GameListRemoveTarget::CacheStorage:
|
||||
case QtCommon::Game::GameListRemoveTarget::CacheStorage:
|
||||
return tr("Remove Cache Storage?");
|
||||
default:
|
||||
return QString{};
|
||||
|
@ -2786,20 +2610,20 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ
|
|||
}
|
||||
|
||||
switch (target) {
|
||||
case GameListRemoveTarget::VkShaderCache:
|
||||
RemoveVulkanDriverPipelineCache(program_id);
|
||||
case QtCommon::Game::GameListRemoveTarget::VkShaderCache:
|
||||
QtCommon::Game::RemoveVulkanDriverPipelineCache(program_id);
|
||||
[[fallthrough]];
|
||||
case GameListRemoveTarget::GlShaderCache:
|
||||
RemoveTransferableShaderCache(program_id, target);
|
||||
case QtCommon::Game::GameListRemoveTarget::GlShaderCache:
|
||||
QtCommon::Game::RemoveTransferableShaderCache(program_id, target);
|
||||
break;
|
||||
case GameListRemoveTarget::AllShaderCache:
|
||||
RemoveAllTransferableShaderCaches(program_id);
|
||||
case QtCommon::Game::GameListRemoveTarget::AllShaderCache:
|
||||
QtCommon::Game::RemoveAllTransferableShaderCaches(program_id);
|
||||
break;
|
||||
case GameListRemoveTarget::CustomConfiguration:
|
||||
RemoveCustomConfiguration(program_id, game_path);
|
||||
case QtCommon::Game::GameListRemoveTarget::CustomConfiguration:
|
||||
QtCommon::Game::RemoveCustomConfiguration(program_id, game_path);
|
||||
break;
|
||||
case GameListRemoveTarget::CacheStorage:
|
||||
RemoveCacheStorage(program_id);
|
||||
case QtCommon::Game::GameListRemoveTarget::CacheStorage:
|
||||
QtCommon::Game::RemoveCacheStorage(program_id, vfs.get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2815,107 +2639,6 @@ void GMainWindow::OnGameListRemovePlayTimeData(u64 program_id) {
|
|||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target) {
|
||||
const auto target_file_name = [target] {
|
||||
switch (target) {
|
||||
case GameListRemoveTarget::GlShaderCache:
|
||||
return "opengl.bin";
|
||||
case GameListRemoveTarget::VkShaderCache:
|
||||
return "vulkan.bin";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}();
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id);
|
||||
const auto target_file = shader_cache_folder_path / target_file_name;
|
||||
|
||||
if (!Common::FS::Exists(target_file)) {
|
||||
QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
|
||||
tr("A shader cache for this title does not exist."));
|
||||
return;
|
||||
}
|
||||
if (Common::FS::RemoveFile(target_file)) {
|
||||
QMessageBox::information(this, tr("Successfully Removed"),
|
||||
tr("Successfully removed the transferable shader cache."));
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
|
||||
tr("Failed to remove the transferable shader cache."));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveVulkanDriverPipelineCache(u64 program_id) {
|
||||
static constexpr std::string_view target_file_name = "vulkan_pipelines.bin";
|
||||
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id);
|
||||
const auto target_file = shader_cache_folder_path / target_file_name;
|
||||
|
||||
if (!Common::FS::Exists(target_file)) {
|
||||
return;
|
||||
}
|
||||
if (!Common::FS::RemoveFile(target_file)) {
|
||||
QMessageBox::warning(this, tr("Error Removing Vulkan Driver Pipeline Cache"),
|
||||
tr("Failed to remove the driver pipeline cache."));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveAllTransferableShaderCaches(u64 program_id) {
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto program_shader_cache_dir = shader_cache_dir / fmt::format("{:016x}", program_id);
|
||||
|
||||
if (!Common::FS::Exists(program_shader_cache_dir)) {
|
||||
QMessageBox::warning(this, tr("Error Removing Transferable Shader Caches"),
|
||||
tr("A shader cache for this title does not exist."));
|
||||
return;
|
||||
}
|
||||
if (Common::FS::RemoveDirRecursively(program_shader_cache_dir)) {
|
||||
QMessageBox::information(this, tr("Successfully Removed"),
|
||||
tr("Successfully removed the transferable shader caches."));
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Error Removing Transferable Shader Caches"),
|
||||
tr("Failed to remove the transferable shader cache directory."));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& game_path) {
|
||||
const auto file_path = std::filesystem::path(Common::FS::ToU8String(game_path));
|
||||
const auto config_file_name =
|
||||
program_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()).append(".ini")
|
||||
: fmt::format("{:016X}.ini", program_id);
|
||||
const auto custom_config_file_path =
|
||||
Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom" / config_file_name;
|
||||
|
||||
if (!Common::FS::Exists(custom_config_file_path)) {
|
||||
QMessageBox::warning(this, tr("Error Removing Custom Configuration"),
|
||||
tr("A custom configuration for this title does not exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Common::FS::RemoveFile(custom_config_file_path)) {
|
||||
QMessageBox::information(this, tr("Successfully Removed"),
|
||||
tr("Successfully removed the custom game configuration."));
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Error Removing Custom Configuration"),
|
||||
tr("Failed to remove the custom game configuration."));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::RemoveCacheStorage(u64 program_id) {
|
||||
const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir);
|
||||
auto vfs_nand_dir =
|
||||
vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read);
|
||||
|
||||
const auto cache_storage_path = FileSys::SaveDataFactory::GetFullPath(
|
||||
{}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Cache,
|
||||
0 /* program_id */, {}, 0);
|
||||
|
||||
const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path);
|
||||
|
||||
// Not an error if it wasn't cleared.
|
||||
Common::FS::RemoveDirRecursively(path);
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path,
|
||||
DumpRomFSTarget target) {
|
||||
const auto failed = [this] {
|
||||
|
@ -3044,22 +2767,7 @@ void GMainWindow::OnGameListVerifyIntegrity(const std::string& game_path) {
|
|||
return progress.wasCanceled();
|
||||
};
|
||||
|
||||
const auto result = ContentManager::VerifyGameContents(*system, game_path, QtProgressCallback);
|
||||
const QString resultString = tr(QtCommon::GetGameVerificationResultString(result));
|
||||
progress.close();
|
||||
switch (result) {
|
||||
case ContentManager::GameVerificationResult::Success:
|
||||
QMessageBox::information(this, tr("Integrity verification succeeded!"),
|
||||
resultString);
|
||||
break;
|
||||
case ContentManager::GameVerificationResult::Failed:
|
||||
QMessageBox::critical(this, tr("Integrity verification failed!"),
|
||||
resultString);
|
||||
break;
|
||||
case ContentManager::GameVerificationResult::NotImplemented:
|
||||
QMessageBox::warning(this, tr("Integrity verification couldn't be performed"),
|
||||
resultString);
|
||||
}
|
||||
QtCommon::Content::VerifyGameContents(game_path, QtProgressCallback);
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListCopyTID(u64 program_id) {
|
||||
|
@ -4095,6 +3803,7 @@ void GMainWindow::OnLoadAmiibo() {
|
|||
LoadAmiibo(filename);
|
||||
}
|
||||
|
||||
// TODO(crueter): does this need to be ported to QML?
|
||||
bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton) {
|
||||
|
@ -4146,27 +3855,27 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
|
|||
}
|
||||
|
||||
void GMainWindow::OnOpenRootDataFolder() {
|
||||
QtCommon::OpenRootDataFolder();
|
||||
QtCommon::Game::OpenRootDataFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenNANDFolder()
|
||||
{
|
||||
QtCommon::OpenNANDFolder();
|
||||
QtCommon::Game::OpenNANDFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenSDMCFolder()
|
||||
{
|
||||
QtCommon::OpenSDMCFolder();
|
||||
QtCommon::Game::OpenSDMCFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenModFolder()
|
||||
{
|
||||
QtCommon::OpenModFolder();
|
||||
QtCommon::Game::OpenModFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenLogFolder()
|
||||
{
|
||||
QtCommon::OpenLogFolder();
|
||||
QtCommon::Game::OpenLogFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnVerifyInstalledContents() {
|
||||
|
@ -4213,11 +3922,11 @@ void GMainWindow::InstallFirmware(const QString& location, bool recursive) {
|
|||
return progress.wasCanceled();
|
||||
};
|
||||
|
||||
auto result = QtCommon::InstallFirmware(location, recursive, QtProgressCallback, system.get(), vfs.get(), this);
|
||||
auto result = QtCommon::Content::InstallFirmware(location, recursive, QtProgressCallback, vfs.get());
|
||||
|
||||
progress.close();
|
||||
|
||||
if (result != QtCommon::FirmwareInstallResult::Success) return;
|
||||
if (result != QtCommon::Content::FirmwareInstallResult::Success) return;
|
||||
|
||||
auto VerifyFirmwareCallback = [&](size_t total_size, size_t processed_size) {
|
||||
progress.setValue(90 + static_cast<int>((processed_size * 10) / total_size));
|
||||
|
@ -4284,7 +3993,7 @@ void GMainWindow::OnInstallFirmwareFromZIP() {
|
|||
return;
|
||||
}
|
||||
|
||||
const QString qCacheDir = QtCommon::UnzipFirmwareToTmp(firmware_zip_location);
|
||||
const QString qCacheDir = QtCommon::Content::UnzipFirmwareToTmp(firmware_zip_location);
|
||||
|
||||
// In this case, it has to be done recursively, since sometimes people
|
||||
// will pack it into a subdirectory after dumping
|
||||
|
@ -4362,7 +4071,7 @@ void GMainWindow::OnToggleStatusBar() {
|
|||
void GMainWindow::OnGameListRefresh()
|
||||
{
|
||||
// Resets metadata cache and reloads
|
||||
QtCommon::ResetMetadata();
|
||||
QtCommon::Game::ResetMetadata();
|
||||
game_list->RefreshGameDirectory();
|
||||
SetFirmwareVersion();
|
||||
}
|
||||
|
@ -4632,7 +4341,7 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program
|
|||
QImage icon_data =
|
||||
QImage::fromData(icon_image_file.data(), static_cast<int>(icon_image_file.size()));
|
||||
std::filesystem::path out_icon_path;
|
||||
if (QtCommon::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) {
|
||||
if (QtCommon::Game::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) {
|
||||
if (!SaveIconToFile(out_icon_path, icon_data)) {
|
||||
LOG_ERROR(Frontend, "Could not write icon to file");
|
||||
}
|
||||
|
@ -4666,7 +4375,7 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program
|
|||
const std::string categories = "Game;Emulator;Qt;";
|
||||
const std::string keywords = "Switch;Nintendo;";
|
||||
|
||||
if (QtCommon::CreateShortcutLink(shortcut_path, comment, out_icon_path, command,
|
||||
if (QtCommon::Game::CreateShortcutLink(shortcut_path, comment, out_icon_path, command,
|
||||
arguments, categories, keywords, game_title)) {
|
||||
GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS,
|
||||
qgame_title);
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
#include <QTranslator>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include "input_common/drivers/tas_input.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
#include "qt_common/qt_game_util.h"
|
||||
#include "user_data_migration.h"
|
||||
#include "yuzu/compatibility_list.h"
|
||||
#include "yuzu/hotkeys.h"
|
||||
|
@ -53,10 +54,8 @@ class QSlider;
|
|||
class QHBoxLayout;
|
||||
class WaitTreeWidget;
|
||||
enum class GameListOpenTarget;
|
||||
enum class GameListRemoveTarget;
|
||||
enum class GameListShortcutTarget;
|
||||
enum class DumpRomFSTarget;
|
||||
enum class InstalledEntryType;
|
||||
class GameListPlaceholder;
|
||||
|
||||
class QtAmiiboSettingsDialog;
|
||||
|
@ -258,8 +257,6 @@ private:
|
|||
void LinkActionShortcut(QAction* action, const QString& action_name,
|
||||
const bool tas_allowed = false);
|
||||
|
||||
void RegisterMetaTypes();
|
||||
|
||||
void InitializeWidgets();
|
||||
void InitializeDebugWidgets();
|
||||
void InitializeRecentFileMenuActions();
|
||||
|
@ -353,9 +350,8 @@ private slots:
|
|||
void OnGameListLoadFile(QString game_path, u64 program_id);
|
||||
void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target,
|
||||
const std::string& game_path);
|
||||
void OnTransferableShaderCacheOpenFile(u64 program_id);
|
||||
void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type);
|
||||
void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
|
||||
void OnGameListRemoveInstalledEntry(u64 program_id, QtCommon::Game::InstalledEntryType type);
|
||||
void OnGameListRemoveFile(u64 program_id, QtCommon::Game::GameListRemoveTarget target,
|
||||
const std::string& game_path);
|
||||
void OnGameListRemovePlayTimeData(u64 program_id);
|
||||
void OnGameListDumpRomFS(u64 program_id, const std::string& game_path, DumpRomFSTarget target);
|
||||
|
@ -436,16 +432,7 @@ private slots:
|
|||
#endif
|
||||
|
||||
private:
|
||||
QString GetGameListErrorRemoving(InstalledEntryType type) const;
|
||||
void RemoveBaseContent(u64 program_id, InstalledEntryType type);
|
||||
void RemoveUpdateContent(u64 program_id, InstalledEntryType type);
|
||||
void RemoveAddOnContent(u64 program_id, InstalledEntryType type);
|
||||
void RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target);
|
||||
void RemoveVulkanDriverPipelineCache(u64 program_id);
|
||||
void RemoveAllTransferableShaderCaches(u64 program_id);
|
||||
void RemoveCustomConfiguration(u64 program_id, const std::string& game_path);
|
||||
void RemovePlayTimeData(u64 program_id);
|
||||
void RemoveCacheStorage(u64 program_id);
|
||||
bool SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id,
|
||||
u64* selected_title_id, u8* selected_content_record_type);
|
||||
ContentManager::InstallResult InstallNCA(const QString& filename);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue