aboutsummaryrefslogtreecommitdiff
path: root/src/qt_common
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt_common')
-rw-r--r--src/qt_common/CMakeLists.txt3
-rw-r--r--src/qt_common/abstract/frontend.cpp (renamed from src/qt_common/abstract/qt_frontend_util.cpp)2
-rw-r--r--src/qt_common/abstract/frontend.h (renamed from src/qt_common/abstract/qt_frontend_util.h)6
-rw-r--r--src/qt_common/qt_common.cpp10
-rw-r--r--src/qt_common/qt_string_lookup.h23
-rw-r--r--src/qt_common/util/content.cpp6
-rw-r--r--src/qt_common/util/content.h6
-rw-r--r--src/qt_common/util/fs.cpp130
-rw-r--r--src/qt_common/util/fs.h22
-rw-r--r--src/qt_common/util/game.cpp2
-rw-r--r--src/qt_common/util/path.cpp2
11 files changed, 197 insertions, 15 deletions
diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt
index 39dd1a7460..75ef717583 100644
--- a/src/qt_common/CMakeLists.txt
+++ b/src/qt_common/CMakeLists.txt
@@ -20,13 +20,14 @@ add_library(qt_common STATIC
util/applet.h util/applet.cpp
util/compress.h util/compress.cpp
- abstract/qt_frontend_util.h abstract/qt_frontend_util.cpp
+ abstract/frontend.h abstract/frontend.cpp
abstract/qt_progress_dialog.h abstract/qt_progress_dialog.cpp
qt_string_lookup.h
qt_compat.h
discord/discord.h
+ util/fs.h util/fs.cpp
)
create_target_directory_groups(qt_common)
diff --git a/src/qt_common/abstract/qt_frontend_util.cpp b/src/qt_common/abstract/frontend.cpp
index 3fe0ba0a80..2ed76f8ea9 100644
--- a/src/qt_common/abstract/qt_frontend_util.cpp
+++ b/src/qt_common/abstract/frontend.cpp
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
-#include "qt_frontend_util.h"
+#include "frontend.h"
#include "qt_common/qt_common.h"
#ifdef YUZU_QT_WIDGETS
diff --git a/src/qt_common/abstract/qt_frontend_util.h b/src/qt_common/abstract/frontend.h
index 59e8f15a4e..b496b37cbe 100644
--- a/src/qt_common/abstract/qt_frontend_util.h
+++ b/src/qt_common/abstract/frontend.h
@@ -1,8 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
-#ifndef QT_FRONTEND_UTIL_H
-#define QT_FRONTEND_UTIL_H
+#ifndef FRONTEND_H
+#define FRONTEND_H
#include <QGuiApplication>
#include "qt_common/qt_common.h"
@@ -136,4 +136,4 @@ const QString GetSaveFileName(const QString &title,
Options options = Options());
} // namespace QtCommon::Frontend
-#endif // QT_FRONTEND_UTIL_H
+#endif // FRONTEND_H
diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp
index 1fa3df98cf..f2091df866 100644
--- a/src/qt_common/qt_common.cpp
+++ b/src/qt_common/qt_common.cpp
@@ -3,11 +3,14 @@
#include "qt_common.h"
#include "common/fs/fs.h"
+#include "common/fs/ryujinx_compat.h"
#include <QGuiApplication>
#include <QStringLiteral>
#include "common/logging/log.h"
#include "core/frontend/emu_window.h"
+#include "qt_common/abstract/frontend.h"
+#include "qt_common/qt_string_lookup.h"
#include <QFile>
@@ -33,7 +36,8 @@ std::unique_ptr<Core::System> system = nullptr;
std::shared_ptr<FileSys::RealVfsFilesystem> vfs = nullptr;
std::unique_ptr<FileSys::ManualContentProvider> provider = nullptr;
-Core::Frontend::WindowSystemType GetWindowSystemType() {
+Core::Frontend::WindowSystemType GetWindowSystemType()
+{
// Determine WSI type based on Qt platform.
QString platform_name = QGuiApplication::platformName();
if (platform_name == QStringLiteral("windows"))
@@ -101,9 +105,11 @@ void Init(QObject* root)
provider = std::make_unique<FileSys::ManualContentProvider>();
}
-std::filesystem::path GetEdenCommand() {
+std::filesystem::path GetEdenCommand()
+{
std::filesystem::path command;
+ // TODO: flatpak?
QString appimage = QString::fromLocal8Bit(getenv("APPIMAGE"));
if (!appimage.isEmpty()) {
command = std::filesystem::path{appimage.toStdString()};
diff --git a/src/qt_common/qt_string_lookup.h b/src/qt_common/qt_string_lookup.h
index 7756bcdaf2..42d71e6f9d 100644
--- a/src/qt_common/qt_string_lookup.h
+++ b/src/qt_common/qt_string_lookup.h
@@ -42,9 +42,18 @@ enum StringKey {
MigrationTooltipClearOld,
MigrationTooltipLinkOld,
+ // ryujinx
+ KvdbNonexistent,
+ KvdbNoHeader,
+ KvdbInvalidMagic,
+ KvdbMisaligned,
+ KvdbNoImens,
+ RyujinxNoSaveId,
+
};
-static const frozen::map<StringKey, frozen::string, 21> strings = {
+static const constexpr frozen::map<StringKey, frozen::string, 27> strings = {
+ // 0-4
{SavesTooltip,
QT_TR_NOOP("Contains game save data. DO NOT REMOVE UNLESS YOU KNOW WHAT YOU'RE DOING!")},
{ShadersTooltip,
@@ -54,6 +63,7 @@ static const frozen::map<StringKey, frozen::string, 21> strings = {
{ModsTooltip, QT_TR_NOOP("Contains game mods, patches, and cheats.")},
// Key install
+ // 5-9
{KeyInstallSuccess, QT_TR_NOOP("Decryption Keys were successfully installed")},
{KeyInstallInvalidDir, QT_TR_NOOP("Unable to read key directory, aborting")},
{KeyInstallErrorFailedCopy, QT_TR_NOOP("One or more keys failed to copy.")},
@@ -65,6 +75,7 @@ static const frozen::map<StringKey, frozen::string, 21> strings = {
"re-dump keys.")},
// fw install
+ // 10-14
{FwInstallSuccess, QT_TR_NOOP("Successfully installed firmware version %1")},
{FwInstallNoNCAs, QT_TR_NOOP("Unable to locate potential firmware NCA files")},
{FwInstallFailedDelete, QT_TR_NOOP("Failed to delete one or more firmware files.")},
@@ -75,6 +86,7 @@ static const frozen::map<StringKey, frozen::string, 21> strings = {
"Eden or re-install firmware.")},
// migrator
+ // 15-20
{MigrationPromptPrefix, QT_TR_NOOP("Eden has detected user data for the following emulators:")},
{MigrationPrompt,
QT_TR_NOOP("Would you like to migrate your data for use in Eden?\n"
@@ -93,6 +105,15 @@ static const frozen::map<StringKey, frozen::string, 21> strings = {
{MigrationTooltipLinkOld,
QT_TR_NOOP("Creates a filesystem link between the old directory and Eden directory.\n"
"This is recommended if you want to share data between emulators.")},
+
+ // why am I writing these comments again
+ // 21-26
+ {KvdbNonexistent, QT_TR_NOOP("Ryujinx title database does not exist.")},
+ {KvdbNoHeader, QT_TR_NOOP("Invalid header on Ryujinx title database.")},
+ {KvdbInvalidMagic, QT_TR_NOOP("Invalid magic header on Ryujinx title database.")},
+ {KvdbMisaligned, QT_TR_NOOP("Invalid byte alignment on Ryujinx title database.")},
+ {KvdbNoImens, QT_TR_NOOP("No items found in Ryujinx title database.")},
+ {RyujinxNoSaveId, QT_TR_NOOP("Title %1 not found in Ryujinx title database.")},
};
static inline const QString Lookup(StringKey key)
diff --git a/src/qt_common/util/content.cpp b/src/qt_common/util/content.cpp
index 4360efeef0..df4435f567 100644
--- a/src/qt_common/util/content.cpp
+++ b/src/qt_common/util/content.cpp
@@ -11,7 +11,7 @@
#include "frontend_common/firmware_manager.h"
#include "compress.h"
-#include "qt_common/abstract/qt_frontend_util.h"
+#include "qt_common/abstract/frontend.h"
#include "qt_common/abstract/qt_progress_dialog.h"
#include "qt_common/qt_common.h"
@@ -404,7 +404,7 @@ void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir,
std::function<void()> callback)
{
using namespace QtCommon::Frontend;
- const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir, user_id);
+ const std::string dir = FrontendCommon::DataManager::GetDataDirString(data_dir, user_id);
const QString zip_dump_location = GetSaveFileName(tr("Select Export Location"),
tr("%1.zip").arg(name),
@@ -468,7 +468,7 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir,
const std::string& user_id,
std::function<void()> callback)
{
- const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir, user_id);
+ const std::string dir = FrontendCommon::DataManager::GetDataDirString(data_dir, user_id);
using namespace QtCommon::Frontend;
diff --git a/src/qt_common/util/content.h b/src/qt_common/util/content.h
index d1384546e1..4102737fb1 100644
--- a/src/qt_common/util/content.h
+++ b/src/qt_common/util/content.h
@@ -25,7 +25,8 @@ enum class FirmwareInstallResult {
inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result)
{
- return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>((int) result + (int) QtCommon::StringLookup::FwInstallSuccess));
+ return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>(
+ (int) result + (int) QtCommon::StringLookup::FwInstallSuccess));
}
/**
@@ -36,7 +37,8 @@ inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result
inline const QString GetKeyInstallResultString(FirmwareManager::KeyInstallResult result)
{
// this can probably be made into a common function of sorts
- return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>((int) result + (int) QtCommon::StringLookup::KeyInstallSuccess));
+ return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>(
+ (int) result + (int) QtCommon::StringLookup::KeyInstallSuccess));
}
void InstallFirmware(const QString &location, bool recursive);
diff --git a/src/qt_common/util/fs.cpp b/src/qt_common/util/fs.cpp
new file mode 100644
index 0000000000..da59a4e675
--- /dev/null
+++ b/src/qt_common/util/fs.cpp
@@ -0,0 +1,130 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <filesystem>
+#include "fs.h"
+#include "common/fs/ryujinx_compat.h"
+#include "common/fs/symlink.h"
+#include "frontend_common/data_manager.h"
+#include "qt_common/abstract/frontend.h"
+#include "qt_common/qt_string_lookup.h"
+
+namespace fs = std::filesystem;
+
+namespace QtCommon::FS {
+
+void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to)
+{
+ std::error_code ec;
+
+ // "ignore" errors--if the dir fails to be deleted, error handling later will handle it
+ fs::remove_all(to, ec);
+
+ if (Common::FS::CreateSymlink(from, to)) {
+ QtCommon::Frontend::Information(tr("Linked Save Data"), tr("Save data has been linked."));
+ } else {
+ QtCommon::Frontend::Critical(
+ tr("Failed to link save data"),
+ tr("Could not link directory:\n\t%1\nTo:\n\t%2").arg(QString::fromStdString(from.string()), QString::fromStdString(to.string())));
+ }
+}
+
+bool CheckUnlink(const fs::path &eden_dir, const fs::path &ryu_dir)
+{
+ bool eden_link = Common::FS::IsSymlink(eden_dir);
+ bool ryu_link = Common::FS::IsSymlink(ryu_dir);
+
+ if (!(eden_link || ryu_link))
+ return false;
+
+ auto result = QtCommon::Frontend::Warning(
+ tr("Already Linked"),
+ tr("This title is already linked to Ryujinx. Would you like to unlink it?"),
+ QtCommon::Frontend::StandardButton::Yes | QtCommon::Frontend::StandardButton::No);
+
+ if (result != QtCommon::Frontend::StandardButton::Yes)
+ return true;
+
+ fs::path linked;
+ fs::path orig;
+
+ if (eden_link) {
+ linked = eden_dir;
+ orig = ryu_dir;
+ } else {
+ linked = ryu_dir;
+ orig = eden_dir;
+ }
+
+ // first cleanup the symlink/junction,
+ try {
+ // NB: do NOT use remove_all, as Windows treats this as a remove_all to the target,
+ // NOT the junction
+ fs::remove(linked);
+ } catch (std::exception &e) {
+ QtCommon::Frontend::Critical(
+ tr("Failed to unlink old directory"),
+ tr("OS returned error: %1").arg(QString::fromStdString(e.what())));
+ return true;
+ }
+
+ // then COPY the other dir
+ try {
+ fs::copy(orig, linked, fs::copy_options::recursive);
+ } catch (std::exception &e) {
+ QtCommon::Frontend::Critical(
+ tr("Failed to copy save data"),
+ tr("OS returned error: %1").arg(QString::fromStdString(e.what())));
+ }
+
+ QtCommon::Frontend::Information(
+ tr("Unlink Successful"),
+ tr("Successfully unlinked Ryujinx save data. Save data has been kept intact."));
+
+ return true;
+}
+
+u64 GetRyujinxSaveID(const u64 &program_id)
+{
+ auto path = Common::FS::GetKvdbPath();
+ std::vector<Common::FS::IMEN> imens;
+ Common::FS::IMENReadResult res = Common::FS::ReadKvdb(path, imens);
+
+ if (res == Common::FS::IMENReadResult::Success) {
+ // TODO: this can probably be done with std::find_if but I'm lazy
+ for (const Common::FS::IMEN &imen : imens) {
+ if (imen.title_id == program_id)
+ return imen.save_id;
+ }
+
+ QtCommon::Frontend::Critical(
+ tr("Could not find Ryujinx save data"),
+ StringLookup::Lookup(StringLookup::RyujinxNoSaveId).arg(program_id, 0, 16));
+ } else {
+ // TODO: make this long thing a function or something
+ QString caption = StringLookup::Lookup(
+ static_cast<StringLookup::StringKey>((int) res + (int) StringLookup::KvdbNonexistent));
+ QtCommon::Frontend::Critical(tr("Could not find Ryujinx save data"), caption);
+ }
+
+ return -1;
+}
+
+std::optional<std::pair<fs::path, fs::path> > GetEmuPaths(
+ const u64 program_id, const u64 save_id, const std::string &user_id)
+{
+ fs::path ryu_dir = Common::FS::GetRyuSavePath(save_id);
+
+ if (user_id.empty())
+ return std::nullopt;
+
+ std::string hex_program = fmt::format("{:016X}", program_id);
+ fs::path eden_dir
+ = FrontendCommon::DataManager::GetDataDir(FrontendCommon::DataManager::DataDir::Saves,
+ user_id)
+ / hex_program;
+
+ return std::make_pair(eden_dir, ryu_dir);
+}
+
+} // namespace QtCommon::FS
diff --git a/src/qt_common/util/fs.h b/src/qt_common/util/fs.h
new file mode 100644
index 0000000000..ee8859a2e5
--- /dev/null
+++ b/src/qt_common/util/fs.h
@@ -0,0 +1,22 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/common_types.h"
+#include <filesystem>
+#include <optional>
+
+#pragma once
+
+namespace QtCommon::FS {
+
+void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to);
+u64 GetRyujinxSaveID(const u64 &program_id);
+
+/// @brief {eden, ryu}
+std::optional<std::pair<std::filesystem::path, std::filesystem::path>> GetEmuPaths(
+ const u64 program_id, const u64 save_id, const std::string &user_id);
+
+/// returns FALSE if the dirs are NOT linked
+bool CheckUnlink(const std::filesystem::path &eden_dir, const std::filesystem::path &ryu_dir);
+
+} // namespace QtCommon::FS
diff --git a/src/qt_common/util/game.cpp b/src/qt_common/util/game.cpp
index e5018d24cb..e34a388993 100644
--- a/src/qt_common/util/game.cpp
+++ b/src/qt_common/util/game.cpp
@@ -8,7 +8,7 @@
#include "core/file_sys/savedata_factory.h"
#include "core/hle/service/am/am_types.h"
#include "frontend_common/content_manager.h"
-#include "qt_common/abstract/qt_frontend_util.h"
+#include "qt_common/abstract/frontend.h"
#include "qt_common/config/uisettings.h"
#include "qt_common/qt_common.h"
#include "yuzu/util/util.h"
diff --git a/src/qt_common/util/path.cpp b/src/qt_common/util/path.cpp
index 93e8007eb9..73689058c6 100644
--- a/src/qt_common/util/path.cpp
+++ b/src/qt_common/util/path.cpp
@@ -7,7 +7,7 @@
#include <QUrl>
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
-#include "qt_common/abstract/qt_frontend_util.h"
+#include "qt_common/abstract/frontend.h"
#include <fmt/format.h>
namespace QtCommon::Path {