mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 05:28:56 +02:00
[desktop, fs] main_window separation; fix Ryujinx save data link issues (#2929)
Some genius decided to put the entire MainWindow class into main.h and main.cpp, which is not only horrific practice but also completely destroys clangd beyond repair. Please, just don't do this. (this will probably merge conflict to hell and back) Also, fixes a bunch of issues with Ryujinx save data link: - Paths with spaces would cause mklink to fail - Add support for portable directories - Symlink detection was incorrect sometimes(????) - Some other stuff I'm forgetting Furthermore, when selecting "From Eden" and attempting to save in Ryujinx, Ryujinx would destroy the link for... some reason? So to get around this we just copy the Eden data to Ryujinx then treat it like a "From Ryujinx" op Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2929 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
This commit is contained in:
parent
e13c7ef3f8
commit
08f3639c80
51 changed files with 5386 additions and 5283 deletions
|
|
@ -586,7 +586,7 @@ else()
|
||||||
find_package(zstd 1.5 REQUIRED MODULE)
|
find_package(zstd 1.5 REQUIRED MODULE)
|
||||||
|
|
||||||
# wow
|
# wow
|
||||||
find_package(Boost 1.57.0 CONFIG REQUIRED OPTIONAL_COMPONENTS headers context system fiber)
|
find_package(Boost 1.57.0 CONFIG REQUIRED OPTIONAL_COMPONENTS headers context system fiber filesystem)
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
|
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
|
||||||
find_package(gamemode 1.7 MODULE)
|
find_package(gamemode 1.7 MODULE)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
"hash": "4fb7f6fde92762305aad8754d7643cd918dd1f3f67e104e9ab385b18c73178d72a17321354eb203b790b6702f2cf6d725a5d6e2dfbc63b1e35f9eb59fb42ece9",
|
"hash": "4fb7f6fde92762305aad8754d7643cd918dd1f3f67e104e9ab385b18c73178d72a17321354eb203b790b6702f2cf6d725a5d6e2dfbc63b1e35f9eb59fb42ece9",
|
||||||
"git_version": "1.89.0",
|
"git_version": "1.89.0",
|
||||||
"version": "1.57",
|
"version": "1.57",
|
||||||
"find_args": "CONFIG",
|
"find_args": "CONFIG OPTIONAL_COMPONENTS headers context system fiber filesystem",
|
||||||
"patches": [
|
"patches": [
|
||||||
"0001-clang-cl.patch",
|
"0001-clang-cl.patch",
|
||||||
"0002-use-marmasm.patch",
|
"0002-use-marmasm.patch",
|
||||||
|
|
|
||||||
|
|
@ -252,11 +252,13 @@ if(CXX_CLANG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BOOST_NO_HEADERS)
|
if (BOOST_NO_HEADERS)
|
||||||
target_link_libraries(common PUBLIC Boost::algorithm Boost::icl Boost::pool)
|
target_link_libraries(common PUBLIC Boost::algorithm Boost::icl Boost::pool Boost::filesystem)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(common PUBLIC Boost::headers)
|
target_link_libraries(common PUBLIC Boost::headers)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(common PUBLIC Boost::filesystem)
|
||||||
|
|
||||||
if (lz4_ADDED)
|
if (lz4_ADDED)
|
||||||
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,29 @@ namespace fs = std::filesystem;
|
||||||
|
|
||||||
fs::path GetKvdbPath()
|
fs::path GetKvdbPath()
|
||||||
{
|
{
|
||||||
return GetLegacyPath(EmuPath::RyujinxDir) / "bis" / "system" / "save" / "8000000000000000" / "0"
|
return GetKvdbPath(GetLegacyPath(EmuPath::RyujinxDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::path GetKvdbPath(const fs::path& path) {
|
||||||
|
return path / "bis" / "system" / "save" / "8000000000000000" / "0"
|
||||||
/ "imkvdb.arc";
|
/ "imkvdb.arc";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs::path GetRyuPathFromSavePath(const fs::path& path) {
|
||||||
|
// This is a horrible hack, but I cba to find something better
|
||||||
|
return path.parent_path().parent_path().parent_path().parent_path().parent_path();
|
||||||
|
}
|
||||||
|
|
||||||
fs::path GetRyuSavePath(const u64 &save_id)
|
fs::path GetRyuSavePath(const u64 &save_id)
|
||||||
{
|
{
|
||||||
|
return GetRyuSavePath(GetLegacyPath(EmuPath::RyujinxDir), save_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path GetRyuSavePath(const std::filesystem::path& path, const u64& save_id) {
|
||||||
std::string hex = fmt::format("{:016x}", save_id);
|
std::string hex = fmt::format("{:016x}", save_id);
|
||||||
|
|
||||||
// TODO: what's the difference between 0 and 1?
|
// TODO: what's the difference between 0 and 1?
|
||||||
return GetLegacyPath(EmuPath::RyujinxDir) / "bis" / "user" / "save" / hex / "0";
|
return path / "bis" / "user" / "save" / hex / "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
IMENReadResult ReadKvdb(const fs::path &path, std::vector<IMEN> &imens)
|
IMENReadResult ReadKvdb(const fs::path &path, std::vector<IMEN> &imens)
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,17 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
namespace Common::FS {
|
namespace Common::FS {
|
||||||
|
|
||||||
constexpr const char IMEN_MAGIC[4] = {0x49, 0x4d, 0x45, 0x4e};
|
constexpr const char IMEN_MAGIC[4] = {0x49, 0x4d, 0x45, 0x4e};
|
||||||
constexpr const char IMKV_MAGIC[4] = {0x49, 0x4d, 0x4b, 0x56};
|
constexpr const char IMKV_MAGIC[4] = {0x49, 0x4d, 0x4b, 0x56};
|
||||||
constexpr const u8 IMEN_SIZE = 0x8c;
|
constexpr const u8 IMEN_SIZE = 0x8c;
|
||||||
|
|
||||||
fs::path GetKvdbPath();
|
std::filesystem::path GetKvdbPath();
|
||||||
fs::path GetRyuSavePath(const u64 &program_id);
|
std::filesystem::path GetKvdbPath(const std::filesystem::path &path);
|
||||||
|
std::filesystem::path GetRyuPathFromSavePath(const std::filesystem::path &path);
|
||||||
|
std::filesystem::path GetRyuSavePath(const u64 &save_id);
|
||||||
|
std::filesystem::path GetRyuSavePath(const std::filesystem::path &path, const u64 &save_id);
|
||||||
|
|
||||||
enum class IMENReadResult {
|
enum class IMENReadResult {
|
||||||
Nonexistent, // ryujinx not found
|
Nonexistent, // ryujinx not found
|
||||||
|
|
@ -35,6 +36,6 @@ struct IMEN
|
||||||
|
|
||||||
static_assert(sizeof(IMEN) == 0x10, "IMEN has incorrect size.");
|
static_assert(sizeof(IMEN) == 0x10, "IMEN has incorrect size.");
|
||||||
|
|
||||||
IMENReadResult ReadKvdb(const fs::path &path, std::vector<IMEN> &imens);
|
IMENReadResult ReadKvdb(const std::filesystem::path &path, std::vector<IMEN> &imens);
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@
|
||||||
#include "symlink.h"
|
#include "symlink.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
// The sole purpose of this file is to treat symlinks like symlinks on POSIX,
|
// The sole purpose of this file is to treat symlinks like symlinks on POSIX,
|
||||||
|
|
@ -15,29 +17,40 @@ namespace fs = std::filesystem;
|
||||||
// This is because, for some inexplicable reason, Microsoft has locked symbolic
|
// This is because, for some inexplicable reason, Microsoft has locked symbolic
|
||||||
// links behind a "security policy", whereas directory junctions--functionally identical
|
// links behind a "security policy", whereas directory junctions--functionally identical
|
||||||
// for directories, by the way--are not. Why? I don't know.
|
// for directories, by the way--are not. Why? I don't know.
|
||||||
|
// And no, they do NOT provide a standard API for this (at least to my knowledge).
|
||||||
|
// CreateSymbolicLink, even when EXPLICITLY TOLD to create a junction, still fails
|
||||||
|
// because of their security policy.
|
||||||
|
// I don't know what kind of drugs the Windows developers have been on since NT started.
|
||||||
|
|
||||||
|
// Microsoft still has not implemented any of this in their std::filesystem implemenation,
|
||||||
|
// which ALSO means that it DOES NOT FOLLOW ANY DIRECTORY JUNCTIONS... AT ALL.
|
||||||
|
// Nor does any of their command line utilities or APIs. So you're quite literally
|
||||||
|
// on your own.
|
||||||
|
|
||||||
namespace Common::FS {
|
namespace Common::FS {
|
||||||
|
|
||||||
bool CreateSymlink(const fs::path &from, const fs::path &to)
|
bool CreateSymlink(fs::path from, fs::path to)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
from.make_preferred();
|
||||||
const std::string command = fmt::format("mklink /J {} {}", to.string(), from.string());
|
to.make_preferred();
|
||||||
return system(command.c_str()) == 0;
|
|
||||||
#else
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::create_directory_symlink(from, to, ec);
|
fs::create_directory_symlink(from, to, ec);
|
||||||
return !ec;
|
#ifdef _WIN32
|
||||||
|
if (ec) {
|
||||||
|
const std::string command = fmt::format("mklink /J \"{}\" \"{}\"",
|
||||||
|
to.string(),
|
||||||
|
from.string());
|
||||||
|
return system(command.c_str()) == 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return !ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSymlink(const fs::path &path)
|
bool IsSymlink(const fs::path &path)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
return boost::filesystem::is_symlink(boost::filesystem::path{path});
|
||||||
auto attributes = GetFileAttributesW(path.wstring().c_str());
|
|
||||||
return attributes & FILE_ATTRIBUTE_REPARSE_POINT;
|
|
||||||
#else
|
|
||||||
return fs::is_symlink(path);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace Common::FS {
|
namespace Common::FS {
|
||||||
|
|
||||||
bool CreateSymlink(const std::filesystem::path &from, const std::filesystem::path &to);
|
bool CreateSymlink(std::filesystem::path from, std::filesystem::path to);
|
||||||
bool IsSymlink(const std::filesystem::path &path);
|
bool IsSymlink(const std::filesystem::path &path);
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
#include <boost/algorithm/string/find.hpp>
|
#include <boost/algorithm/string/find.hpp>
|
||||||
|
|
@ -18,11 +16,11 @@
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "common/fs/fs_types.h"
|
#include "common/fs/fs_types.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
|
#include "common/fs/symlink.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/file_sys/savedata_factory.h"
|
#include "core/file_sys/savedata_factory.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include <ranges>
|
|
||||||
|
|
||||||
namespace Service::Account {
|
namespace Service::Account {
|
||||||
|
|
||||||
|
|
@ -492,6 +490,32 @@ void ProfileManager::ResetUserSaveFile()
|
||||||
ParseUserSaveFile();
|
ParseUserSaveFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<UUID> ProfileManager::FindExistingProfileUUIDs()
|
||||||
|
{
|
||||||
|
std::vector<UUID> uuids;
|
||||||
|
for (const ProfileInfo& p : profiles) {
|
||||||
|
auto uuid = p.user_uuid;
|
||||||
|
if (!uuid.IsInvalid()) {
|
||||||
|
uuids.emplace_back(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuids;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> ProfileManager::FindExistingProfileStrings()
|
||||||
|
{
|
||||||
|
std::vector<UUID> uuids = FindExistingProfileUUIDs();
|
||||||
|
std::vector<std::string> uuid_strings;
|
||||||
|
|
||||||
|
for (const UUID &uuid : uuids) {
|
||||||
|
auto user_id = uuid.AsU128();
|
||||||
|
uuid_strings.emplace_back(fmt::format("{:016X}{:016X}", user_id[1], user_id[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuid_strings;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> ProfileManager::FindGoodProfiles()
|
std::vector<std::string> ProfileManager::FindGoodProfiles()
|
||||||
{
|
{
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
@ -501,31 +525,17 @@ std::vector<std::string> ProfileManager::FindGoodProfiles()
|
||||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)
|
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)
|
||||||
/ "user/save/0000000000000000";
|
/ "user/save/0000000000000000";
|
||||||
|
|
||||||
// some exceptions because certain games just LOVE TO CAUSE ISSUES
|
// some exceptions, e.g. the "system" profile
|
||||||
static constexpr const std::array<const char* const, 2> EXCEPTION_UUIDS
|
static constexpr const std::array<const char* const, 1> EXCEPTION_UUIDS
|
||||||
= {"5755CC2A545A87128500000000000000", "00000000000000000000000000000000"};
|
= {"00000000000000000000000000000000"};
|
||||||
|
|
||||||
for (const char *const uuid : EXCEPTION_UUIDS) {
|
for (const char *const uuid : EXCEPTION_UUIDS) {
|
||||||
if (fs::exists(path / uuid))
|
if (fs::exists(path / uuid))
|
||||||
good_uuids.emplace_back(uuid);
|
good_uuids.emplace_back(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const ProfileInfo& p : profiles) {
|
auto existing = FindExistingProfileStrings();
|
||||||
std::string uuid_string = [p]() -> std::string {
|
good_uuids.insert(good_uuids.end(), existing.begin(), existing.end());
|
||||||
auto uuid = p.user_uuid;
|
|
||||||
|
|
||||||
// "ignore" invalid uuids
|
|
||||||
if (uuid.IsInvalid()) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto user_id = uuid.AsU128();
|
|
||||||
|
|
||||||
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
|
|
||||||
}();
|
|
||||||
|
|
||||||
if (uuid_string != "0") good_uuids.emplace_back(uuid_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return good_uuids;
|
return good_uuids;
|
||||||
}
|
}
|
||||||
|
|
@ -562,7 +572,8 @@ std::vector<std::string> ProfileManager::FindOrphanedProfiles()
|
||||||
override = true;
|
override = true;
|
||||||
|
|
||||||
// if there are any regular files (NOT directories) there, do NOT delete it :p
|
// if there are any regular files (NOT directories) there, do NOT delete it :p
|
||||||
if (file.is_regular_file())
|
// Also: check for symlinks
|
||||||
|
if (file.is_regular_file() || Common::FS::IsSymlink(file.path()))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (const fs::filesystem_error& e) {
|
} catch (const fs::filesystem_error& e) {
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,8 @@ public:
|
||||||
|
|
||||||
void ResetUserSaveFile();
|
void ResetUserSaveFile();
|
||||||
|
|
||||||
|
std::vector<Common::UUID> FindExistingProfileUUIDs();
|
||||||
|
std::vector<std::string> FindExistingProfileStrings();
|
||||||
std::vector<std::string> FindGoodProfiles();
|
std::vector<std::string> FindGoodProfiles();
|
||||||
std::vector<std::string> FindOrphanedProfiles();
|
std::vector<std::string> FindOrphanedProfiles();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const QString GetOpenFileName(const QString &title,
|
||||||
Options options)
|
Options options)
|
||||||
{
|
{
|
||||||
#ifdef YUZU_QT_WIDGETS
|
#ifdef YUZU_QT_WIDGETS
|
||||||
return QFileDialog::getOpenFileName((QWidget *) rootObject, title, dir, filter, selectedFilter, options);
|
return QFileDialog::getOpenFileName(rootObject, title, dir, filter, selectedFilter, options);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,7 +39,14 @@ const QString GetSaveFileName(const QString &title,
|
||||||
Options options)
|
Options options)
|
||||||
{
|
{
|
||||||
#ifdef YUZU_QT_WIDGETS
|
#ifdef YUZU_QT_WIDGETS
|
||||||
return QFileDialog::getSaveFileName((QWidget *) rootObject, title, dir, filter, selectedFilter, options);
|
return QFileDialog::getSaveFileName(rootObject, title, dir, filter, selectedFilter, options);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString GetExistingDirectory(const QString& caption, const QString& dir,
|
||||||
|
Options options) {
|
||||||
|
#ifdef YUZU_QT_WIDGETS
|
||||||
|
return QFileDialog::getExistingDirectory(rootObject, caption, dir, options);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,5 +135,9 @@ const QString GetSaveFileName(const QString &title,
|
||||||
QString *selectedFilter = nullptr,
|
QString *selectedFilter = nullptr,
|
||||||
Options options = Options());
|
Options options = Options());
|
||||||
|
|
||||||
|
const QString GetExistingDirectory(const QString &caption = QString(),
|
||||||
|
const QString &dir = QString(),
|
||||||
|
Options options = Option::ShowDirsOnly);
|
||||||
|
|
||||||
} // namespace QtCommon::Frontend
|
} // namespace QtCommon::Frontend
|
||||||
#endif // FRONTEND_H
|
#endif // FRONTEND_H
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,17 @@ void QtConfig::ReadUIGamelistValues() {
|
||||||
}
|
}
|
||||||
EndArray();
|
EndArray();
|
||||||
|
|
||||||
|
const int linked_size = BeginArray("ryujinx_linked");
|
||||||
|
for (int i = 0; i < linked_size; ++i) {
|
||||||
|
SetArrayIndex(i);
|
||||||
|
|
||||||
|
QDir ryu_dir = QString::fromStdString(ReadStringSetting("ryujinx_path"));
|
||||||
|
u64 program_id = ReadUnsignedIntegerSetting("program_id");
|
||||||
|
|
||||||
|
UISettings::values.ryujinx_link_paths.insert(program_id, ryu_dir);
|
||||||
|
}
|
||||||
|
EndArray();
|
||||||
|
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -499,6 +510,21 @@ void QtConfig::SaveUIGamelistValues() {
|
||||||
}
|
}
|
||||||
EndArray(); // favorites
|
EndArray(); // favorites
|
||||||
|
|
||||||
|
BeginArray(std::string("ryujinx_linked"));
|
||||||
|
int i = 0;
|
||||||
|
QMapIterator iter(UISettings::values.ryujinx_link_paths);
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.next();
|
||||||
|
|
||||||
|
SetArrayIndex(i);
|
||||||
|
WriteIntegerSetting("program_id", iter.key());
|
||||||
|
WriteStringSetting("ryujinx_path", iter.value().absolutePath().toStdString());
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndArray(); // ryujinx
|
||||||
|
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,54 +28,54 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject *parent);
|
||||||
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent);
|
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent);
|
||||||
|
|
||||||
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map = {
|
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map = {
|
||||||
{Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "None"))},
|
{Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "None"))},
|
||||||
{Settings::AntiAliasing::Fxaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FXAA"))},
|
{Settings::AntiAliasing::Fxaa, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "FXAA"))},
|
||||||
{Settings::AntiAliasing::Smaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SMAA"))},
|
{Settings::AntiAliasing::Smaa, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "SMAA"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map = {
|
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map = {
|
||||||
{Settings::ScalingFilter::NearestNeighbor,
|
{Settings::ScalingFilter::NearestNeighbor,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Nearest"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Nearest"))},
|
||||||
{Settings::ScalingFilter::Bilinear,
|
{Settings::ScalingFilter::Bilinear,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Bilinear"))},
|
||||||
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
|
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Bicubic"))},
|
||||||
{Settings::ScalingFilter::ZeroTangent, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Zero-Tangent"))},
|
{Settings::ScalingFilter::ZeroTangent, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Zero-Tangent"))},
|
||||||
{Settings::ScalingFilter::BSpline, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "B-Spline"))},
|
{Settings::ScalingFilter::BSpline, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "B-Spline"))},
|
||||||
{Settings::ScalingFilter::Mitchell, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Mitchell"))},
|
{Settings::ScalingFilter::Mitchell, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Mitchell"))},
|
||||||
{Settings::ScalingFilter::Spline1,
|
{Settings::ScalingFilter::Spline1,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Spline-1"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Spline-1"))},
|
||||||
{Settings::ScalingFilter::Gaussian,
|
{Settings::ScalingFilter::Gaussian,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Gaussian"))},
|
||||||
{Settings::ScalingFilter::Lanczos,
|
{Settings::ScalingFilter::Lanczos,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Lanczos"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Lanczos"))},
|
||||||
{Settings::ScalingFilter::ScaleForce,
|
{Settings::ScalingFilter::ScaleForce,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "ScaleForce"))},
|
||||||
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
|
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "FSR"))},
|
||||||
{Settings::ScalingFilter::Area, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Area"))},
|
{Settings::ScalingFilter::Area, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Area"))},
|
||||||
{Settings::ScalingFilter::Mmpx, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "MMPX"))},
|
{Settings::ScalingFilter::Mmpx, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "MMPX"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
|
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
|
||||||
{Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))},
|
{Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Docked"))},
|
||||||
{Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))},
|
{Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Handheld"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map = {
|
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map = {
|
||||||
{Settings::GpuAccuracy::Normal, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Normal"))},
|
{Settings::GpuAccuracy::Normal, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Normal"))},
|
||||||
{Settings::GpuAccuracy::High, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "High"))},
|
{Settings::GpuAccuracy::High, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "High"))},
|
||||||
{Settings::GpuAccuracy::Extreme, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Extreme"))},
|
{Settings::GpuAccuracy::Extreme, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Extreme"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map = {
|
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map = {
|
||||||
{Settings::RendererBackend::Vulkan, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Vulkan"))},
|
{Settings::RendererBackend::Vulkan, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Vulkan"))},
|
||||||
{Settings::RendererBackend::OpenGL, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "OpenGL"))},
|
{Settings::RendererBackend::OpenGL, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "OpenGL"))},
|
||||||
{Settings::RendererBackend::Null, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Null"))},
|
{Settings::RendererBackend::Null, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Null"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map = {
|
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map = {
|
||||||
{Settings::ShaderBackend::Glsl, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLSL"))},
|
{Settings::ShaderBackend::Glsl, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "GLSL"))},
|
||||||
{Settings::ShaderBackend::Glasm, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLASM"))},
|
{Settings::ShaderBackend::Glasm, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "GLASM"))},
|
||||||
{Settings::ShaderBackend::SpirV, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SPIRV"))},
|
{Settings::ShaderBackend::SpirV, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "SPIRV"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ConfigurationShared
|
} // namespace ConfigurationShared
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <qdir.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/settings_enums.h"
|
#include "common/settings_enums.h"
|
||||||
|
|
@ -201,6 +202,7 @@ struct Values {
|
||||||
Setting<bool> cache_game_list{linkage, true, "cache_game_list", Category::UiGameList};
|
Setting<bool> cache_game_list{linkage, true, "cache_game_list", Category::UiGameList};
|
||||||
Setting<bool> favorites_expanded{linkage, true, "favorites_expanded", Category::UiGameList};
|
Setting<bool> favorites_expanded{linkage, true, "favorites_expanded", Category::UiGameList};
|
||||||
QVector<u64> favorited_ids;
|
QVector<u64> favorited_ids;
|
||||||
|
QMap<u64, QDir> ryujinx_link_paths;
|
||||||
|
|
||||||
// Compatibility List
|
// Compatibility List
|
||||||
Setting<bool> show_compat{linkage, true, "show_compat", Category::UiGameList};
|
Setting<bool> show_compat{linkage, true, "show_compat", Category::UiGameList};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,12 @@
|
||||||
#include "frozen/map.h"
|
#include "frozen/map.h"
|
||||||
#include "frozen/string.h"
|
#include "frozen/string.h"
|
||||||
|
|
||||||
|
/// Small helper to look up enums.
|
||||||
|
/// res = the result code
|
||||||
|
/// base = the base matching value in the StringKey table
|
||||||
|
#define LOOKUP_ENUM(res, base) StringLookup::Lookup( \
|
||||||
|
static_cast<StringLookup::StringKey>((int) res + (int) StringLookup::base))
|
||||||
|
|
||||||
namespace QtCommon::StringLookup {
|
namespace QtCommon::StringLookup {
|
||||||
|
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,7 @@ enum class FirmwareInstallResult {
|
||||||
|
|
||||||
inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result)
|
inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result)
|
||||||
{
|
{
|
||||||
return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>(
|
return LOOKUP_ENUM(result, FwInstallSuccess);
|
||||||
(int) result + (int) QtCommon::StringLookup::FwInstallSuccess));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,9 +35,7 @@ inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result
|
||||||
*/
|
*/
|
||||||
inline const QString GetKeyInstallResultString(FirmwareManager::KeyInstallResult result)
|
inline const QString GetKeyInstallResultString(FirmwareManager::KeyInstallResult result)
|
||||||
{
|
{
|
||||||
// this can probably be made into a common function of sorts
|
return LOOKUP_ENUM(result, KeyInstallSuccess);
|
||||||
return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>(
|
|
||||||
(int) result + (int) QtCommon::StringLookup::KeyInstallSuccess));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallFirmware(const QString &location, bool recursive);
|
void InstallFirmware(const QString &location, bool recursive);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "fs.h"
|
|
||||||
#include "common/fs/ryujinx_compat.h"
|
#include "common/fs/ryujinx_compat.h"
|
||||||
#include "common/fs/symlink.h"
|
#include "common/fs/symlink.h"
|
||||||
#include "frontend_common/data_manager.h"
|
#include "fs.h"
|
||||||
#include "qt_common/abstract/frontend.h"
|
#include "qt_common/abstract/frontend.h"
|
||||||
#include "qt_common/qt_string_lookup.h"
|
#include "qt_common/qt_string_lookup.h"
|
||||||
|
|
||||||
|
|
@ -56,6 +56,9 @@ bool CheckUnlink(const fs::path &eden_dir, const fs::path &ryu_dir)
|
||||||
orig = eden_dir;
|
orig = eden_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linked.make_preferred();
|
||||||
|
orig.make_preferred();
|
||||||
|
|
||||||
// first cleanup the symlink/junction,
|
// first cleanup the symlink/junction,
|
||||||
try {
|
try {
|
||||||
// NB: do NOT use remove_all, as Windows treats this as a remove_all to the target,
|
// NB: do NOT use remove_all, as Windows treats this as a remove_all to the target,
|
||||||
|
|
@ -84,47 +87,64 @@ bool CheckUnlink(const fs::path &eden_dir, const fs::path &ryu_dir)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetRyujinxSaveID(const u64 &program_id)
|
const fs::path GetRyujinxSavePath(const fs::path &path_hint, const u64 &program_id)
|
||||||
{
|
{
|
||||||
auto path = Common::FS::GetKvdbPath();
|
auto ryu_path = path_hint;
|
||||||
|
|
||||||
|
auto kvdb_path = Common::FS::GetKvdbPath(ryu_path);
|
||||||
|
|
||||||
|
if (!fs::exists(kvdb_path)) {
|
||||||
|
using namespace QtCommon::Frontend;
|
||||||
|
auto res = Warning(
|
||||||
|
tr("Could not find Ryujinx installation"),
|
||||||
|
tr("Could not find a valid Ryujinx installation. This may typically occur if you are "
|
||||||
|
"using Ryujinx in portable mode.\n\nWould you like to manually select a portable "
|
||||||
|
"folder to use?"), StandardButton::Yes | StandardButton::No);
|
||||||
|
|
||||||
|
if (res == StandardButton::Yes) {
|
||||||
|
auto selected_path = GetExistingDirectory(tr("Ryujinx Portable Location"), QDir::homePath()).toStdString();
|
||||||
|
if (selected_path.empty())
|
||||||
|
return fs::path{};
|
||||||
|
|
||||||
|
ryu_path = selected_path;
|
||||||
|
|
||||||
|
// In case the user selects the actual ryujinx installation dir INSTEAD OF
|
||||||
|
// the portable dir
|
||||||
|
if (fs::exists(ryu_path / "portable")) {
|
||||||
|
ryu_path = ryu_path / "portable";
|
||||||
|
}
|
||||||
|
|
||||||
|
kvdb_path = Common::FS::GetKvdbPath(ryu_path);
|
||||||
|
|
||||||
|
if (!fs::exists(kvdb_path)) {
|
||||||
|
QtCommon::Frontend::Critical(
|
||||||
|
tr("Not a valid Ryujinx directory"),
|
||||||
|
tr("The specified directory does not contain valid Ryujinx data."));
|
||||||
|
return fs::path{};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fs::path{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Common::FS::IMEN> imens;
|
std::vector<Common::FS::IMEN> imens;
|
||||||
Common::FS::IMENReadResult res = Common::FS::ReadKvdb(path, imens);
|
Common::FS::IMENReadResult res = Common::FS::ReadKvdb(kvdb_path, imens);
|
||||||
|
|
||||||
if (res == Common::FS::IMENReadResult::Success) {
|
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) {
|
for (const Common::FS::IMEN &imen : imens) {
|
||||||
if (imen.title_id == program_id)
|
if (imen.title_id == program_id)
|
||||||
return imen.save_id;
|
return Common::FS::GetRyuSavePath(ryu_path, imen.save_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
QtCommon::Frontend::Critical(
|
QtCommon::Frontend::Critical(
|
||||||
tr("Could not find Ryujinx save data"),
|
tr("Could not find Ryujinx save data"),
|
||||||
StringLookup::Lookup(StringLookup::RyujinxNoSaveId).arg(program_id, 0, 16));
|
StringLookup::Lookup(StringLookup::RyujinxNoSaveId).arg(program_id, 0, 16));
|
||||||
} else {
|
} else {
|
||||||
// TODO: make this long thing a function or something
|
QString caption = LOOKUP_ENUM(res, KvdbNonexistent);
|
||||||
QString caption = StringLookup::Lookup(
|
|
||||||
static_cast<StringLookup::StringKey>((int) res + (int) StringLookup::KvdbNonexistent));
|
|
||||||
QtCommon::Frontend::Critical(tr("Could not find Ryujinx save data"), caption);
|
QtCommon::Frontend::Critical(tr("Could not find Ryujinx save data"), caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return fs::path{};
|
||||||
}
|
|
||||||
|
|
||||||
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
|
} // namespace QtCommon::FS
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,10 @@
|
||||||
namespace QtCommon::FS {
|
namespace QtCommon::FS {
|
||||||
|
|
||||||
void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to);
|
void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to);
|
||||||
u64 GetRyujinxSaveID(const u64 &program_id);
|
const std::filesystem::path GetRyujinxSavePath(const std::filesystem::path &path_hint, 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
|
/// returns FALSE if the dirs are NOT linked
|
||||||
bool CheckUnlink(const std::filesystem::path &eden_dir, const std::filesystem::path &ryu_dir);
|
bool CheckUnlink(const std::filesystem::path& eden_dir,
|
||||||
|
const std::filesystem::path& ryu_dir);
|
||||||
|
|
||||||
} // namespace QtCommon::FS
|
} // namespace QtCommon::FS
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ if (YUZU_USE_BUNDLED_QT AND PLATFORM_LINUX)
|
||||||
set(CMAKE_BUILD_RPATH "${CMAKE_BINARY_DIR}/bin/lib/")
|
set(CMAKE_BUILD_RPATH "${CMAKE_BINARY_DIR}/bin/lib/")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Widgets)
|
||||||
|
|
||||||
add_executable(yuzu
|
add_executable(yuzu
|
||||||
Info.plist
|
Info.plist
|
||||||
about_dialog.cpp
|
about_dialog.cpp
|
||||||
|
|
@ -169,9 +171,9 @@ add_executable(yuzu
|
||||||
loading_screen.cpp
|
loading_screen.cpp
|
||||||
loading_screen.h
|
loading_screen.h
|
||||||
loading_screen.ui
|
loading_screen.ui
|
||||||
|
|
||||||
main.cpp
|
main.cpp
|
||||||
main.h
|
|
||||||
main.ui
|
|
||||||
multiplayer/chat_room.cpp
|
multiplayer/chat_room.cpp
|
||||||
multiplayer/chat_room.h
|
multiplayer/chat_room.h
|
||||||
multiplayer/chat_room.ui
|
multiplayer/chat_room.ui
|
||||||
|
|
@ -235,6 +237,7 @@ add_executable(yuzu
|
||||||
data_dialog.h data_dialog.cpp data_dialog.ui
|
data_dialog.h data_dialog.cpp data_dialog.ui
|
||||||
data_widget.ui
|
data_widget.ui
|
||||||
ryujinx_dialog.h ryujinx_dialog.cpp ryujinx_dialog.ui
|
ryujinx_dialog.h ryujinx_dialog.cpp ryujinx_dialog.ui
|
||||||
|
main_window.h main_window.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")
|
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")
|
||||||
|
|
@ -441,6 +444,7 @@ endif()
|
||||||
|
|
||||||
if (YUZU_ROOM)
|
if (YUZU_ROOM)
|
||||||
target_link_libraries(yuzu PRIVATE yuzu-room)
|
target_link_libraries(yuzu PRIVATE yuzu-room)
|
||||||
|
target_link_libraries(yuzu PRIVATE Qt6::Widgets)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
create_target_directory_groups(yuzu)
|
create_target_directory_groups(yuzu)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -18,7 +21,7 @@
|
||||||
#include "web_service/web_backend.h"
|
#include "web_service/web_backend.h"
|
||||||
#endif
|
#endif
|
||||||
#include "yuzu/applets/qt_amiibo_settings.h"
|
#include "yuzu/applets/qt_amiibo_settings.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
|
|
||||||
QtAmiiboSettingsDialog::QtAmiiboSettingsDialog(QWidget* parent,
|
QtAmiiboSettingsDialog::QtAmiiboSettingsDialog(QWidget* parent,
|
||||||
Core::Frontend::CabinetParameters parameters_,
|
Core::Frontend::CabinetParameters parameters_,
|
||||||
|
|
@ -244,12 +247,12 @@ void QtAmiiboSettingsDialog::SetSettingsDescription() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QtAmiiboSettings::QtAmiiboSettings(GMainWindow& parent) {
|
QtAmiiboSettings::QtAmiiboSettings(MainWindow& parent) {
|
||||||
connect(this, &QtAmiiboSettings::MainWindowShowAmiiboSettings, &parent,
|
connect(this, &QtAmiiboSettings::MainWindowShowAmiiboSettings, &parent,
|
||||||
&GMainWindow::AmiiboSettingsShowDialog, Qt::QueuedConnection);
|
&MainWindow::AmiiboSettingsShowDialog, Qt::QueuedConnection);
|
||||||
connect(this, &QtAmiiboSettings::MainWindowRequestExit, &parent,
|
connect(this, &QtAmiiboSettings::MainWindowRequestExit, &parent,
|
||||||
&GMainWindow::AmiiboSettingsRequestExit, Qt::QueuedConnection);
|
&MainWindow::AmiiboSettingsRequestExit, Qt::QueuedConnection);
|
||||||
connect(&parent, &GMainWindow::AmiiboSettingsFinished, this,
|
connect(&parent, &MainWindow::AmiiboSettingsFinished, this,
|
||||||
&QtAmiiboSettings::MainWindowFinished, Qt::QueuedConnection);
|
&QtAmiiboSettings::MainWindowFinished, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -8,7 +11,7 @@
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "core/frontend/applets/cabinet.h"
|
#include "core/frontend/applets/cabinet.h"
|
||||||
|
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
|
|
@ -65,7 +68,7 @@ class QtAmiiboSettings final : public QObject, public Core::Frontend::CabinetApp
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QtAmiiboSettings(GMainWindow& parent);
|
explicit QtAmiiboSettings(MainWindow& parent);
|
||||||
~QtAmiiboSettings() override;
|
~QtAmiiboSettings() override;
|
||||||
|
|
||||||
void Close() const override;
|
void Close() const override;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
#include "yuzu/configuration/configure_motion_touch.h"
|
#include "yuzu/configuration/configure_motion_touch.h"
|
||||||
#include "yuzu/configuration/configure_vibration.h"
|
#include "yuzu/configuration/configure_vibration.h"
|
||||||
#include "yuzu/configuration/input_profiles.h"
|
#include "yuzu/configuration/input_profiles.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/util/controller_navigation.h"
|
#include "yuzu/util/controller_navigation.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
@ -753,12 +753,12 @@ void QtControllerSelectorDialog::DisableUnsupportedPlayers() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QtControllerSelector::QtControllerSelector(GMainWindow& parent) {
|
QtControllerSelector::QtControllerSelector(MainWindow& parent) {
|
||||||
connect(this, &QtControllerSelector::MainWindowReconfigureControllers, &parent,
|
connect(this, &QtControllerSelector::MainWindowReconfigureControllers, &parent,
|
||||||
&GMainWindow::ControllerSelectorReconfigureControllers, Qt::QueuedConnection);
|
&MainWindow::ControllerSelectorReconfigureControllers, Qt::QueuedConnection);
|
||||||
connect(this, &QtControllerSelector::MainWindowRequestExit, &parent,
|
connect(this, &QtControllerSelector::MainWindowRequestExit, &parent,
|
||||||
&GMainWindow::ControllerSelectorRequestExit, Qt::QueuedConnection);
|
&MainWindow::ControllerSelectorRequestExit, Qt::QueuedConnection);
|
||||||
connect(&parent, &GMainWindow::ControllerSelectorReconfigureFinished, this,
|
connect(&parent, &MainWindow::ControllerSelectorReconfigureFinished, this,
|
||||||
&QtControllerSelector::MainWindowReconfigureFinished, Qt::QueuedConnection);
|
&QtControllerSelector::MainWindowReconfigureFinished, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -8,7 +11,7 @@
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "core/frontend/applets/controller.h"
|
#include "core/frontend/applets/controller.h"
|
||||||
|
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
|
|
@ -163,7 +166,7 @@ class QtControllerSelector final : public QObject, public Core::Frontend::Contro
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QtControllerSelector(GMainWindow& parent);
|
explicit QtControllerSelector(MainWindow& parent);
|
||||||
~QtControllerSelector() override;
|
~QtControllerSelector() override;
|
||||||
|
|
||||||
void Close() const override;
|
void Close() const override;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include "yuzu/applets/qt_error.h"
|
#include "yuzu/applets/qt_error.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
|
|
||||||
QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) {
|
QtErrorDisplay::QtErrorDisplay(MainWindow& parent) {
|
||||||
connect(this, &QtErrorDisplay::MainWindowDisplayError, &parent,
|
connect(this, &QtErrorDisplay::MainWindowDisplayError, &parent,
|
||||||
&GMainWindow::ErrorDisplayDisplayError, Qt::QueuedConnection);
|
&MainWindow::ErrorDisplayDisplayError, Qt::QueuedConnection);
|
||||||
connect(this, &QtErrorDisplay::MainWindowRequestExit, &parent,
|
connect(this, &QtErrorDisplay::MainWindowRequestExit, &parent,
|
||||||
&GMainWindow::ErrorDisplayRequestExit, Qt::QueuedConnection);
|
&MainWindow::ErrorDisplayRequestExit, Qt::QueuedConnection);
|
||||||
connect(&parent, &GMainWindow::ErrorDisplayFinished, this,
|
connect(&parent, &MainWindow::ErrorDisplayFinished, this,
|
||||||
&QtErrorDisplay::MainWindowFinishedError, Qt::DirectConnection);
|
&QtErrorDisplay::MainWindowFinishedError, Qt::DirectConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -7,13 +10,13 @@
|
||||||
|
|
||||||
#include "core/frontend/applets/error.h"
|
#include "core/frontend/applets/error.h"
|
||||||
|
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
|
|
||||||
class QtErrorDisplay final : public QObject, public Core::Frontend::ErrorApplet {
|
class QtErrorDisplay final : public QObject, public Core::Frontend::ErrorApplet {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QtErrorDisplay(GMainWindow& parent);
|
explicit QtErrorDisplay(MainWindow& parent);
|
||||||
~QtErrorDisplay() override;
|
~QtErrorDisplay() override;
|
||||||
|
|
||||||
void Close() const override;
|
void Close() const override;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "yuzu/applets/qt_profile_select.h"
|
#include "yuzu/applets/qt_profile_select.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/util/controller_navigation.h"
|
#include "yuzu/util/controller_navigation.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
@ -230,12 +230,12 @@ void QtProfileSelectionDialog::SetDialogPurpose(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QtProfileSelector::QtProfileSelector(GMainWindow& parent) {
|
QtProfileSelector::QtProfileSelector(MainWindow& parent) {
|
||||||
connect(this, &QtProfileSelector::MainWindowSelectProfile, &parent,
|
connect(this, &QtProfileSelector::MainWindowSelectProfile, &parent,
|
||||||
&GMainWindow::ProfileSelectorSelectProfile, Qt::QueuedConnection);
|
&MainWindow::ProfileSelectorSelectProfile, Qt::QueuedConnection);
|
||||||
connect(this, &QtProfileSelector::MainWindowRequestExit, &parent,
|
connect(this, &QtProfileSelector::MainWindowRequestExit, &parent,
|
||||||
&GMainWindow::ProfileSelectorRequestExit, Qt::QueuedConnection);
|
&MainWindow::ProfileSelectorRequestExit, Qt::QueuedConnection);
|
||||||
connect(&parent, &GMainWindow::ProfileSelectorFinishedSelection, this,
|
connect(&parent, &MainWindow::ProfileSelectorFinishedSelection, this,
|
||||||
&QtProfileSelector::MainWindowFinishedSelection, Qt::DirectConnection);
|
&QtProfileSelector::MainWindowFinishedSelection, Qt::DirectConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -9,7 +12,7 @@
|
||||||
#include "core/frontend/applets/profile_select.h"
|
#include "core/frontend/applets/profile_select.h"
|
||||||
|
|
||||||
class ControllerNavigation;
|
class ControllerNavigation;
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class QGraphicsScene;
|
class QGraphicsScene;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
|
@ -69,7 +72,7 @@ class QtProfileSelector final : public QObject, public Core::Frontend::ProfileSe
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QtProfileSelector(GMainWindow& parent);
|
explicit QtProfileSelector(MainWindow& parent);
|
||||||
~QtProfileSelector() override;
|
~QtProfileSelector() override;
|
||||||
|
|
||||||
void Close() const override;
|
void Close() const override;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -15,7 +18,7 @@
|
||||||
#include "hid_core/hid_types.h"
|
#include "hid_core/hid_types.h"
|
||||||
#include "ui_qt_software_keyboard.h"
|
#include "ui_qt_software_keyboard.h"
|
||||||
#include "yuzu/applets/qt_software_keyboard.h"
|
#include "yuzu/applets/qt_software_keyboard.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/util/overlay_dialog.h"
|
#include "yuzu/util/overlay_dialog.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
@ -1541,24 +1544,24 @@ void QtSoftwareKeyboardDialog::InputThread() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& main_window) {
|
QtSoftwareKeyboard::QtSoftwareKeyboard(MainWindow& main_window) {
|
||||||
connect(this, &QtSoftwareKeyboard::MainWindowInitializeKeyboard, &main_window,
|
connect(this, &QtSoftwareKeyboard::MainWindowInitializeKeyboard, &main_window,
|
||||||
&GMainWindow::SoftwareKeyboardInitialize, Qt::QueuedConnection);
|
&MainWindow::SoftwareKeyboardInitialize, Qt::QueuedConnection);
|
||||||
connect(this, &QtSoftwareKeyboard::MainWindowShowNormalKeyboard, &main_window,
|
connect(this, &QtSoftwareKeyboard::MainWindowShowNormalKeyboard, &main_window,
|
||||||
&GMainWindow::SoftwareKeyboardShowNormal, Qt::QueuedConnection);
|
&MainWindow::SoftwareKeyboardShowNormal, Qt::QueuedConnection);
|
||||||
connect(this, &QtSoftwareKeyboard::MainWindowShowTextCheckDialog, &main_window,
|
connect(this, &QtSoftwareKeyboard::MainWindowShowTextCheckDialog, &main_window,
|
||||||
&GMainWindow::SoftwareKeyboardShowTextCheck, Qt::QueuedConnection);
|
&MainWindow::SoftwareKeyboardShowTextCheck, Qt::QueuedConnection);
|
||||||
connect(this, &QtSoftwareKeyboard::MainWindowShowInlineKeyboard, &main_window,
|
connect(this, &QtSoftwareKeyboard::MainWindowShowInlineKeyboard, &main_window,
|
||||||
&GMainWindow::SoftwareKeyboardShowInline, Qt::QueuedConnection);
|
&MainWindow::SoftwareKeyboardShowInline, Qt::QueuedConnection);
|
||||||
connect(this, &QtSoftwareKeyboard::MainWindowHideInlineKeyboard, &main_window,
|
connect(this, &QtSoftwareKeyboard::MainWindowHideInlineKeyboard, &main_window,
|
||||||
&GMainWindow::SoftwareKeyboardHideInline, Qt::QueuedConnection);
|
&MainWindow::SoftwareKeyboardHideInline, Qt::QueuedConnection);
|
||||||
connect(this, &QtSoftwareKeyboard::MainWindowInlineTextChanged, &main_window,
|
connect(this, &QtSoftwareKeyboard::MainWindowInlineTextChanged, &main_window,
|
||||||
&GMainWindow::SoftwareKeyboardInlineTextChanged, Qt::QueuedConnection);
|
&MainWindow::SoftwareKeyboardInlineTextChanged, Qt::QueuedConnection);
|
||||||
connect(this, &QtSoftwareKeyboard::MainWindowExitKeyboard, &main_window,
|
connect(this, &QtSoftwareKeyboard::MainWindowExitKeyboard, &main_window,
|
||||||
&GMainWindow::SoftwareKeyboardExit, Qt::QueuedConnection);
|
&MainWindow::SoftwareKeyboardExit, Qt::QueuedConnection);
|
||||||
connect(&main_window, &GMainWindow::SoftwareKeyboardSubmitNormalText, this,
|
connect(&main_window, &MainWindow::SoftwareKeyboardSubmitNormalText, this,
|
||||||
&QtSoftwareKeyboard::SubmitNormalText, Qt::QueuedConnection);
|
&QtSoftwareKeyboard::SubmitNormalText, Qt::QueuedConnection);
|
||||||
connect(&main_window, &GMainWindow::SoftwareKeyboardSubmitInlineText, this,
|
connect(&main_window, &MainWindow::SoftwareKeyboardSubmitInlineText, this,
|
||||||
&QtSoftwareKeyboard::SubmitInlineText, Qt::QueuedConnection);
|
&QtSoftwareKeyboard::SubmitInlineText, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -27,7 +30,7 @@ namespace Ui {
|
||||||
class QtSoftwareKeyboardDialog;
|
class QtSoftwareKeyboardDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
|
|
||||||
class QtSoftwareKeyboardDialog final : public QDialog {
|
class QtSoftwareKeyboardDialog final : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -230,7 +233,7 @@ class QtSoftwareKeyboard final : public QObject, public Core::Frontend::Software
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QtSoftwareKeyboard(GMainWindow& parent);
|
explicit QtSoftwareKeyboard(MainWindow& parent);
|
||||||
~QtSoftwareKeyboard() override;
|
~QtSoftwareKeyboard() override;
|
||||||
|
|
||||||
void Close() const override {
|
void Close() const override {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -18,7 +21,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "yuzu/applets/qt_web_browser.h"
|
#include "yuzu/applets/qt_web_browser.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
|
|
||||||
#ifdef YUZU_USE_QT_WEB_ENGINE
|
#ifdef YUZU_USE_QT_WEB_ENGINE
|
||||||
|
|
||||||
|
|
@ -391,14 +394,14 @@ void QtNXWebEngineView::FocusFirstLinkElement() {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {
|
QtWebBrowser::QtWebBrowser(MainWindow& main_window) {
|
||||||
connect(this, &QtWebBrowser::MainWindowOpenWebPage, &main_window,
|
connect(this, &QtWebBrowser::MainWindowOpenWebPage, &main_window,
|
||||||
&GMainWindow::WebBrowserOpenWebPage, Qt::QueuedConnection);
|
&MainWindow::WebBrowserOpenWebPage, Qt::QueuedConnection);
|
||||||
connect(this, &QtWebBrowser::MainWindowRequestExit, &main_window,
|
connect(this, &QtWebBrowser::MainWindowRequestExit, &main_window,
|
||||||
&GMainWindow::WebBrowserRequestExit, Qt::QueuedConnection);
|
&MainWindow::WebBrowserRequestExit, Qt::QueuedConnection);
|
||||||
connect(&main_window, &GMainWindow::WebBrowserExtractOfflineRomFS, this,
|
connect(&main_window, &MainWindow::WebBrowserExtractOfflineRomFS, this,
|
||||||
&QtWebBrowser::MainWindowExtractOfflineRomFS, Qt::QueuedConnection);
|
&QtWebBrowser::MainWindowExtractOfflineRomFS, Qt::QueuedConnection);
|
||||||
connect(&main_window, &GMainWindow::WebBrowserClosed, this,
|
connect(&main_window, &MainWindow::WebBrowserClosed, this,
|
||||||
&QtWebBrowser::MainWindowWebBrowserClosed, Qt::QueuedConnection);
|
&QtWebBrowser::MainWindowWebBrowserClosed, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -14,7 +17,7 @@
|
||||||
|
|
||||||
#include "core/frontend/applets/web_browser.h"
|
#include "core/frontend/applets/web_browser.h"
|
||||||
|
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
class InputInterpreter;
|
class InputInterpreter;
|
||||||
class UrlRequestInterceptor;
|
class UrlRequestInterceptor;
|
||||||
|
|
||||||
|
|
@ -193,7 +196,7 @@ class QtWebBrowser final : public QObject, public Core::Frontend::WebBrowserAppl
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QtWebBrowser(GMainWindow& parent);
|
explicit QtWebBrowser(MainWindow& parent);
|
||||||
~QtWebBrowser() override;
|
~QtWebBrowser() override;
|
||||||
|
|
||||||
void Close() const override;
|
void Close() const override;
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
#include "video_core/rasterizer_interface.h"
|
#include "video_core/rasterizer_interface.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "yuzu/bootmanager.h"
|
#include "yuzu/bootmanager.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "qt_common/qt_common.h"
|
#include "qt_common/qt_common.h"
|
||||||
|
|
||||||
class QObject;
|
class QObject;
|
||||||
|
|
@ -272,7 +272,7 @@ struct NullRenderWidget : public RenderWidget {
|
||||||
explicit NullRenderWidget(GRenderWindow* parent) : RenderWidget(parent) {}
|
explicit NullRenderWidget(GRenderWindow* parent) : RenderWidget(parent) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
GRenderWindow::GRenderWindow(MainWindow* parent, EmuThread* emu_thread_,
|
||||||
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
||||||
Core::System& system_)
|
Core::System& system_)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
|
|
@ -290,11 +290,11 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
||||||
strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland") ||
|
strict_context_required = QGuiApplication::platformName() == QStringLiteral("wayland") ||
|
||||||
QGuiApplication::platformName() == QStringLiteral("wayland-egl");
|
QGuiApplication::platformName() == QStringLiteral("wayland-egl");
|
||||||
|
|
||||||
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
|
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &MainWindow::OnLoadComplete);
|
||||||
connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
|
connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &MainWindow::OnExecuteProgram,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection);
|
connect(this, &GRenderWindow::ExitSignal, parent, &MainWindow::OnExit, Qt::QueuedConnection);
|
||||||
connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged);
|
connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &MainWindow::OnTasStateChanged);
|
||||||
|
|
||||||
mouse_constrain_timer.setInterval(default_mouse_constrain_timeout);
|
mouse_constrain_timer.setInterval(default_mouse_constrain_timeout);
|
||||||
connect(&mouse_constrain_timer, &QTimer::timeout, this, &GRenderWindow::ConstrainMouse);
|
connect(&mouse_constrain_timer, &QTimer::timeout, this, &GRenderWindow::ConstrainMouse);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -29,7 +32,7 @@
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
|
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
class QCamera;
|
class QCamera;
|
||||||
class QCameraImageCapture;
|
class QCameraImageCapture;
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
|
|
@ -146,7 +149,7 @@ class GRenderWindow : public QWidget, public Core::Frontend::EmuWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
explicit GRenderWindow(MainWindow* parent, EmuThread* emu_thread_,
|
||||||
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
||||||
Core::System& system_);
|
Core::System& system_);
|
||||||
~GRenderWindow() override;
|
~GRenderWindow() override;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "data_dialog.h"
|
#include "data_dialog.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
|
||||||
#include "frontend_common/data_manager.h"
|
#include "frontend_common/data_manager.h"
|
||||||
#include "qt_common/qt_common.h"
|
|
||||||
#include "qt_common/util/content.h"
|
#include "qt_common/util/content.h"
|
||||||
#include "qt_common/qt_string_lookup.h"
|
#include "qt_common/qt_string_lookup.h"
|
||||||
#include "ui_data_dialog.h"
|
#include "ui_data_dialog.h"
|
||||||
|
#include "util/util.h"
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
@ -26,17 +25,18 @@ DataDialog::DataDialog(QWidget *parent)
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
// TODO: Should we make this a single widget that pulls data from a model?
|
// TODO: Should we make this a single widget that pulls data from a model?
|
||||||
#define WIDGET(name) \
|
#define WIDGET(label, name) \
|
||||||
ui->page->addWidget(new DataWidget(FrontendCommon::DataManager::DataDir::name, \
|
ui->page->addWidget(new DataWidget(FrontendCommon::DataManager::DataDir::name, \
|
||||||
QtCommon::StringLookup::name##Tooltip, \
|
QtCommon::StringLookup::name##Tooltip, \
|
||||||
QStringLiteral(#name), \
|
QStringLiteral(#name), \
|
||||||
this));
|
this)); \
|
||||||
|
ui->labels->addItem(label);
|
||||||
|
|
||||||
WIDGET(Shaders)
|
WIDGET(tr("Shaders"), Shaders)
|
||||||
WIDGET(UserNand)
|
WIDGET(tr("UserNAND"), UserNand)
|
||||||
WIDGET(SysNand)
|
WIDGET(tr("SysNAND"), SysNand)
|
||||||
WIDGET(Mods)
|
WIDGET(tr("Mods"), Mods)
|
||||||
WIDGET(Saves)
|
WIDGET(tr("Saves"), Saves)
|
||||||
|
|
||||||
#undef WIDGET
|
#undef WIDGET
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ void DataWidget::clear()
|
||||||
{
|
{
|
||||||
std::string user_id{};
|
std::string user_id{};
|
||||||
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
||||||
user_id = selectProfile();
|
user_id = GetProfileIDString();
|
||||||
}
|
}
|
||||||
QtCommon::Content::ClearDataDir(m_dir, user_id);
|
QtCommon::Content::ClearDataDir(m_dir, user_id);
|
||||||
scan();
|
scan();
|
||||||
|
|
@ -92,7 +92,7 @@ void DataWidget::open()
|
||||||
{
|
{
|
||||||
std::string user_id{};
|
std::string user_id{};
|
||||||
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
||||||
user_id = selectProfile();
|
user_id = GetProfileIDString();
|
||||||
}
|
}
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||||
QString::fromStdString(FrontendCommon::DataManager::GetDataDirString(m_dir, user_id))));
|
QString::fromStdString(FrontendCommon::DataManager::GetDataDirString(m_dir, user_id))));
|
||||||
|
|
@ -102,7 +102,7 @@ void DataWidget::upload()
|
||||||
{
|
{
|
||||||
std::string user_id{};
|
std::string user_id{};
|
||||||
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
||||||
user_id = selectProfile();
|
user_id = GetProfileIDString();
|
||||||
}
|
}
|
||||||
QtCommon::Content::ExportDataDir(m_dir, user_id, m_exportName);
|
QtCommon::Content::ExportDataDir(m_dir, user_id, m_exportName);
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +111,7 @@ void DataWidget::download()
|
||||||
{
|
{
|
||||||
std::string user_id{};
|
std::string user_id{};
|
||||||
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
|
||||||
user_id = selectProfile();
|
user_id = GetProfileIDString();
|
||||||
}
|
}
|
||||||
QtCommon::Content::ImportDataDir(m_dir, user_id, std::bind(&DataWidget::scan, this));
|
QtCommon::Content::ImportDataDir(m_dir, user_id, std::bind(&DataWidget::scan, this));
|
||||||
}
|
}
|
||||||
|
|
@ -131,37 +131,3 @@ void DataWidget::scan() {
|
||||||
watcher->setFuture(
|
watcher->setFuture(
|
||||||
QtConcurrent::run([this]() { return FrontendCommon::DataManager::DataDirSize(m_dir); }));
|
QtConcurrent::run([this]() { return FrontendCommon::DataManager::DataDirSize(m_dir); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataWidget::selectProfile()
|
|
||||||
{
|
|
||||||
const auto select_profile = [this] {
|
|
||||||
const Core::Frontend::ProfileSelectParameters parameters{
|
|
||||||
.mode = Service::AM::Frontend::UiMode::UserSelector,
|
|
||||||
.invalid_uid_list = {},
|
|
||||||
.display_options = {},
|
|
||||||
.purpose = Service::AM::Frontend::UserSelectionPurpose::General,
|
|
||||||
};
|
|
||||||
QtProfileSelectionDialog dialog(*QtCommon::system, this, parameters);
|
|
||||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint
|
|
||||||
| Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
|
|
||||||
dialog.setWindowModality(Qt::WindowModal);
|
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Rejected) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dialog.GetIndex();
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto index = select_profile();
|
|
||||||
if (index == -1) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto uuid = QtCommon::system->GetProfileManager().GetUser(static_cast<std::size_t>(index));
|
|
||||||
ASSERT(uuid);
|
|
||||||
|
|
||||||
const auto user_id = uuid->AsU128();
|
|
||||||
|
|
||||||
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -36,31 +36,6 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Shaders</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>UserNAND</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>SysNAND</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Mods</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Saves</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ DepsDialog::DepsDialog(QWidget* parent)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
constexpr size_t rows = Common::dep_hashes.size();
|
constexpr int rows = (int) Common::dep_hashes.size();
|
||||||
ui->tableDeps->setRowCount(rows);
|
ui->tableDeps->setRowCount(rows);
|
||||||
|
|
||||||
QStringList labels;
|
QStringList labels;
|
||||||
|
|
@ -29,7 +29,7 @@ DepsDialog::DepsDialog(QWidget* parent)
|
||||||
ui->tableDeps->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeMode::Fixed);
|
ui->tableDeps->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeMode::Fixed);
|
||||||
ui->tableDeps->horizontalHeader()->setMinimumSectionSize(200);
|
ui->tableDeps->horizontalHeader()->setMinimumSectionSize(200);
|
||||||
|
|
||||||
for (size_t i = 0; i < rows; ++i) {
|
for (int i = 0; i < rows; ++i) {
|
||||||
const std::string name = Common::dep_names.at(i);
|
const std::string name = Common::dep_names.at(i);
|
||||||
const std::string sha = Common::dep_hashes.at(i);
|
const std::string sha = Common::dep_hashes.at(i);
|
||||||
const std::string url = Common::dep_urls.at(i);
|
const std::string url = Common::dep_urls.at(i);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include "yuzu/compatibility_list.h"
|
#include "yuzu/compatibility_list.h"
|
||||||
#include "yuzu/game_list_p.h"
|
#include "yuzu/game_list_p.h"
|
||||||
#include "yuzu/game_list_worker.h"
|
#include "yuzu/game_list_worker.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/util/controller_navigation.h"
|
#include "yuzu/util/controller_navigation.h"
|
||||||
#include <fmt/ranges.h>
|
#include <fmt/ranges.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
@ -314,7 +314,7 @@ void GameList::OnFilterCloseClicked() {
|
||||||
|
|
||||||
GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvider* provider_,
|
GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvider* provider_,
|
||||||
PlayTime::PlayTimeManager& play_time_manager_, Core::System& system_,
|
PlayTime::PlayTimeManager& play_time_manager_, Core::System& system_,
|
||||||
GMainWindow* parent)
|
MainWindow* parent)
|
||||||
: QWidget{parent}, vfs{std::move(vfs_)}, provider{provider_},
|
: QWidget{parent}, vfs{std::move(vfs_)}, provider{provider_},
|
||||||
play_time_manager{play_time_manager_}, system{system_} {
|
play_time_manager{play_time_manager_}, system{system_} {
|
||||||
watcher = new QFileSystemWatcher(this);
|
watcher = new QFileSystemWatcher(this);
|
||||||
|
|
@ -347,7 +347,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid
|
||||||
tree_view->setColumnHidden(COLUMN_PLAY_TIME, !UISettings::values.show_play_time);
|
tree_view->setColumnHidden(COLUMN_PLAY_TIME, !UISettings::values.show_play_time);
|
||||||
item_model->setSortRole(GameListItemPath::SortRole);
|
item_model->setSortRole(GameListItemPath::SortRole);
|
||||||
|
|
||||||
connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons);
|
connect(main_window, &MainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons);
|
||||||
connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry);
|
connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry);
|
||||||
connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
|
connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
|
||||||
connect(tree_view, &QTreeView::expanded, this, &GameList::OnItemExpanded);
|
connect(tree_view, &QTreeView::expanded, this, &GameList::OnItemExpanded);
|
||||||
|
|
@ -943,8 +943,8 @@ void GameList::RemoveFavorite(u64 program_id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} {
|
GameListPlaceholder::GameListPlaceholder(MainWindow* parent) : QWidget{parent} {
|
||||||
connect(parent, &GMainWindow::UpdateThemedIcons, this,
|
connect(parent, &MainWindow::UpdateThemedIcons, this,
|
||||||
&GameListPlaceholder::onUpdateThemedIcons);
|
&GameListPlaceholder::onUpdateThemedIcons);
|
||||||
|
|
||||||
layout = new QVBoxLayout;
|
layout = new QVBoxLayout;
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class ControllerNavigation;
|
||||||
class GameListWorker;
|
class GameListWorker;
|
||||||
class GameListSearchField;
|
class GameListSearchField;
|
||||||
class GameListDir;
|
class GameListDir;
|
||||||
class GMainWindow;
|
class MainWindow;
|
||||||
enum class AmLaunchType;
|
enum class AmLaunchType;
|
||||||
enum class StartGameType;
|
enum class StartGameType;
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ public:
|
||||||
explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs_,
|
explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs_,
|
||||||
FileSys::ManualContentProvider* provider_,
|
FileSys::ManualContentProvider* provider_,
|
||||||
PlayTime::PlayTimeManager& play_time_manager_, Core::System& system_,
|
PlayTime::PlayTimeManager& play_time_manager_, Core::System& system_,
|
||||||
GMainWindow* parent = nullptr);
|
MainWindow* parent = nullptr);
|
||||||
~GameList() override;
|
~GameList() override;
|
||||||
|
|
||||||
QString GetLastFilterResultItem() const;
|
QString GetLastFilterResultItem() const;
|
||||||
|
|
@ -153,7 +153,7 @@ private:
|
||||||
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
||||||
FileSys::ManualContentProvider* provider;
|
FileSys::ManualContentProvider* provider;
|
||||||
GameListSearchField* search_field;
|
GameListSearchField* search_field;
|
||||||
GMainWindow* main_window = nullptr;
|
MainWindow* main_window = nullptr;
|
||||||
QVBoxLayout* layout = nullptr;
|
QVBoxLayout* layout = nullptr;
|
||||||
QTreeView* tree_view = nullptr;
|
QTreeView* tree_view = nullptr;
|
||||||
QStandardItemModel* item_model = nullptr;
|
QStandardItemModel* item_model = nullptr;
|
||||||
|
|
@ -171,7 +171,7 @@ private:
|
||||||
class GameListPlaceholder : public QWidget {
|
class GameListPlaceholder : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit GameListPlaceholder(GMainWindow* parent = nullptr);
|
explicit GameListPlaceholder(MainWindow* parent = nullptr);
|
||||||
~GameListPlaceholder();
|
~GameListPlaceholder();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
||||||
4945
src/yuzu/main.cpp
4945
src/yuzu/main.cpp
File diff suppressed because it is too large
Load diff
4899
src/yuzu/main_window.cpp
Normal file
4899
src/yuzu/main_window.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -29,7 +29,7 @@
|
||||||
#include <QDBusObjectPath>
|
#include <QDBusObjectPath>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QtDBus/QDBusInterface>
|
#include <QtDBus/QDBusInterface>
|
||||||
#include <QtDBus/QtDBus>
|
#include <QSocketNotifier>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_UPDATE_CHECKER
|
#ifdef ENABLE_UPDATE_CHECKER
|
||||||
|
|
@ -38,7 +38,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class QtConfig;
|
class QtConfig;
|
||||||
class ClickableLabel;
|
|
||||||
class EmuThread;
|
class EmuThread;
|
||||||
class GameList;
|
class GameList;
|
||||||
class GImageInfo;
|
class GImageInfo;
|
||||||
|
|
@ -154,7 +153,7 @@ private:
|
||||||
constexpr static int MaxMultiplier = 8;
|
constexpr static int MaxMultiplier = 8;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GMainWindow : public QMainWindow {
|
class MainWindow : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
/// Max number of recently loaded items to keep track of
|
/// Max number of recently loaded items to keep track of
|
||||||
|
|
@ -163,8 +162,8 @@ class GMainWindow : public QMainWindow {
|
||||||
public:
|
public:
|
||||||
void filterBarSetChecked(bool state);
|
void filterBarSetChecked(bool state);
|
||||||
void UpdateUITheme();
|
void UpdateUITheme();
|
||||||
explicit GMainWindow(bool has_broken_vulkan);
|
explicit MainWindow(bool has_broken_vulkan);
|
||||||
~GMainWindow() override;
|
~MainWindow() override;
|
||||||
|
|
||||||
bool DropAction(QDropEvent* event);
|
bool DropAction(QDropEvent* event);
|
||||||
void AcceptDropEvent(QDropEvent* event);
|
void AcceptDropEvent(QDropEvent* event);
|
||||||
|
|
@ -470,8 +469,6 @@ private:
|
||||||
QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
|
QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
|
||||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||||
|
|
||||||
std::string GetProfileID();
|
|
||||||
|
|
||||||
std::unique_ptr<Ui::MainWindow> ui;
|
std::unique_ptr<Ui::MainWindow> ui;
|
||||||
|
|
||||||
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
||||||
|
|
@ -11,11 +11,11 @@
|
||||||
|
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
|
|
||||||
MigrationWorker::MigrationWorker(const Emulator selected_legacy_emu_,
|
MigrationWorker::MigrationWorker(const Emulator selected_emu_,
|
||||||
const bool clear_shader_cache_,
|
const bool clear_shader_cache_,
|
||||||
const MigrationStrategy strategy_)
|
const MigrationStrategy strategy_)
|
||||||
: QObject()
|
: QObject()
|
||||||
, selected_legacy_emu(selected_legacy_emu_)
|
, selected_emu(selected_emu_)
|
||||||
, clear_shader_cache(clear_shader_cache_)
|
, clear_shader_cache(clear_shader_cache_)
|
||||||
, strategy(strategy_)
|
, strategy(strategy_)
|
||||||
{}
|
{}
|
||||||
|
|
@ -25,15 +25,20 @@ void MigrationWorker::process()
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
constexpr auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive;
|
constexpr auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive;
|
||||||
|
|
||||||
const fs::path legacy_user_dir = selected_legacy_emu.get_user_dir();
|
const fs::path legacy_user_dir = selected_emu.get_user_dir();
|
||||||
const fs::path legacy_config_dir = selected_legacy_emu.get_config_dir();
|
const fs::path legacy_config_dir = selected_emu.get_config_dir();
|
||||||
const fs::path legacy_cache_dir = selected_legacy_emu.get_cache_dir();
|
const fs::path legacy_cache_dir = selected_emu.get_cache_dir();
|
||||||
|
|
||||||
// TODO(crueter): Make these constexpr since they're defaulted
|
// TODO(crueter): Make these constexpr since they're defaulted
|
||||||
const fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir);
|
fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir);
|
||||||
const fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir);
|
fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir);
|
||||||
const fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir);
|
fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir);
|
||||||
const fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||||
|
|
||||||
|
eden_dir.make_preferred();
|
||||||
|
config_dir.make_preferred();
|
||||||
|
cache_dir.make_preferred();
|
||||||
|
shader_dir.make_preferred();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs::remove_all(eden_dir);
|
fs::remove_all(eden_dir);
|
||||||
|
|
@ -69,7 +74,7 @@ void MigrationWorker::process()
|
||||||
|
|
||||||
success_text.append(tr("\n\nNote that your configuration and data will be shared with %1.\n"
|
success_text.append(tr("\n\nNote that your configuration and data will be shared with %1.\n"
|
||||||
"If this is not desirable, delete the following files:\n%2\n%3\n%4")
|
"If this is not desirable, delete the following files:\n%2\n%3\n%4")
|
||||||
.arg(selected_legacy_emu.name(),
|
.arg(selected_emu.name(),
|
||||||
QString::fromStdString(eden_dir.string()),
|
QString::fromStdString(eden_dir.string()),
|
||||||
QString::fromStdString(config_dir.string()),
|
QString::fromStdString(config_dir.string()),
|
||||||
QString::fromStdString(cache_dir.string())));
|
QString::fromStdString(cache_dir.string())));
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,12 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
|
|
||||||
using namespace Common::FS;
|
|
||||||
|
|
||||||
typedef struct Emulator {
|
typedef struct Emulator {
|
||||||
const char *m_name;
|
const char *m_name;
|
||||||
|
|
||||||
EmuPath e_user_dir;
|
Common::FS::EmuPath e_user_dir;
|
||||||
EmuPath e_config_dir;
|
Common::FS::EmuPath e_config_dir;
|
||||||
EmuPath e_cache_dir;
|
Common::FS::EmuPath e_cache_dir;
|
||||||
|
|
||||||
const std::string get_user_dir() const {
|
const std::string get_user_dir() const {
|
||||||
return Common::FS::GetLegacyPath(e_user_dir).string();
|
return Common::FS::GetLegacyPath(e_user_dir).string();
|
||||||
|
|
@ -35,11 +33,13 @@ typedef struct Emulator {
|
||||||
}
|
}
|
||||||
} Emulator;
|
} Emulator;
|
||||||
|
|
||||||
|
#define STRUCT_EMU(name, enumName) Emulator{name, Common::FS::enumName##Dir, Common::FS::enumName##ConfigDir, Common::FS::enumName##CacheDir}
|
||||||
|
|
||||||
static constexpr std::array<Emulator, 4> legacy_emus = {
|
static constexpr std::array<Emulator, 4> legacy_emus = {
|
||||||
Emulator{QT_TR_NOOP("Citron"), CitronDir, CitronConfigDir, CitronCacheDir},
|
STRUCT_EMU(QT_TR_NOOP("Citron"), Citron),
|
||||||
Emulator{QT_TR_NOOP("Sudachi"), SudachiDir, SudachiConfigDir, SudachiCacheDir},
|
STRUCT_EMU(QT_TR_NOOP("Sudachi"), Sudachi),
|
||||||
Emulator{QT_TR_NOOP("Suyu"), SuyuDir, SuyuConfigDir, SuyuCacheDir},
|
STRUCT_EMU(QT_TR_NOOP("Suyu"), Suyu),
|
||||||
Emulator{QT_TR_NOOP("Yuzu"), YuzuDir, YuzuConfigDir, YuzuCacheDir},
|
STRUCT_EMU(QT_TR_NOOP("Yuzu"), Yuzu),
|
||||||
};
|
};
|
||||||
|
|
||||||
class MigrationWorker : public QObject
|
class MigrationWorker : public QObject
|
||||||
|
|
@ -52,7 +52,7 @@ public:
|
||||||
Link,
|
Link,
|
||||||
};
|
};
|
||||||
|
|
||||||
MigrationWorker(const Emulator selected_legacy_emu,
|
MigrationWorker(const Emulator selected_emu,
|
||||||
const bool clear_shader_cache,
|
const bool clear_shader_cache,
|
||||||
const MigrationStrategy strategy);
|
const MigrationStrategy strategy);
|
||||||
|
|
||||||
|
|
@ -64,7 +64,7 @@ signals:
|
||||||
void error(const QString &error_message);
|
void error(const QString &error_message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Emulator selected_legacy_emu;
|
Emulator selected_emu;
|
||||||
bool clear_shader_cache;
|
bool clear_shader_cache;
|
||||||
MigrationStrategy strategy;
|
MigrationStrategy strategy;
|
||||||
QString success_text = tr("Data was migrated successfully.");
|
QString success_text = tr("Data was migrated successfully.");
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
#include "core/internal_network/network_interface.h"
|
#include "core/internal_network/network_interface.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "ui_direct_connect.h"
|
#include "ui_direct_connect.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/multiplayer/client_room.h"
|
#include "yuzu/multiplayer/client_room.h"
|
||||||
#include "yuzu/multiplayer/direct_connect.h"
|
#include "yuzu/multiplayer/direct_connect.h"
|
||||||
#include "yuzu/multiplayer/message.h"
|
#include "yuzu/multiplayer/message.h"
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
#include "network/announce_multiplayer_session.h"
|
#include "network/announce_multiplayer_session.h"
|
||||||
#include "ui_host_room.h"
|
#include "ui_host_room.h"
|
||||||
#include "yuzu/game_list_p.h"
|
#include "yuzu/game_list_p.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/multiplayer/host_room.h"
|
#include "yuzu/multiplayer/host_room.h"
|
||||||
#include "yuzu/multiplayer/message.h"
|
#include "yuzu/multiplayer/message.h"
|
||||||
#include "yuzu/multiplayer/state.h"
|
#include "yuzu/multiplayer/state.h"
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "ui_lobby.h"
|
#include "ui_lobby.h"
|
||||||
#include "yuzu/game_list_p.h"
|
#include "yuzu/game_list_p.h"
|
||||||
#include "yuzu/main.h"
|
#include "yuzu/main_window.h"
|
||||||
#include "yuzu/multiplayer/client_room.h"
|
#include "yuzu/multiplayer/client_room.h"
|
||||||
#include "yuzu/multiplayer/lobby.h"
|
#include "yuzu/multiplayer/lobby.h"
|
||||||
#include "yuzu/multiplayer/lobby_p.h"
|
#include "yuzu/multiplayer/lobby_p.h"
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "qt_common/abstract/frontend.h"
|
||||||
#include "ryujinx_dialog.h"
|
#include "ryujinx_dialog.h"
|
||||||
#include "qt_common/util/fs.h"
|
#include "qt_common/util/fs.h"
|
||||||
#include "ui_ryujinx_dialog.h"
|
#include "ui_ryujinx_dialog.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
RyujinxDialog::RyujinxDialog(std::filesystem::path eden_path,
|
RyujinxDialog::RyujinxDialog(std::filesystem::path eden_path,
|
||||||
std::filesystem::path ryu_path,
|
std::filesystem::path ryu_path,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
|
|
@ -20,6 +19,7 @@ RyujinxDialog::RyujinxDialog(std::filesystem::path eden_path,
|
||||||
|
|
||||||
connect(ui->eden, &QPushButton::clicked, this, &RyujinxDialog::fromEden);
|
connect(ui->eden, &QPushButton::clicked, this, &RyujinxDialog::fromEden);
|
||||||
connect(ui->ryujinx, &QPushButton::clicked, this, &RyujinxDialog::fromRyujinx);
|
connect(ui->ryujinx, &QPushButton::clicked, this, &RyujinxDialog::fromRyujinx);
|
||||||
|
connect(ui->cancel, &QPushButton::clicked, this, &RyujinxDialog::reject);
|
||||||
}
|
}
|
||||||
|
|
||||||
RyujinxDialog::~RyujinxDialog()
|
RyujinxDialog::~RyujinxDialog()
|
||||||
|
|
@ -30,7 +30,21 @@ RyujinxDialog::~RyujinxDialog()
|
||||||
void RyujinxDialog::fromEden()
|
void RyujinxDialog::fromEden()
|
||||||
{
|
{
|
||||||
accept();
|
accept();
|
||||||
QtCommon::FS::LinkRyujinx(m_eden, m_ryu);
|
|
||||||
|
// Workaround: Ryujinx deletes and re-creates its directory structure???
|
||||||
|
// So we just copy Eden's data to Ryujinx and then link the other way
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
try {
|
||||||
|
fs::remove_all(m_ryu);
|
||||||
|
fs::create_directories(m_ryu);
|
||||||
|
fs::copy(m_eden, m_ryu, fs::copy_options::recursive);
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
QtCommon::Frontend::Critical(tr("Failed to link save data"),
|
||||||
|
tr("OS returned error: %1").arg(QString::fromStdString(e.what())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ?ploo
|
||||||
|
QtCommon::FS::LinkRyujinx(m_ryu, m_eden);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RyujinxDialog::fromRyujinx()
|
void RyujinxDialog::fromRyujinx()
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
UserDataMigrator::UserDataMigrator(QMainWindow *main_window)
|
UserDataMigrator::UserDataMigrator(QMainWindow *main_window)
|
||||||
{
|
{
|
||||||
// NOTE: Logging is not initialized yet, do not produce logs here.
|
// NOTE: Logging is not initialized yet, do not produce logs here.
|
||||||
|
|
@ -32,7 +30,7 @@ UserDataMigrator::UserDataMigrator(QMainWindow *main_window)
|
||||||
// Check migration if config directory does not exist
|
// Check migration if config directory does not exist
|
||||||
// TODO: ProfileManager messes with us a bit here, and force-creates the /nand/system/save/8000000000000010/su/avators/profiles.dat
|
// TODO: ProfileManager messes with us a bit here, and force-creates the /nand/system/save/8000000000000010/su/avators/profiles.dat
|
||||||
// file. Find a way to reorder operations and have it create after this guy runs.
|
// file. Find a way to reorder operations and have it create after this guy runs.
|
||||||
if (!fs::is_directory(Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir))) {
|
if (!std::filesystem::is_directory(Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir))) {
|
||||||
ShowMigrationPrompt(main_window);
|
ShowMigrationPrompt(main_window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,23 +38,7 @@ UserDataMigrator::UserDataMigrator(QMainWindow *main_window)
|
||||||
void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
|
void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
|
||||||
{
|
{
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
using namespace QtCommon::StringLookup;
|
||||||
// define strings here for easy access
|
|
||||||
|
|
||||||
QString prompt_prefix_text = QtCommon::StringLookup::Lookup(
|
|
||||||
QtCommon::StringLookup::MigrationPromptPrefix);
|
|
||||||
QString migration_prompt_message = QtCommon::StringLookup::Lookup(
|
|
||||||
QtCommon::StringLookup::MigrationPrompt);
|
|
||||||
QString clear_shader_tooltip = QtCommon::StringLookup::Lookup(
|
|
||||||
QtCommon::StringLookup::MigrationTooltipClearShader);
|
|
||||||
QString keep_old_data_tooltip = QtCommon::StringLookup::Lookup(
|
|
||||||
QtCommon::StringLookup::MigrationTooltipKeepOld);
|
|
||||||
QString clear_old_data_tooltip = QtCommon::StringLookup::Lookup(
|
|
||||||
QtCommon::StringLookup::MigrationTooltipClearOld);
|
|
||||||
QString link_old_dir_tooltip = QtCommon::StringLookup::Lookup(
|
|
||||||
QtCommon::StringLookup::MigrationTooltipLinkOld);
|
|
||||||
|
|
||||||
// actual migration code
|
|
||||||
|
|
||||||
MigrationDialog migration_prompt;
|
MigrationDialog migration_prompt;
|
||||||
migration_prompt.setWindowTitle(QObject::tr("Migration"));
|
migration_prompt.setWindowTitle(QObject::tr("Migration"));
|
||||||
|
|
@ -69,11 +51,11 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
|
||||||
#define BUTTON(clazz, name, text, tooltip, checkState) \
|
#define BUTTON(clazz, name, text, tooltip, checkState) \
|
||||||
clazz *name = new clazz(&migration_prompt); \
|
clazz *name = new clazz(&migration_prompt); \
|
||||||
name->setText(text); \
|
name->setText(text); \
|
||||||
name->setToolTip(tooltip); \
|
name->setToolTip(Lookup(tooltip)); \
|
||||||
name->setChecked(checkState); \
|
name->setChecked(checkState); \
|
||||||
migration_prompt.addBox(name);
|
migration_prompt.addBox(name);
|
||||||
|
|
||||||
BUTTON(QCheckBox, clear_shaders, QObject::tr("Clear Shader Cache"), clear_shader_tooltip, true)
|
BUTTON(QCheckBox, clear_shaders, QObject::tr("Clear Shader Cache"), MigrationTooltipClearShader, true)
|
||||||
|
|
||||||
u32 id = 0;
|
u32 id = 0;
|
||||||
|
|
||||||
|
|
@ -81,9 +63,9 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
|
||||||
BUTTON(QRadioButton, name, text, tooltip, checkState) \
|
BUTTON(QRadioButton, name, text, tooltip, checkState) \
|
||||||
group->addButton(name, ++id);
|
group->addButton(name, ++id);
|
||||||
|
|
||||||
RADIO(keep_old, QObject::tr("Keep Old Data"), keep_old_data_tooltip, true)
|
RADIO(keep_old, QObject::tr("Keep Old Data"), MigrationTooltipKeepOld, true)
|
||||||
RADIO(clear_old, QObject::tr("Clear Old Data"), clear_old_data_tooltip, false)
|
RADIO(clear_old, QObject::tr("Clear Old Data"), MigrationTooltipClearOld, false)
|
||||||
RADIO(link_old, QObject::tr("Link Old Directory"), link_old_dir_tooltip, false)
|
RADIO(link_old, QObject::tr("Link Old Directory"), MigrationTooltipLinkOld, false)
|
||||||
|
|
||||||
#undef RADIO
|
#undef RADIO
|
||||||
#undef BUTTON
|
#undef BUTTON
|
||||||
|
|
@ -101,7 +83,7 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
|
||||||
// makes my life easier
|
// makes my life easier
|
||||||
qRegisterMetaType<Emulator>();
|
qRegisterMetaType<Emulator>();
|
||||||
|
|
||||||
QString prompt_text = prompt_prefix_text;
|
QString prompt_text = Lookup(MigrationPromptPrefix);
|
||||||
|
|
||||||
// natural language processing is a nightmare
|
// natural language processing is a nightmare
|
||||||
for (const Emulator &emu : found) {
|
for (const Emulator &emu : found) {
|
||||||
|
|
@ -114,7 +96,7 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt_text.append(QObject::tr("\n\n"));
|
prompt_text.append(QObject::tr("\n\n"));
|
||||||
prompt_text = prompt_text % QStringLiteral("\n\n") % migration_prompt_message;
|
prompt_text = prompt_text % QStringLiteral("\n\n") % Lookup(MigrationPrompt);
|
||||||
|
|
||||||
migration_prompt.setText(prompt_text);
|
migration_prompt.setText(prompt_text);
|
||||||
migration_prompt.addButton(QObject::tr("No"), true);
|
migration_prompt.addButton(QObject::tr("No"), true);
|
||||||
|
|
@ -127,24 +109,12 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
|
||||||
return ShowMigrationCancelledMessage(main_window);
|
return ShowMigrationCancelledMessage(main_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
MigrationWorker::MigrationStrategy strategy;
|
MigrationWorker::MigrationStrategy strategy = static_cast<MigrationWorker::MigrationStrategy>(
|
||||||
|
group->checkedId());
|
||||||
|
|
||||||
switch (group->checkedId()) {
|
selected_emu = button->property("emulator").value<Emulator>();
|
||||||
default:
|
|
||||||
[[fallthrough]];
|
|
||||||
case 1:
|
|
||||||
strategy = MigrationWorker::MigrationStrategy::Copy;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
strategy = MigrationWorker::MigrationStrategy::Move;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
strategy = MigrationWorker::MigrationStrategy::Link;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MigrateUserData(main_window,
|
MigrateUserData(main_window,
|
||||||
button->property("emulator").value<Emulator>(),
|
|
||||||
clear_shaders->isChecked(),
|
clear_shaders->isChecked(),
|
||||||
strategy);
|
strategy);
|
||||||
}
|
}
|
||||||
|
|
@ -161,12 +131,9 @@ void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow *main_window)
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserDataMigrator::MigrateUserData(QMainWindow *main_window,
|
void UserDataMigrator::MigrateUserData(QMainWindow *main_window,
|
||||||
const Emulator selected_legacy_emu,
|
|
||||||
const bool clear_shader_cache,
|
const bool clear_shader_cache,
|
||||||
const MigrationWorker::MigrationStrategy strategy)
|
const MigrationWorker::MigrationStrategy strategy)
|
||||||
{
|
{
|
||||||
selected_emu = selected_legacy_emu;
|
|
||||||
|
|
||||||
// Create a dialog to let the user know it's migrating
|
// Create a dialog to let the user know it's migrating
|
||||||
QProgressDialog *progress = new QProgressDialog(main_window);
|
QProgressDialog *progress = new QProgressDialog(main_window);
|
||||||
progress->setWindowTitle(QObject::tr("Migrating"));
|
progress->setWindowTitle(QObject::tr("Migrating"));
|
||||||
|
|
@ -176,7 +143,7 @@ void UserDataMigrator::MigrateUserData(QMainWindow *main_window,
|
||||||
progress->setWindowModality(Qt::WindowModality::ApplicationModal);
|
progress->setWindowModality(Qt::WindowModality::ApplicationModal);
|
||||||
|
|
||||||
QThread *thread = new QThread(main_window);
|
QThread *thread = new QThread(main_window);
|
||||||
MigrationWorker *worker = new MigrationWorker(selected_legacy_emu, clear_shader_cache, strategy);
|
MigrationWorker *worker = new MigrationWorker(selected_emu, clear_shader_cache, strategy);
|
||||||
worker->moveToThread(thread);
|
worker->moveToThread(thread);
|
||||||
|
|
||||||
thread->connect(thread, &QThread::started, worker, &MigrationWorker::process);
|
thread->connect(thread, &QThread::started, worker, &MigrationWorker::process);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ private:
|
||||||
void ShowMigrationPrompt(QMainWindow* main_window);
|
void ShowMigrationPrompt(QMainWindow* main_window);
|
||||||
void ShowMigrationCancelledMessage(QMainWindow* main_window);
|
void ShowMigrationCancelledMessage(QMainWindow* main_window);
|
||||||
void MigrateUserData(QMainWindow* main_window,
|
void MigrateUserData(QMainWindow* main_window,
|
||||||
const Emulator selected_legacy_emu,
|
|
||||||
const bool clear_shader_cache,
|
const bool clear_shader_cache,
|
||||||
const MigrationWorker::MigrationStrategy strategy);
|
const MigrationWorker::MigrationStrategy strategy);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,11 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include "applets/qt_profile_select.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/frontend/applets/profile_select.h"
|
||||||
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
|
#include "qt_common/qt_common.h"
|
||||||
#include "yuzu/util/util.h"
|
#include "yuzu/util/util.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
@ -153,3 +157,49 @@ bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image)
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
const std::optional<Common::UUID> GetProfileID() {
|
||||||
|
// if there's only a single profile, the user probably wants to use that... right?
|
||||||
|
const auto& profiles = QtCommon::system->GetProfileManager().FindExistingProfileUUIDs();
|
||||||
|
if (profiles.size() == 1) {
|
||||||
|
return profiles[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto select_profile = [] {
|
||||||
|
const Core::Frontend::ProfileSelectParameters parameters{
|
||||||
|
.mode = Service::AM::Frontend::UiMode::UserSelector,
|
||||||
|
.invalid_uid_list = {},
|
||||||
|
.display_options = {},
|
||||||
|
.purpose = Service::AM::Frontend::UserSelectionPurpose::General,
|
||||||
|
};
|
||||||
|
QtProfileSelectionDialog dialog(*QtCommon::system, QtCommon::rootObject, parameters);
|
||||||
|
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
|
||||||
|
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
|
||||||
|
dialog.setWindowModality(Qt::WindowModal);
|
||||||
|
|
||||||
|
if (dialog.exec() == QDialog::Rejected) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dialog.GetIndex();
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto index = select_profile();
|
||||||
|
if (index == -1) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto uuid =
|
||||||
|
QtCommon::system->GetProfileManager().GetUser(static_cast<std::size_t>(index));
|
||||||
|
ASSERT(uuid);
|
||||||
|
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
std::string GetProfileIDString() {
|
||||||
|
const auto uuid = GetProfileID();
|
||||||
|
if (!uuid)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
auto user_id = uuid->AsU128();
|
||||||
|
|
||||||
|
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -6,6 +9,7 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include "common/uuid.h"
|
||||||
|
|
||||||
/// Returns a QFont object appropriate to use as a monospace font for debugging widgets, etc.
|
/// Returns a QFont object appropriate to use as a monospace font for debugging widgets, etc.
|
||||||
[[nodiscard]] QFont GetMonospaceFont();
|
[[nodiscard]] QFont GetMonospaceFont();
|
||||||
|
|
@ -27,3 +31,15 @@
|
||||||
* @return bool If the operation succeeded
|
* @return bool If the operation succeeded
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image);
|
[[nodiscard]] bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user for a profile ID. If there is only one valid profile, returns that profile.
|
||||||
|
* @return The selected profile, or an std::nullopt if none were selected
|
||||||
|
*/
|
||||||
|
const std::optional<Common::UUID> GetProfileID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user for a profile ID. If there is only one valid profile, returns that profile.
|
||||||
|
* @return A string representation of the selected profile, or an empty string if none were seleeced
|
||||||
|
*/
|
||||||
|
std::string GetProfileIDString();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue