Browse Source
[qt_common] reorg, move more stuff out of main
[qt_common] reorg, move more stuff out of main
Signed-off-by: crueter <crueter@eden-emu.dev>pull/94/head
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
20 changed files with 917 additions and 674 deletions
-
5src/qt_common/CMakeLists.txt
-
175src/qt_common/qt_common.cpp
-
68src/qt_common/qt_common.h
-
202src/qt_common/qt_content_util.cpp
-
48src/qt_common/qt_content_util.h
-
69src/qt_common/qt_frontend_util.cpp
-
44src/qt_common/qt_frontend_util.h
-
270src/qt_common/qt_game_util.cpp
-
40src/qt_common/qt_game_util.h
-
72src/qt_common/qt_meta.cpp
-
12src/qt_common/qt_meta.h
-
9src/qt_common/qt_path_util.cpp
-
4src/qt_common/qt_path_util.h
-
75src/qt_common/qt_rom_util.cpp
-
17src/qt_common/qt_rom_util.h
-
13src/yuzu/configuration/configure_filesystem.cpp
-
25src/yuzu/game_list.cpp
-
19src/yuzu/game_list.h
-
403src/yuzu/main.cpp
-
21src/yuzu/main.h
@ -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.")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -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 |
||||
@ -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"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
#ifndef QT_META_H |
||||
|
#define QT_META_H |
||||
|
|
||||
|
#include <QObject> |
||||
|
|
||||
|
namespace QtCommon::Meta { |
||||
|
|
||||
|
// |
||||
|
void RegisterMetaTypes(); |
||||
|
|
||||
|
} |
||||
|
#endif // QT_META_H |
||||
@ -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; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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 |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue