forked from eden-emu/eden
Compare commits
10 commits
master
...
refactor/q
Author | SHA1 | Date | |
---|---|---|---|
490758c2ce | |||
aafd2b7437 | |||
0f28ecbe71 | |||
b080a8192b | |||
3198770ffb | |||
1da87f01f7 | |||
6c48a82c83 | |||
6b13fd566d | |||
916d01242e | |||
8d0b35e75d |
65 changed files with 939 additions and 505 deletions
|
@ -4,16 +4,22 @@ HEADER="$(cat "$PWD/.ci/license/header.txt")"
|
|||
|
||||
echo "Getting branch changes"
|
||||
|
||||
BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||
COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"`
|
||||
RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}"
|
||||
FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
|
||||
# BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||
# COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"`
|
||||
# RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}"
|
||||
# FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
|
||||
|
||||
BASE=`git merge-base master HEAD`
|
||||
FILES=`git diff --name-only $BASE`
|
||||
|
||||
#FILES=$(git diff --name-only master)
|
||||
|
||||
echo $FILES
|
||||
echo "Done"
|
||||
|
||||
for file in $FILES; do
|
||||
[ -f "$file" ] || continue
|
||||
|
||||
EXTENSION="${file##*.}"
|
||||
case "$EXTENSION" in
|
||||
kts|kt|cpp|h)
|
||||
|
|
|
@ -212,6 +212,8 @@ if (YUZU_ROOM_STANDALONE)
|
|||
endif()
|
||||
|
||||
if (ENABLE_QT)
|
||||
add_definitions(-DYUZU_QT_WIDGETS)
|
||||
add_subdirectory(qt_common)
|
||||
add_subdirectory(yuzu)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -126,6 +129,10 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir,
|
|||
|
||||
std::string out = GetSaveDataSpaceIdPath(space);
|
||||
|
||||
LOG_INFO(Common_Filesystem, "Save ID: {:016X}", save_id);
|
||||
LOG_INFO(Common_Filesystem, "User ID[1]: {:016X}", user_id[1]);
|
||||
LOG_INFO(Common_Filesystem, "User ID[0]: {:016X}", user_id[0]);
|
||||
|
||||
switch (type) {
|
||||
case SaveDataType::System:
|
||||
return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]);
|
||||
|
|
File diff suppressed because one or more lines are too long
29
src/qt_common/CMakeLists.txt
Normal file
29
src/qt_common/CMakeLists.txt
Normal file
|
@ -0,0 +1,29 @@
|
|||
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
|
||||
add_library(qt_common STATIC
|
||||
qt_common.h
|
||||
qt_common.cpp
|
||||
|
||||
uisettings.cpp
|
||||
uisettings.h
|
||||
|
||||
qt_config.cpp
|
||||
qt_config.h
|
||||
|
||||
shared_translation.cpp
|
||||
shared_translation.h
|
||||
qt_path_util.h qt_path_util.cpp
|
||||
qt_game_util.h qt_game_util.cpp
|
||||
qt_frontend_util.h qt_frontend_util.cpp
|
||||
)
|
||||
|
||||
create_target_directory_groups(qt_common)
|
||||
target_link_libraries(qt_common PUBLIC core Qt6::Widgets SimpleIni::SimpleIni QuaZip::QuaZip)
|
||||
target_link_libraries(qt_common PRIVATE Qt6::Core)
|
||||
|
||||
if (NOT WIN32)
|
||||
target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
endif()
|
242
src/qt_common/qt_common.cpp
Normal file
242
src/qt_common/qt_common.cpp
Normal file
|
@ -0,0 +1,242 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "qt_common.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "frontend_common/firmware_manager.h"
|
||||
#include "uisettings.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QStringLiteral>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include "qt_frontend_util.h"
|
||||
|
||||
#include <JlCompress.h>
|
||||
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <objc/message.h>
|
||||
#endif
|
||||
|
||||
namespace QtCommon {
|
||||
MetadataResult ResetMetadata()
|
||||
{
|
||||
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir)
|
||||
/ "game_list/")) {
|
||||
return MetadataResult::Empty;
|
||||
} else if (Common::FS::RemoveDirRecursively(
|
||||
Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) {
|
||||
return MetadataResult::Success;
|
||||
UISettings::values.is_game_list_reload_pending.exchange(true);
|
||||
} else {
|
||||
return MetadataResult::Failure;
|
||||
}
|
||||
}
|
||||
|
||||
Core::Frontend::WindowSystemType GetWindowSystemType()
|
||||
{
|
||||
// Determine WSI type based on Qt platform.
|
||||
QString platform_name = QGuiApplication::platformName();
|
||||
if (platform_name == QStringLiteral("windows"))
|
||||
return Core::Frontend::WindowSystemType::Windows;
|
||||
else if (platform_name == QStringLiteral("xcb"))
|
||||
return Core::Frontend::WindowSystemType::X11;
|
||||
else if (platform_name == QStringLiteral("wayland"))
|
||||
return Core::Frontend::WindowSystemType::Wayland;
|
||||
else if (platform_name == QStringLiteral("wayland-egl"))
|
||||
return Core::Frontend::WindowSystemType::Wayland;
|
||||
else if (platform_name == QStringLiteral("cocoa"))
|
||||
return Core::Frontend::WindowSystemType::Cocoa;
|
||||
else if (platform_name == QStringLiteral("android"))
|
||||
return Core::Frontend::WindowSystemType::Android;
|
||||
|
||||
LOG_CRITICAL(Frontend, "Unknown Qt platform {}!", platform_name.toStdString());
|
||||
return Core::Frontend::WindowSystemType::Windows;
|
||||
} // namespace Core::Frontend::WindowSystemType
|
||||
|
||||
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window)
|
||||
{
|
||||
Core::Frontend::EmuWindow::WindowSystemInfo wsi;
|
||||
wsi.type = GetWindowSystemType();
|
||||
|
||||
#if defined(WIN32)
|
||||
// Our Win32 Qt external doesn't have the private API.
|
||||
wsi.render_surface = reinterpret_cast<void*>(window->winId());
|
||||
#elif defined(__APPLE__)
|
||||
wsi.render_surface = reinterpret_cast<void* (*) (id, SEL)>(
|
||||
objc_msgSend)(reinterpret_cast<id>(window->winId()), sel_registerName("layer"));
|
||||
#else
|
||||
QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface();
|
||||
wsi.display_connection = pni->nativeResourceForWindow("display", window);
|
||||
if (wsi.type == Core::Frontend::WindowSystemType::Wayland)
|
||||
wsi.render_surface = window ? pni->nativeResourceForWindow("surface", window) : nullptr;
|
||||
else
|
||||
wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr;
|
||||
#endif
|
||||
wsi.render_surface_scale = window ? static_cast<float>(window->devicePixelRatio()) : 1.0f;
|
||||
|
||||
return wsi;
|
||||
}
|
||||
|
||||
FirmwareInstallResult InstallFirmware(
|
||||
const QString& location,
|
||||
bool recursive,
|
||||
std::function<bool(std::size_t, std::size_t)> QtProgressCallback,
|
||||
Core::System* system,
|
||||
FileSys::VfsFilesystem* vfs,
|
||||
QWidget* parent)
|
||||
{
|
||||
static constexpr const char* failedTitle = "Firmware Install Failed";
|
||||
static constexpr const char* successTitle = "Firmware Install Failed";
|
||||
static constexpr QMessageBox::StandardButtons buttons = QMessageBox::Ok;
|
||||
|
||||
QMessageBox::Icon icon;
|
||||
FirmwareInstallResult result;
|
||||
|
||||
const auto ShowMessage = [&]() {
|
||||
QtCommon::Frontend::ShowMessage(icon,
|
||||
failedTitle,
|
||||
GetFirmwareInstallResultString(result),
|
||||
buttons,
|
||||
parent);
|
||||
};
|
||||
|
||||
LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString());
|
||||
|
||||
// Check for a reasonable number of .nca files (don't hardcode them, just see if there's some in
|
||||
// there.)
|
||||
std::filesystem::path firmware_source_path = location.toStdString();
|
||||
if (!Common::FS::IsDir(firmware_source_path)) {
|
||||
return FirmwareInstallResult::NoOp;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> out;
|
||||
const Common::FS::DirEntryCallable callback =
|
||||
[&out](const std::filesystem::directory_entry& entry) {
|
||||
if (entry.path().has_extension() && entry.path().extension() == ".nca") {
|
||||
out.emplace_back(entry.path());
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
QtProgressCallback(100, 10);
|
||||
|
||||
if (recursive) {
|
||||
Common::FS::IterateDirEntriesRecursively(firmware_source_path,
|
||||
callback,
|
||||
Common::FS::DirEntryFilter::File);
|
||||
} else {
|
||||
Common::FS::IterateDirEntries(firmware_source_path,
|
||||
callback,
|
||||
Common::FS::DirEntryFilter::File);
|
||||
}
|
||||
|
||||
if (out.size() <= 0) {
|
||||
result = FirmwareInstallResult::NoNCAs;
|
||||
icon = QMessageBox::Warning;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Locate and erase the content of nand/system/Content/registered/*.nca, if any.
|
||||
auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory();
|
||||
if (sysnand_content_vdir->IsWritable()
|
||||
&& !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
|
||||
result = FirmwareInstallResult::FailedDelete;
|
||||
icon = QMessageBox::Critical;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
LOG_INFO(Frontend,
|
||||
"Cleaned nand/system/Content/registered folder in preparation for new firmware.");
|
||||
|
||||
QtProgressCallback(100, 20);
|
||||
|
||||
auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered");
|
||||
|
||||
bool success = true;
|
||||
int i = 0;
|
||||
for (const auto& firmware_src_path : out) {
|
||||
i++;
|
||||
auto firmware_src_vfile = vfs->OpenFile(firmware_src_path.generic_string(),
|
||||
FileSys::OpenMode::Read);
|
||||
auto firmware_dst_vfile = firmware_vdir
|
||||
->CreateFileRelative(firmware_src_path.filename().string());
|
||||
|
||||
if (!VfsRawCopy(firmware_src_vfile, firmware_dst_vfile)) {
|
||||
LOG_ERROR(Frontend,
|
||||
"Failed to copy firmware file {} to {} in registered folder!",
|
||||
firmware_src_path.generic_string(),
|
||||
firmware_src_path.filename().string());
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (QtProgressCallback(100,
|
||||
20
|
||||
+ static_cast<int>(((i) / static_cast<float>(out.size()))
|
||||
* 70.0))) {
|
||||
result = FirmwareInstallResult::FailedCorrupted;
|
||||
icon = QMessageBox::Warning;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
result = FirmwareInstallResult::FailedCopy;
|
||||
icon = QMessageBox::Critical;
|
||||
ShowMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Re-scan VFS for the newly placed firmware files.
|
||||
system->GetFileSystemController().CreateFactories(*vfs);
|
||||
|
||||
const auto pair = FirmwareManager::GetFirmwareVersion(*system);
|
||||
const auto firmware_data = pair.first;
|
||||
const std::string display_version(firmware_data.display_version.data());
|
||||
|
||||
result = FirmwareInstallResult::Success;
|
||||
QtCommon::Frontend::ShowMessage(QMessageBox::Information,
|
||||
qApp->tr(successTitle),
|
||||
qApp->tr(GetFirmwareInstallResultString(result))
|
||||
.arg(QString::fromStdString(display_version)),
|
||||
buttons,
|
||||
parent);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString UnzipFirmwareToTmp(const QString& location)
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
fs::path tmp{fs::temp_directory_path()};
|
||||
|
||||
if (!fs::create_directories(tmp / "eden" / "firmware")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
tmp /= "eden";
|
||||
tmp /= "firmware";
|
||||
|
||||
QString qCacheDir = QString::fromStdString(tmp.string());
|
||||
|
||||
QFile zip(location);
|
||||
|
||||
QStringList result = JlCompress::extractDir(&zip, qCacheDir);
|
||||
if (result.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return qCacheDir;
|
||||
}
|
||||
} // namespace QtCommon
|
80
src/qt_common/qt_common.h
Normal file
80
src/qt_common/qt_common.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef QT_COMMON_H
|
||||
#define QT_COMMON_H
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <QWindow>
|
||||
#include "core/core.h"
|
||||
#include <core/frontend/emu_window.h>
|
||||
|
||||
#include <core/file_sys/vfs/vfs_real.h>
|
||||
|
||||
namespace QtCommon {
|
||||
static constexpr std::array<const char *, 3> METADATA_RESULTS = {
|
||||
"The operation completed successfully.",
|
||||
"The metadata cache couldn't be deleted. It might be in use or non-existent.",
|
||||
"The metadata cache is already empty.",
|
||||
};
|
||||
|
||||
enum class MetadataResult {
|
||||
Success,
|
||||
Failure,
|
||||
Empty,
|
||||
};
|
||||
/**
|
||||
* @brief ResetMetadata Reset game list metadata.
|
||||
* @return A result code.
|
||||
*/
|
||||
MetadataResult ResetMetadata();
|
||||
|
||||
/**
|
||||
* \brief Get a string representation of a result from ResetMetadata.
|
||||
* \param result The result code.
|
||||
* \return A string representation of the passed result code.
|
||||
*/
|
||||
inline constexpr const char *GetResetMetadataResultString(MetadataResult result)
|
||||
{
|
||||
return METADATA_RESULTS.at(static_cast<std::size_t>(result));
|
||||
}
|
||||
|
||||
static constexpr std::array<const char *, 6> FIRMWARE_RESULTS
|
||||
= {"Successfully installed firmware version %1",
|
||||
"",
|
||||
"Unable to locate potential firmware NCA files",
|
||||
"Failed to delete one or more firmware files.",
|
||||
"One or more firmware files failed to copy into NAND.",
|
||||
"Firmware installation cancelled, firmware may be in a bad state or corrupted."
|
||||
"Restart Eden or re-install firmware."};
|
||||
|
||||
enum class FirmwareInstallResult {
|
||||
Success,
|
||||
NoOp,
|
||||
NoNCAs,
|
||||
FailedDelete,
|
||||
FailedCopy,
|
||||
FailedCorrupted,
|
||||
};
|
||||
|
||||
FirmwareInstallResult InstallFirmware(
|
||||
const QString &location,
|
||||
bool recursive,
|
||||
std::function<bool(std::size_t, std::size_t)> QtProgressCallback,
|
||||
Core::System *system,
|
||||
FileSys::VfsFilesystem *vfs,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
QString UnzipFirmwareToTmp(const QString &location);
|
||||
|
||||
inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result)
|
||||
{
|
||||
return FIRMWARE_RESULTS.at(static_cast<std::size_t>(result));
|
||||
}
|
||||
|
||||
Core::Frontend::WindowSystemType GetWindowSystemType();
|
||||
|
||||
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window);
|
||||
} // namespace QtCommon
|
||||
#endif
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
28
src/qt_common/qt_frontend_util.cpp
Normal file
28
src/qt_common/qt_frontend_util.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "qt_frontend_util.h"
|
||||
|
||||
namespace QtCommon::Frontend {
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QWidget *parent)
|
||||
{
|
||||
#ifdef YUZU_QT_WIDGETS
|
||||
QMessageBox *box = new QMessageBox(icon, title, text, buttons, parent);
|
||||
return static_cast<QMessageBox::StandardButton>(box->exec());
|
||||
#endif
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons,
|
||||
QWidget *parent)
|
||||
{
|
||||
return ShowMessage(icon, qApp->tr(title), qApp->tr(text), buttons, parent);
|
||||
}
|
||||
|
||||
} // namespace QtCommon::Frontend
|
32
src/qt_common/qt_frontend_util.h
Normal file
32
src/qt_common/qt_frontend_util.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef QT_FRONTEND_UTIL_H
|
||||
#define QT_FRONTEND_UTIL_H
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QMessageBox>
|
||||
|
||||
#ifdef YUZU_QT_WIDGETS
|
||||
#include <QWidget>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* manages common functionality e.g. message boxes and such for Qt/QML
|
||||
*/
|
||||
namespace QtCommon::Frontend {
|
||||
Q_NAMESPACE
|
||||
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
const QString &title,
|
||||
const QString &text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
QMessageBox::StandardButton ShowMessage(QMessageBox::Icon icon,
|
||||
const char *title,
|
||||
const char *text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
|
||||
QWidget *parent = nullptr);
|
||||
} // namespace QtCommon::Frontend
|
||||
#endif // QT_FRONTEND_UTIL_H
|
177
src/qt_common/qt_game_util.cpp
Normal file
177
src/qt_common/qt_game_util.cpp
Normal file
|
@ -0,0 +1,177 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "qt_game_util.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <shlobj.h>
|
||||
#include <windows.h>
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/string_util.h"
|
||||
#else
|
||||
#include "fmt/ostream.h"
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
namespace QtCommon {
|
||||
|
||||
bool CreateShortcutLink(const std::filesystem::path& shortcut_path,
|
||||
const std::string& comment,
|
||||
const std::filesystem::path& icon_path,
|
||||
const std::filesystem::path& command,
|
||||
const std::string& arguments, const std::string& categories,
|
||||
const std::string& keywords, const std::string& name) try {
|
||||
#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD
|
||||
std::filesystem::path shortcut_path_full = shortcut_path / (name + ".desktop");
|
||||
std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc);
|
||||
if (!shortcut_stream.is_open()) {
|
||||
LOG_ERROR(Frontend, "Failed to create shortcut");
|
||||
return false;
|
||||
}
|
||||
// TODO: Migrate fmt::print to std::print in futures STD C++ 23.
|
||||
fmt::print(shortcut_stream, "[Desktop Entry]\n");
|
||||
fmt::print(shortcut_stream, "Type=Application\n");
|
||||
fmt::print(shortcut_stream, "Version=1.0\n");
|
||||
fmt::print(shortcut_stream, "Name={}\n", name);
|
||||
if (!comment.empty()) {
|
||||
fmt::print(shortcut_stream, "Comment={}\n", comment);
|
||||
}
|
||||
if (std::filesystem::is_regular_file(icon_path)) {
|
||||
fmt::print(shortcut_stream, "Icon={}\n", icon_path.string());
|
||||
}
|
||||
fmt::print(shortcut_stream, "TryExec={}\n", command.string());
|
||||
fmt::print(shortcut_stream, "Exec={} {}\n", command.string(), arguments);
|
||||
if (!categories.empty()) {
|
||||
fmt::print(shortcut_stream, "Categories={}\n", categories);
|
||||
}
|
||||
if (!keywords.empty()) {
|
||||
fmt::print(shortcut_stream, "Keywords={}\n", keywords);
|
||||
}
|
||||
return true;
|
||||
#elif defined(_WIN32) // Windows
|
||||
HRESULT hr = CoInitialize(nullptr);
|
||||
if (FAILED(hr)) {
|
||||
LOG_ERROR(Frontend, "CoInitialize failed");
|
||||
return false;
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
CoUninitialize();
|
||||
};
|
||||
IShellLinkW* ps1 = nullptr;
|
||||
IPersistFile* persist_file = nullptr;
|
||||
SCOPE_EXIT {
|
||||
if (persist_file != nullptr) {
|
||||
persist_file->Release();
|
||||
}
|
||||
if (ps1 != nullptr) {
|
||||
ps1->Release();
|
||||
}
|
||||
};
|
||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
|
||||
reinterpret_cast<void**>(&ps1));
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to create IShellLinkW instance");
|
||||
return false;
|
||||
}
|
||||
hres = ps1->SetPath(command.c_str());
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set path");
|
||||
return false;
|
||||
}
|
||||
if (!arguments.empty()) {
|
||||
hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data());
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set arguments");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!comment.empty()) {
|
||||
hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data());
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set description");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (std::filesystem::is_regular_file(icon_path)) {
|
||||
hres = ps1->SetIconLocation(icon_path.c_str(), 0);
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set icon location");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
hres = ps1->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&persist_file));
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to get IPersistFile interface");
|
||||
return false;
|
||||
}
|
||||
hres = persist_file->Save(std::filesystem::path{shortcut_path / (name + ".lnk")}.c_str(), TRUE);
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to save shortcut");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else // Unsupported platform
|
||||
return false;
|
||||
#endif
|
||||
} catch (const std::exception& e) {
|
||||
LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
|
||||
std::filesystem::path& out_icon_path) {
|
||||
// Get path to Yuzu icons directory & icon extension
|
||||
std::string ico_extension = "png";
|
||||
#if defined(_WIN32)
|
||||
out_icon_path = Common::FS::GetEdenPath(Common::FS::EdenPath::IconsDir);
|
||||
ico_extension = "ico";
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256";
|
||||
#endif
|
||||
// Create icons directory if it doesn't exist
|
||||
if (!Common::FS::CreateDirs(out_icon_path)) {
|
||||
out_icon_path.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create icon file path
|
||||
out_icon_path /= (program_id == 0 ? fmt::format("eden-{}.{}", game_file_name, ico_extension)
|
||||
: fmt::format("eden-{:016X}.{}", program_id, ico_extension));
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenRootDataFolder() {
|
||||
QDesktopServices::openUrl(QUrl(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir))));
|
||||
}
|
||||
|
||||
void OpenNANDFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir))));
|
||||
}
|
||||
|
||||
void OpenSDMCFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir))));
|
||||
}
|
||||
|
||||
void OpenModFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir))));
|
||||
}
|
||||
|
||||
void OpenLogFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir))));
|
||||
}
|
||||
|
||||
}
|
44
src/qt_common/qt_game_util.h
Normal file
44
src/qt_common/qt_game_util.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef QT_GAME_UTIL_H
|
||||
#define QT_GAME_UTIL_H
|
||||
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include <array>
|
||||
|
||||
namespace QtCommon {
|
||||
|
||||
static constexpr std::array<const char *, 3> GAME_VERIFICATION_RESULTS = {
|
||||
"The operation completed successfully.",
|
||||
"File contents may be corrupt or missing..",
|
||||
"Firmware installation cancelled, firmware may be in a bad state or corrupted."
|
||||
"File contents could not be checked for validity."
|
||||
};
|
||||
|
||||
inline constexpr const char *GetGameVerificationResultString(ContentManager::GameVerificationResult result)
|
||||
{
|
||||
return GAME_VERIFICATION_RESULTS.at(static_cast<std::size_t>(result));
|
||||
}
|
||||
|
||||
bool CreateShortcutLink(const std::filesystem::path& shortcut_path,
|
||||
const std::string& comment,
|
||||
const std::filesystem::path& icon_path,
|
||||
const std::filesystem::path& command,
|
||||
const std::string& arguments,
|
||||
const std::string& categories,
|
||||
const std::string& keywords,
|
||||
const std::string& name);
|
||||
|
||||
bool MakeShortcutIcoPath(const u64 program_id,
|
||||
const std::string_view game_file_name,
|
||||
std::filesystem::path& out_icon_path);
|
||||
|
||||
void OpenRootDataFolder();
|
||||
void OpenNANDFolder();
|
||||
void OpenSDMCFolder();
|
||||
void OpenModFolder();
|
||||
void OpenLogFolder();
|
||||
}
|
||||
|
||||
#endif // QT_GAME_UTIL_H
|
23
src/qt_common/qt_path_util.cpp
Normal file
23
src/qt_common/qt_path_util.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "qt_path_util.h"
|
||||
#include <QDesktopServices>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
bool QtCommon::PathUtil::OpenShaderCache(u64 program_id)
|
||||
{
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
|
||||
if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
|
||||
const auto qt_shader_cache_path = QString::fromStdString(shader_path_string);
|
||||
return QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
|
||||
}
|
10
src/qt_common/qt_path_util.h
Normal file
10
src/qt_common/qt_path_util.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef QT_PATH_UTIL_H
|
||||
#define QT_PATH_UTIL_H
|
||||
|
||||
#include "common/common_types.h"
|
||||
namespace QtCommon::PathUtil { bool OpenShaderCache(u64 program_id); }
|
||||
|
||||
#endif // QT_PATH_UTIL_H
|
|
@ -7,23 +7,21 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "shared_translation.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QWidget>
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "common/settings_setting.h"
|
||||
#include "common/time_zone.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace ConfigurationShared {
|
||||
|
||||
std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent)
|
||||
std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
|
||||
{
|
||||
std::unique_ptr<TranslationMap> translations = std::make_unique<TranslationMap>();
|
||||
const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); };
|
||||
|
@ -459,7 +457,7 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent)
|
|||
return translations;
|
||||
}
|
||||
|
||||
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent)
|
||||
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
|
||||
{
|
||||
std::unique_ptr<ComboboxTranslationMap> translations = std::make_unique<ComboboxTranslationMap>();
|
||||
const auto& tr = [&](const char* text, const char* context = "") {
|
|
@ -11,23 +11,20 @@
|
|||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
class QWidget;
|
||||
#include "common/settings_enums.h"
|
||||
|
||||
namespace ConfigurationShared {
|
||||
using TranslationMap = std::map<u32, std::pair<QString, QString>>;
|
||||
using ComboboxTranslations = std::vector<std::pair<u32, QString>>;
|
||||
using ComboboxTranslationMap = std::map<u32, ComboboxTranslations>;
|
||||
|
||||
std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent);
|
||||
std::unique_ptr<TranslationMap> InitializeTranslations(QObject *parent);
|
||||
|
||||
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent);
|
||||
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent);
|
||||
|
||||
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map = {
|
||||
{Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "None"))},
|
|
@ -1,10 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QSettings>
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
|
||||
namespace Settings {
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -14,7 +17,7 @@
|
|||
#include "common/common_types.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "configuration/qt_config.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
|
||||
using Settings::Category;
|
||||
using Settings::ConfirmStop;
|
|
@ -150,12 +150,8 @@ add_executable(yuzu
|
|||
configuration/configure_web.ui
|
||||
configuration/input_profiles.cpp
|
||||
configuration/input_profiles.h
|
||||
configuration/shared_translation.cpp
|
||||
configuration/shared_translation.h
|
||||
configuration/shared_widget.cpp
|
||||
configuration/shared_widget.h
|
||||
configuration/qt_config.cpp
|
||||
configuration/qt_config.h
|
||||
debugger/console.cpp
|
||||
debugger/console.h
|
||||
debugger/controller.cpp
|
||||
|
@ -207,12 +203,8 @@ add_executable(yuzu
|
|||
play_time_manager.cpp
|
||||
play_time_manager.h
|
||||
precompiled_headers.h
|
||||
qt_common.cpp
|
||||
qt_common.h
|
||||
startup_checks.cpp
|
||||
startup_checks.h
|
||||
uisettings.cpp
|
||||
uisettings.h
|
||||
util/clickable_label.cpp
|
||||
util/clickable_label.h
|
||||
util/controller_navigation.cpp
|
||||
|
@ -394,14 +386,12 @@ elseif(WIN32)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core)
|
||||
target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core qt_common)
|
||||
target_link_libraries(yuzu PRIVATE Boost::headers glad Qt6::Widgets)
|
||||
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
||||
|
||||
target_link_libraries(yuzu PRIVATE Vulkan::Headers)
|
||||
if (NOT WIN32)
|
||||
target_include_directories(yuzu PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(yuzu PRIVATE Qt6::DBus)
|
||||
endif()
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include "common/settings_enums.h"
|
||||
#include "uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
|
||||
#include <QCamera>
|
||||
#include <QCameraImageCapture>
|
||||
|
@ -59,7 +59,7 @@
|
|||
#include "video_core/renderer_base.h"
|
||||
#include "yuzu/bootmanager.h"
|
||||
#include "yuzu/main.h"
|
||||
#include "yuzu/qt_common.h"
|
||||
#include "qt_common/qt_common.h"
|
||||
|
||||
class QObject;
|
||||
class QPaintEngine;
|
||||
|
@ -240,7 +240,7 @@ class DummyContext : public Core::Frontend::GraphicsContext {};
|
|||
|
||||
class RenderWidget : public QWidget {
|
||||
public:
|
||||
explicit RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) {
|
||||
explicit RenderWidget(GRenderWindow* parent) : QWidget(parent) {
|
||||
setAttribute(Qt::WA_NativeWindow);
|
||||
setAttribute(Qt::WA_PaintOnScreen);
|
||||
if (QtCommon::GetWindowSystemType() == Core::Frontend::WindowSystemType::Wayland) {
|
||||
|
@ -253,9 +253,6 @@ public:
|
|||
QPaintEngine* paintEngine() const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
GRenderWindow* render_window;
|
||||
};
|
||||
|
||||
struct OpenGLRenderWidget : public RenderWidget {
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -16,9 +19,9 @@
|
|||
#include "ui_configure_audio.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_audio.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
ConfigureAudio::ConfigureAudio(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -7,7 +10,7 @@
|
|||
#include <vector>
|
||||
#include <QWidget>
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
|
||||
class QComboBox;
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -12,7 +15,7 @@
|
|||
#include "ui_configure_debug.h"
|
||||
#include "yuzu/configuration/configure_debug.h"
|
||||
#include "yuzu/debugger/console.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
ConfigureDebug::ConfigureDebug(const Core::System& system_, QWidget* parent)
|
||||
: QScrollArea(parent), ui{std::make_unique<Ui::ConfigureDebug>()}, system{system_} {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -27,7 +30,7 @@
|
|||
#include "yuzu/configuration/configure_ui.h"
|
||||
#include "yuzu/configuration/configure_web.h"
|
||||
#include "yuzu/hotkeys.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
|
||||
InputCommon::InputSubsystem* input_subsystem,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -8,7 +11,7 @@
|
|||
#include <QDialog>
|
||||
#include "configuration/shared_widget.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
#include "yuzu/vk_device_info.h"
|
||||
|
||||
namespace Core {
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "yuzu/configuration/configure_filesystem.h"
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "qt_common/qt_common.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "ui_configure_filesystem.h"
|
||||
#include "yuzu/configuration/configure_filesystem.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
ConfigureFilesystem::ConfigureFilesystem(QWidget* parent)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureFilesystem>()) {
|
||||
|
@ -126,19 +130,16 @@ void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit)
|
|||
}
|
||||
|
||||
void ConfigureFilesystem::ResetMetadata() {
|
||||
if (!Common::FS::Exists(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) /
|
||||
"game_list/")) {
|
||||
QMessageBox::information(this, tr("Reset Metadata Cache"),
|
||||
tr("The metadata cache is already empty."));
|
||||
} else if (Common::FS::RemoveDirRecursively(
|
||||
Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) {
|
||||
QMessageBox::information(this, tr("Reset Metadata Cache"),
|
||||
tr("The operation completed successfully."));
|
||||
UISettings::values.is_game_list_reload_pending.exchange(true);
|
||||
} else {
|
||||
QMessageBox::warning(
|
||||
this, tr("Reset Metadata Cache"),
|
||||
tr("The metadata cache couldn't be deleted. It might be in use or non-existent."));
|
||||
auto result = QtCommon::ResetMetadata();
|
||||
const QString resultMessage = tr(QtCommon::GetResetMetadataResultString(result));
|
||||
const QString title = tr("Reset Metadata Cache");
|
||||
|
||||
switch (result) {
|
||||
case QtCommon::MetadataResult::Failure:
|
||||
QMessageBox::warning(this, title, resultMessage);
|
||||
break;
|
||||
default:
|
||||
QMessageBox::information(this, title, resultMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -11,7 +14,7 @@
|
|||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_general.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
ConfigureGeneral::ConfigureGeneral(const Core::System& system_,
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -40,8 +43,8 @@
|
|||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_graphics.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
#include "yuzu/qt_common.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/qt_common.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/vk_device_info.h"
|
||||
|
||||
static const std::vector<VkPresentModeKHR> default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -15,7 +18,7 @@
|
|||
#include <vulkan/vulkan_core.h>
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
#include "vk_device_info.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -9,7 +12,7 @@
|
|||
#include "ui_configure_graphics_advanced.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_graphics_advanced.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
|
||||
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -11,7 +14,7 @@
|
|||
#include "ui_configure_graphics_extensions.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_graphics_extensions.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
#include "yuzu/configuration/shared_widget.h"
|
||||
|
||||
ConfigureGraphicsExtensions::ConfigureGraphicsExtensions(
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -13,7 +16,7 @@
|
|||
#include "ui_configure_hotkeys.h"
|
||||
#include "yuzu/configuration/configure_hotkeys.h"
|
||||
#include "yuzu/hotkeys.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/sequence_dialog/sequence_dialog.h"
|
||||
|
||||
constexpr int name_column = 0;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -9,7 +12,7 @@
|
|||
|
||||
#include "ui_configure_input_per_game.h"
|
||||
#include "yuzu/configuration/input_profiles.h"
|
||||
#include "yuzu/configuration/qt_config.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
|
||||
class QComboBox;
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -12,7 +15,7 @@
|
|||
#include <QTimer>
|
||||
#include "common/assert.h"
|
||||
#include "common/param_package.h"
|
||||
#include "configuration/qt_config.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
#include "frontend_common/config.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -38,7 +41,7 @@
|
|||
#include "yuzu/configuration/configure_per_game.h"
|
||||
#include "yuzu/configuration/configure_per_game_addons.h"
|
||||
#include "yuzu/configuration/configure_system.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/util.h"
|
||||
#include "yuzu/vk_device_info.h"
|
||||
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -15,8 +18,8 @@
|
|||
#include "frontend_common/config.h"
|
||||
#include "vk_device_info.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/qt_config.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -21,7 +24,7 @@
|
|||
#include "ui_configure_per_game_addons.h"
|
||||
#include "yuzu/configuration/configure_input.h"
|
||||
#include "yuzu/configuration/configure_per_game_addons.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* parent)
|
||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigurePerGameAddons>()}, system{system_} {
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -8,7 +11,7 @@
|
|||
#include <QTimer>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include "configuration/qt_config.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "input_common/drivers/keyboard.h"
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -8,7 +11,7 @@
|
|||
#include "common/settings.h"
|
||||
#include "ui_configure_tas.h"
|
||||
#include "yuzu/configuration/configure_tas.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
ConfigureTasDialog::ConfigureTasDialog(QWidget* parent)
|
||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureTas>()) {
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "core/core.h"
|
||||
#include "core/frontend/framebuffer_layout.h"
|
||||
#include "ui_configure_ui.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
namespace {
|
||||
constexpr std::array default_game_icon_sizes{
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <QtConcurrent/QtConcurrentRun>
|
||||
#include "common/settings.h"
|
||||
#include "ui_configure_web.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
ConfigureWeb::ConfigureWeb(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -6,7 +9,7 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "configuration/qt_config.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -42,7 +45,7 @@
|
|||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_common.h"
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
|
||||
namespace ConfigurationShared {
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -11,7 +14,7 @@
|
|||
#include <QStringLiteral>
|
||||
#include <QWidget>
|
||||
#include <qobjectdefs.h>
|
||||
#include "yuzu/configuration/shared_translation.h"
|
||||
#include "qt_common/shared_translation.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -9,7 +12,7 @@
|
|||
|
||||
#include "common/logging/backend.h"
|
||||
#include "yuzu/debugger/console.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
namespace Debugger {
|
||||
void ToggleConsole() {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -5,7 +8,7 @@
|
|||
#include <fmt/ranges.h>
|
||||
|
||||
#include "yuzu/debugger/wait_tree.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
#include "core/arm/debug.h"
|
||||
#include "core/core.h"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "yuzu/game_list_p.h"
|
||||
#include "yuzu/game_list_worker.h"
|
||||
#include "yuzu/main.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/controller_navigation.h"
|
||||
|
||||
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent)
|
||||
|
@ -820,7 +820,7 @@ QStandardItemModel* GameList::GetModel() const {
|
|||
return item_model;
|
||||
}
|
||||
|
||||
void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs, const bool cached)
|
||||
void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs)
|
||||
{
|
||||
tree_view->setEnabled(false);
|
||||
|
||||
|
@ -843,8 +843,7 @@ void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs, const bool
|
|||
game_dirs,
|
||||
compatibility_list,
|
||||
play_time_manager,
|
||||
system,
|
||||
cached);
|
||||
system);
|
||||
|
||||
// Get events from the worker as data becomes available
|
||||
connect(current_worker.get(), &GameListWorker::DataAvailable, this, &GameList::WorkerEvent,
|
||||
|
@ -873,14 +872,6 @@ const QStringList GameList::supported_file_extensions = {
|
|||
QStringLiteral("nso"), QStringLiteral("nro"), QStringLiteral("nca"),
|
||||
QStringLiteral("xci"), QStringLiteral("nsp"), QStringLiteral("kip")};
|
||||
|
||||
void GameList::ForceRefreshGameDirectory()
|
||||
{
|
||||
if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
|
||||
LOG_INFO(Frontend, "Force-reloading game list per user request.");
|
||||
PopulateAsync(UISettings::values.game_dirs, false);
|
||||
}
|
||||
}
|
||||
|
||||
void GameList::RefreshGameDirectory()
|
||||
{
|
||||
if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
#include "uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/compatibility_list.h"
|
||||
#include "yuzu/play_time_manager.h"
|
||||
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
bool IsEmpty() const;
|
||||
|
||||
void LoadCompatibilityList();
|
||||
void PopulateAsync(QVector<UISettings::GameDir>& game_dirs, const bool cached = true);
|
||||
void PopulateAsync(QVector<UISettings::GameDir>& game_dirs);
|
||||
|
||||
void SaveInterfaceLayout();
|
||||
void LoadInterfaceLayout();
|
||||
|
@ -110,7 +110,6 @@ public:
|
|||
static const QStringList supported_file_extensions;
|
||||
|
||||
public slots:
|
||||
void ForceRefreshGameDirectory();
|
||||
void RefreshGameDirectory();
|
||||
|
||||
signals:
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -19,7 +22,7 @@
|
|||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "yuzu/play_time_manager.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/util.h"
|
||||
|
||||
enum class GameListItemType {
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -27,7 +30,7 @@
|
|||
#include "yuzu/game_list.h"
|
||||
#include "yuzu/game_list_p.h"
|
||||
#include "yuzu/game_list_worker.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -199,8 +202,7 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path,
|
|||
u64 program_id,
|
||||
const CompatibilityList& compatibility_list,
|
||||
const PlayTime::PlayTimeManager& play_time_manager,
|
||||
const FileSys::PatchManager& patch,
|
||||
const bool cached)
|
||||
const FileSys::PatchManager& patch)
|
||||
{
|
||||
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||
|
||||
|
@ -224,14 +226,10 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path,
|
|||
|
||||
QString patch_versions;
|
||||
|
||||
if (cached) {
|
||||
patch_versions = GetGameListCachedObject(
|
||||
fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] {
|
||||
return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable());
|
||||
});
|
||||
} else {
|
||||
patch_versions = FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable());
|
||||
}
|
||||
patch_versions = GetGameListCachedObject(
|
||||
fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] {
|
||||
return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable());
|
||||
});
|
||||
|
||||
list.insert(2, new GameListItem(patch_versions));
|
||||
|
||||
|
@ -244,15 +242,13 @@ GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs_,
|
|||
QVector<UISettings::GameDir>& game_dirs_,
|
||||
const CompatibilityList& compatibility_list_,
|
||||
const PlayTime::PlayTimeManager& play_time_manager_,
|
||||
Core::System& system_,
|
||||
const bool cached_)
|
||||
Core::System& system_)
|
||||
: vfs{std::move(vfs_)}
|
||||
, provider{provider_}
|
||||
, game_dirs{game_dirs_}
|
||||
, compatibility_list{compatibility_list_}
|
||||
, play_time_manager{play_time_manager_}
|
||||
, system{system_}
|
||||
, cached{cached_}
|
||||
{
|
||||
// We want the game list to manage our lifetime.
|
||||
setAutoDelete(false);
|
||||
|
@ -355,8 +351,7 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
|
|||
program_id,
|
||||
compatibility_list,
|
||||
play_time_manager,
|
||||
patch,
|
||||
cached);
|
||||
patch);
|
||||
RecordEvent([=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); });
|
||||
}
|
||||
}
|
||||
|
@ -439,8 +434,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
|
|||
id,
|
||||
compatibility_list,
|
||||
play_time_manager,
|
||||
patch,
|
||||
cached);
|
||||
patch);
|
||||
|
||||
RecordEvent(
|
||||
[=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); });
|
||||
|
@ -463,8 +457,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
|
|||
program_id,
|
||||
compatibility_list,
|
||||
play_time_manager,
|
||||
patch,
|
||||
cached);
|
||||
patch);
|
||||
|
||||
RecordEvent(
|
||||
[=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); });
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -15,7 +18,7 @@
|
|||
|
||||
#include "common/thread.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/compatibility_list.h"
|
||||
#include "yuzu/play_time_manager.h"
|
||||
|
||||
|
@ -45,8 +48,7 @@ public:
|
|||
QVector<UISettings::GameDir>& game_dirs_,
|
||||
const CompatibilityList& compatibility_list_,
|
||||
const PlayTime::PlayTimeManager& play_time_manager_,
|
||||
Core::System& system_,
|
||||
const bool cached = true);
|
||||
Core::System& system_);
|
||||
~GameListWorker() override;
|
||||
|
||||
/// Starts the processing of directory tree information.
|
||||
|
@ -95,6 +97,4 @@ private:
|
|||
Common::Event processing_completed;
|
||||
|
||||
Core::System& system;
|
||||
|
||||
const bool cached;
|
||||
};
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -8,7 +11,7 @@
|
|||
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "yuzu/hotkeys.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
HotkeyRegistry::HotkeyRegistry() = default;
|
||||
HotkeyRegistry::~HotkeyRegistry() = default;
|
||||
|
|
|
@ -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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -8,7 +11,7 @@
|
|||
#include <QListWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include "yuzu/install_dialog.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
InstallDialog::InstallDialog(QWidget* parent, const QStringList& files) : QDialog(parent) {
|
||||
file_list = new QListWidget(this);
|
||||
|
|
|
@ -11,8 +11,9 @@
|
|||
#include "core/loader/nca.h"
|
||||
#include "core/tools/renderdoc.h"
|
||||
#include "frontend_common/firmware_manager.h"
|
||||
|
||||
#include <JlCompress.h>
|
||||
#include "qt_common/qt_common.h"
|
||||
#include "qt_common/qt_game_util.h"
|
||||
#include "qt_common/qt_path_util.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h> // for chdir
|
||||
|
@ -116,7 +117,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
|||
#include "common/scm_rev.h"
|
||||
#include "common/scope_exit.h"
|
||||
#ifdef _WIN32
|
||||
#include <shlobj.h>
|
||||
#include "common/windows/timer_resolution.h"
|
||||
#endif
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
|
@ -154,7 +154,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
|||
#include "yuzu/compatibility_list.h"
|
||||
#include "yuzu/configuration/configure_dialog.h"
|
||||
#include "yuzu/configuration/configure_input_per_game.h"
|
||||
#include "yuzu/configuration/qt_config.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
#include "yuzu/debugger/console.h"
|
||||
#include "yuzu/debugger/controller.h"
|
||||
#include "yuzu/debugger/profiler.h"
|
||||
|
@ -168,7 +168,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
|||
#include "yuzu/main.h"
|
||||
#include "yuzu/play_time_manager.h"
|
||||
#include "yuzu/startup_checks.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/clickable_label.h"
|
||||
#include "yuzu/vk_device_info.h"
|
||||
|
||||
|
@ -470,7 +470,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
|
|||
|
||||
game_list->LoadCompatibilityList();
|
||||
// force reload on first load to ensure add-ons get updated
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs, false);
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
|
||||
// make sure menubar has the arrow cursor instead of inheriting from this
|
||||
ui->menubar->setCursor(QCursor());
|
||||
|
@ -1076,7 +1076,7 @@ void GMainWindow::InitializeWidgets() {
|
|||
loading_screen = new LoadingScreen(this);
|
||||
loading_screen->hide();
|
||||
ui->horizontalLayout->addWidget(loading_screen);
|
||||
connect(loading_screen, &LoadingScreen::Hidden, [&] {
|
||||
connect(loading_screen, &LoadingScreen::Hidden, this, [&] {
|
||||
loading_screen->Clear();
|
||||
if (emulation_running) {
|
||||
render_window->show();
|
||||
|
@ -2518,17 +2518,11 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
|
|||
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
|
||||
}
|
||||
|
||||
// TODO(crueter): Transfer ts to showmessage
|
||||
void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
|
||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
|
||||
if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
|
||||
QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"),
|
||||
tr("Failed to create the shader cache directory for this title."));
|
||||
return;
|
||||
if (!QtCommon::PathUtil::OpenShaderCache(program_id)) {
|
||||
QMessageBox::warning(this, tr("Error Opening Shader Cache"), tr("Failed to create or open shader cache for this title, ensure your app data directory has write permissions."));
|
||||
}
|
||||
const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
|
||||
const auto qt_shader_cache_path = QString::fromStdString(shader_path_string);
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
|
||||
}
|
||||
|
||||
static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& dialog,
|
||||
|
@ -2593,6 +2587,9 @@ static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog&
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO(crueter): All this can be transfered to qt_common
|
||||
// Aldoe I need to decide re: message boxes for QML
|
||||
// translations_common? strings_common? qt_strings? who knows
|
||||
QString GMainWindow::GetGameListErrorRemoving(InstalledEntryType type) const {
|
||||
switch (type) {
|
||||
case InstalledEntryType::Game:
|
||||
|
@ -2949,12 +2946,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
|||
}
|
||||
}
|
||||
|
||||
// END
|
||||
void GMainWindow::OnGameListVerifyIntegrity(const std::string& game_path) {
|
||||
const auto NotImplemented = [this] {
|
||||
QMessageBox::warning(this, tr("Integrity verification couldn't be performed!"),
|
||||
tr("File contents were not checked for validity."));
|
||||
};
|
||||
|
||||
QProgressDialog progress(tr("Verifying integrity..."), tr("Cancel"), 0, 100, this);
|
||||
progress.setWindowModality(Qt::WindowModal);
|
||||
progress.setMinimumDuration(100);
|
||||
|
@ -2967,18 +2960,20 @@ void GMainWindow::OnGameListVerifyIntegrity(const std::string& game_path) {
|
|||
};
|
||||
|
||||
const auto result = ContentManager::VerifyGameContents(*system, game_path, QtProgressCallback);
|
||||
const QString resultString = tr(QtCommon::GetGameVerificationResultString(result));
|
||||
progress.close();
|
||||
switch (result) {
|
||||
case ContentManager::GameVerificationResult::Success:
|
||||
QMessageBox::information(this, tr("Integrity verification succeeded!"),
|
||||
tr("The operation completed successfully."));
|
||||
resultString);
|
||||
break;
|
||||
case ContentManager::GameVerificationResult::Failed:
|
||||
QMessageBox::critical(this, tr("Integrity verification failed!"),
|
||||
tr("File contents may be corrupt."));
|
||||
resultString);
|
||||
break;
|
||||
case ContentManager::GameVerificationResult::NotImplemented:
|
||||
NotImplemented();
|
||||
QMessageBox::warning(this, tr("Integrity verification couldn't be performed"),
|
||||
resultString);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2999,109 +2994,8 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id,
|
|||
QDesktopServices::openUrl(QUrl(QStringLiteral("https://eden-emulator.github.io/game/") + directory));
|
||||
}
|
||||
|
||||
bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
|
||||
const std::string& comment,
|
||||
const std::filesystem::path& icon_path,
|
||||
const std::filesystem::path& command,
|
||||
const std::string& arguments, const std::string& categories,
|
||||
const std::string& keywords, const std::string& name) try {
|
||||
#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD
|
||||
std::filesystem::path shortcut_path_full = shortcut_path / (name + ".desktop");
|
||||
std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc);
|
||||
if (!shortcut_stream.is_open()) {
|
||||
LOG_ERROR(Frontend, "Failed to create shortcut");
|
||||
return false;
|
||||
}
|
||||
// TODO: Migrate fmt::print to std::print in futures STD C++ 23.
|
||||
fmt::print(shortcut_stream, "[Desktop Entry]\n");
|
||||
fmt::print(shortcut_stream, "Type=Application\n");
|
||||
fmt::print(shortcut_stream, "Version=1.0\n");
|
||||
fmt::print(shortcut_stream, "Name={}\n", name);
|
||||
if (!comment.empty()) {
|
||||
fmt::print(shortcut_stream, "Comment={}\n", comment);
|
||||
}
|
||||
if (std::filesystem::is_regular_file(icon_path)) {
|
||||
fmt::print(shortcut_stream, "Icon={}\n", icon_path.string());
|
||||
}
|
||||
fmt::print(shortcut_stream, "TryExec={}\n", command.string());
|
||||
fmt::print(shortcut_stream, "Exec={} {}\n", command.string(), arguments);
|
||||
if (!categories.empty()) {
|
||||
fmt::print(shortcut_stream, "Categories={}\n", categories);
|
||||
}
|
||||
if (!keywords.empty()) {
|
||||
fmt::print(shortcut_stream, "Keywords={}\n", keywords);
|
||||
}
|
||||
return true;
|
||||
#elif defined(_WIN32) // Windows
|
||||
HRESULT hr = CoInitialize(nullptr);
|
||||
if (FAILED(hr)) {
|
||||
LOG_ERROR(Frontend, "CoInitialize failed");
|
||||
return false;
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
CoUninitialize();
|
||||
};
|
||||
IShellLinkW* ps1 = nullptr;
|
||||
IPersistFile* persist_file = nullptr;
|
||||
SCOPE_EXIT {
|
||||
if (persist_file != nullptr) {
|
||||
persist_file->Release();
|
||||
}
|
||||
if (ps1 != nullptr) {
|
||||
ps1->Release();
|
||||
}
|
||||
};
|
||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
|
||||
reinterpret_cast<void**>(&ps1));
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to create IShellLinkW instance");
|
||||
return false;
|
||||
}
|
||||
hres = ps1->SetPath(command.c_str());
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set path");
|
||||
return false;
|
||||
}
|
||||
if (!arguments.empty()) {
|
||||
hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data());
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set arguments");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!comment.empty()) {
|
||||
hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data());
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set description");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (std::filesystem::is_regular_file(icon_path)) {
|
||||
hres = ps1->SetIconLocation(icon_path.c_str(), 0);
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to set icon location");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
hres = ps1->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&persist_file));
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to get IPersistFile interface");
|
||||
return false;
|
||||
}
|
||||
hres = persist_file->Save(std::filesystem::path{shortcut_path / (name + ".lnk")}.c_str(), TRUE);
|
||||
if (FAILED(hres)) {
|
||||
LOG_ERROR(Frontend, "Failed to save shortcut");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else // Unsupported platform
|
||||
return false;
|
||||
#endif
|
||||
} catch (const std::exception& e) {
|
||||
LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
// Messages in pre-defined message boxes for less code spaghetti
|
||||
// TODO(crueter): Still need to decide what to do re: message boxes w/ qml
|
||||
bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) {
|
||||
int result = 0;
|
||||
QMessageBox::StandardButtons buttons;
|
||||
|
@ -3132,33 +3026,6 @@ bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QSt
|
|||
}
|
||||
}
|
||||
|
||||
bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
|
||||
std::filesystem::path& out_icon_path) {
|
||||
// Get path to Yuzu icons directory & icon extension
|
||||
std::string ico_extension = "png";
|
||||
#if defined(_WIN32)
|
||||
out_icon_path = Common::FS::GetEdenPath(Common::FS::EdenPath::IconsDir);
|
||||
ico_extension = "ico";
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256";
|
||||
#endif
|
||||
// Create icons directory if it doesn't exist
|
||||
if (!Common::FS::CreateDirs(out_icon_path)) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Create Icon"),
|
||||
tr("Cannot create icon file. Path \"%1\" does not exist and cannot be created.")
|
||||
.arg(QString::fromStdString(out_icon_path.string())),
|
||||
QMessageBox::StandardButton::Ok);
|
||||
out_icon_path.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create icon file path
|
||||
out_icon_path /= (program_id == 0 ? fmt::format("eden-{}.{}", game_file_name, ico_extension)
|
||||
: fmt::format("eden-{:016X}.{}", program_id, ico_extension));
|
||||
return true;
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& game_path,
|
||||
GameListShortcutTarget target) {
|
||||
// Create shortcut
|
||||
|
@ -4185,32 +4052,27 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
|
|||
}
|
||||
|
||||
void GMainWindow::OnOpenRootDataFolder() {
|
||||
QDesktopServices::openUrl(QUrl(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir))));
|
||||
QtCommon::OpenRootDataFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenNANDFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir))));
|
||||
QtCommon::OpenNANDFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenSDMCFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir))));
|
||||
QtCommon::OpenSDMCFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenModFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir))));
|
||||
QtCommon::OpenModFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenLogFolder()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir))));
|
||||
QtCommon::OpenLogFolder();
|
||||
}
|
||||
|
||||
void GMainWindow::OnVerifyInstalledContents() {
|
||||
|
@ -4258,104 +4120,23 @@ void GMainWindow::InstallFirmware(const QString &location, bool recursive)
|
|||
return progress.wasCanceled();
|
||||
};
|
||||
|
||||
LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString());
|
||||
auto result = QtCommon::InstallFirmware(location, recursive, QtProgressCallback, system.get(), vfs.get(), this);
|
||||
|
||||
// Check for a reasonable number of .nca files (don't hardcode them, just see if there's some in
|
||||
// there.)
|
||||
std::filesystem::path firmware_source_path = location.toStdString();
|
||||
if (!Common::FS::IsDir(firmware_source_path)) {
|
||||
progress.close();
|
||||
return;
|
||||
}
|
||||
progress.close();
|
||||
|
||||
std::vector<std::filesystem::path> out;
|
||||
const Common::FS::DirEntryCallable callback =
|
||||
[&out](const std::filesystem::directory_entry& entry) {
|
||||
if (entry.path().has_extension() && entry.path().extension() == ".nca") {
|
||||
out.emplace_back(entry.path());
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
QtProgressCallback(100, 10);
|
||||
|
||||
if (recursive) {
|
||||
Common::FS::IterateDirEntriesRecursively(firmware_source_path, callback, Common::FS::DirEntryFilter::File);
|
||||
} else {
|
||||
Common::FS::IterateDirEntries(firmware_source_path, callback, Common::FS::DirEntryFilter::File);
|
||||
}
|
||||
|
||||
if (out.size() <= 0) {
|
||||
progress.close();
|
||||
QMessageBox::warning(this, tr("Firmware install failed"),
|
||||
tr("Unable to locate potential firmware NCA files"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Locate and erase the content of nand/system/Content/registered/*.nca, if any.
|
||||
auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory();
|
||||
if (!sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
|
||||
progress.close();
|
||||
QMessageBox::critical(this, tr("Firmware install failed"),
|
||||
tr("Failed to delete one or more firmware file."));
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(Frontend,
|
||||
"Cleaned nand/system/Content/registered folder in preparation for new firmware.");
|
||||
|
||||
QtProgressCallback(100, 20);
|
||||
|
||||
auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered");
|
||||
|
||||
bool success = true;
|
||||
int i = 0;
|
||||
for (const auto& firmware_src_path : out) {
|
||||
i++;
|
||||
auto firmware_src_vfile =
|
||||
vfs->OpenFile(firmware_src_path.generic_string(), FileSys::OpenMode::Read);
|
||||
auto firmware_dst_vfile =
|
||||
firmware_vdir->CreateFileRelative(firmware_src_path.filename().string());
|
||||
|
||||
if (!VfsRawCopy(firmware_src_vfile, firmware_dst_vfile)) {
|
||||
LOG_ERROR(Frontend, "Failed to copy firmware file {} to {} in registered folder!",
|
||||
firmware_src_path.generic_string(), firmware_src_path.filename().string());
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (QtProgressCallback(
|
||||
100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) {
|
||||
progress.close();
|
||||
QMessageBox::warning(
|
||||
this, tr("Firmware install failed"),
|
||||
tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. "
|
||||
"Restart Eden or re-install firmware."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
progress.close();
|
||||
QMessageBox::critical(this, tr("Firmware install failed"),
|
||||
tr("One or more firmware files failed to copy into NAND."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-scan VFS for the newly placed firmware files.
|
||||
system->GetFileSystemController().CreateFactories(*vfs);
|
||||
if (result != QtCommon::FirmwareInstallResult::Success) return;
|
||||
|
||||
auto VerifyFirmwareCallback = [&](size_t total_size, size_t processed_size) {
|
||||
progress.setValue(90 + static_cast<int>((processed_size * 10) / total_size));
|
||||
return progress.wasCanceled();
|
||||
};
|
||||
|
||||
auto result =
|
||||
auto results =
|
||||
ContentManager::VerifyInstalledContents(*system, *provider, VerifyFirmwareCallback, true);
|
||||
|
||||
if (result.size() > 0) {
|
||||
if (results.size() > 0) {
|
||||
const auto failed_names =
|
||||
QString::fromStdString(fmt::format("{}", fmt::join(result, "\n")));
|
||||
QString::fromStdString(fmt::format("{}", fmt::join(results, "\n")));
|
||||
progress.close();
|
||||
QMessageBox::critical(
|
||||
this, tr("Firmware integrity verification failed!"),
|
||||
|
@ -4412,32 +4193,14 @@ void GMainWindow::OnInstallFirmwareFromZIP()
|
|||
return;
|
||||
}
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
fs::path tmp{std::filesystem::temp_directory_path()};
|
||||
const QString qCacheDir = QtCommon::UnzipFirmwareToTmp(firmware_zip_location);
|
||||
|
||||
if (!std::filesystem::create_directories(tmp / "eden" / "firmware")) {
|
||||
goto unzipFailed;
|
||||
}
|
||||
|
||||
{
|
||||
tmp /= "eden";
|
||||
tmp /= "firmware";
|
||||
|
||||
QString qCacheDir = QString::fromStdString(tmp.string());
|
||||
|
||||
QFile zip(firmware_zip_location);
|
||||
|
||||
QStringList result = JlCompress::extractDir(&zip, qCacheDir);
|
||||
if (result.isEmpty()) {
|
||||
goto unzipFailed;
|
||||
}
|
||||
|
||||
// In this case, it has to be done recursively, since sometimes people
|
||||
// will pack it into a subdirectory after dumping
|
||||
// In this case, it has to be done recursively, since sometimes people
|
||||
// will pack it into a subdirectory after dumping
|
||||
if (!qCacheDir.isEmpty()) {
|
||||
InstallFirmware(qCacheDir, true);
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::remove_all(tmp, ec);
|
||||
std::filesystem::remove_all(std::filesystem::temp_directory_path() / "eden" / "firmware", ec);
|
||||
|
||||
if (ec) {
|
||||
QMessageBox::warning(this, tr("Firmware cleanup failed"),
|
||||
|
@ -4445,14 +4208,7 @@ void GMainWindow::OnInstallFirmwareFromZIP()
|
|||
"Check write permissions in the system temp directory and try again.\nOS reported error: %1")
|
||||
.arg(QString::fromStdString(ec.message())));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
unzipFailed:
|
||||
QMessageBox::critical(this, tr("Firmware unzip failed"),
|
||||
tr("Check write permissions in the system temp directory and try again."));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void GMainWindow::OnInstallDecryptionKeys() {
|
||||
|
@ -4509,8 +4265,9 @@ void GMainWindow::OnToggleStatusBar() {
|
|||
|
||||
void GMainWindow::OnGameListRefresh()
|
||||
{
|
||||
// force reload add-ons etc
|
||||
game_list->ForceRefreshGameDirectory();
|
||||
// Resets metadata cache and reloads
|
||||
QtCommon::ResetMetadata();
|
||||
game_list->RefreshGameDirectory();
|
||||
}
|
||||
|
||||
void GMainWindow::OnAlbum() {
|
||||
|
@ -4518,7 +4275,7 @@ void GMainWindow::OnAlbum() {
|
|||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
QMessageBox::warning(this, tr("No firmware available"),
|
||||
tr("Please install the firmware to use the Album applet."));
|
||||
tr("Please install firmware to use the Album applet."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4541,7 +4298,7 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
|
|||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
QMessageBox::warning(this, tr("No firmware available"),
|
||||
tr("Please install the firmware to use the Cabinet applet."));
|
||||
tr("Please install firmware to use the Cabinet applet."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4565,7 +4322,7 @@ void GMainWindow::OnMiiEdit() {
|
|||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
QMessageBox::warning(this, tr("No firmware available"),
|
||||
tr("Please install the firmware to use the Mii editor."));
|
||||
tr("Please install firmware to use the Mii editor."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4588,7 +4345,7 @@ void GMainWindow::OnOpenControllerMenu() {
|
|||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
QMessageBox::warning(this, tr("No firmware available"),
|
||||
tr("Please install the firmware to use the Controller Menu."));
|
||||
tr("Please install firmware to use the Controller Menu."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4613,7 +4370,7 @@ void GMainWindow::OnHomeMenu() {
|
|||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
QMessageBox::warning(this, tr("No firmware available"),
|
||||
tr("Please install the firmware to use the Home Menu."));
|
||||
tr("Please install firmware to use the Home Menu."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4637,7 +4394,7 @@ void GMainWindow::OnInitialSetup()
|
|||
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
QMessageBox::warning(this, tr("No firmware available"),
|
||||
tr("Please install the firmware to use Starter."));
|
||||
tr("Please install firmware to use Starter."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4700,7 +4457,7 @@ std::filesystem::path GMainWindow::GetShortcutPath(GameListShortcutTarget target
|
|||
}
|
||||
|
||||
void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program_id, const std::string& game_title_, GameListShortcutTarget target, std::string arguments_, const bool needs_title) {
|
||||
// Get path to yuzu executable
|
||||
// Get path to Eden executable
|
||||
std::filesystem::path command = GetEdenCommand();
|
||||
|
||||
// Shortcut path
|
||||
|
@ -4752,10 +4509,16 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program
|
|||
QImage icon_data =
|
||||
QImage::fromData(icon_image_file.data(), static_cast<int>(icon_image_file.size()));
|
||||
std::filesystem::path out_icon_path;
|
||||
if (GMainWindow::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) {
|
||||
if (QtCommon::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) {
|
||||
if (!SaveIconToFile(out_icon_path, icon_data)) {
|
||||
LOG_ERROR(Frontend, "Could not write icon to file");
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(
|
||||
this, tr("Create Icon"),
|
||||
tr("Cannot create icon file. Path \"%1\" does not exist and cannot be created.")
|
||||
.arg(QString::fromStdString(out_icon_path.string())),
|
||||
QMessageBox::StandardButton::Ok);
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
|
@ -4776,11 +4539,11 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program
|
|||
this, GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, qgame_title)) {
|
||||
arguments = "-f " + arguments;
|
||||
}
|
||||
const std::string comment = fmt::format("Start {:s} with the eden Emulator", game_title);
|
||||
const std::string comment = fmt::format("Start {:s} with the Eden Emulator", game_title);
|
||||
const std::string categories = "Game;Emulator;Qt;";
|
||||
const std::string keywords = "Switch;Nintendo;";
|
||||
|
||||
if (GMainWindow::CreateShortcutLink(shortcut_path, comment, out_icon_path, command,
|
||||
if (QtCommon::CreateShortcutLink(shortcut_path, comment, out_icon_path, command,
|
||||
arguments, categories, keywords, game_title)) {
|
||||
GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS,
|
||||
qgame_title);
|
||||
|
@ -4810,6 +4573,7 @@ void GMainWindow::OnCreateHomeMenuShortcut(GameListShortcutTarget target)
|
|||
auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program);
|
||||
const auto game_path = qlaunch_applet_nca->GetFullPath();
|
||||
|
||||
// TODO(crueter): Make this use the Eden icon
|
||||
CreateShortcut(game_path, QLaunchId, "Switch Home Menu", target, "-qlaunch", false);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <QTranslator>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "configuration/qt_config.h"
|
||||
#include "qt_common/qt_config.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include "input_common/drivers/tas_input.h"
|
||||
#include "user_data_migration.h"
|
||||
|
@ -478,13 +478,7 @@ private:
|
|||
|
||||
QString GetTasStateDescription() const;
|
||||
bool CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title);
|
||||
bool MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
|
||||
std::filesystem::path& out_icon_path);
|
||||
bool CreateShortcutLink(const std::filesystem::path& shortcut_path, const std::string& comment,
|
||||
const std::filesystem::path& icon_path,
|
||||
const std::filesystem::path& command, const std::string& arguments,
|
||||
const std::string& categories, const std::string& keywords,
|
||||
const std::string& name);
|
||||
|
||||
/**
|
||||
* Mimic the behavior of QMessageBox::question but link controller navigation to the dialog
|
||||
* The only difference is that it returns a boolean.
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "yuzu/multiplayer/message.h"
|
||||
#include "yuzu/multiplayer/state.h"
|
||||
#include "yuzu/multiplayer/validation.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
|
||||
enum class ConnectionType : u8 { TraversalServer, IP };
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "yuzu/multiplayer/message.h"
|
||||
#include "yuzu/multiplayer/state.h"
|
||||
#include "yuzu/multiplayer/validation.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#ifdef ENABLE_WEB_SERVICE
|
||||
#include "web_service/verify_user_jwt.h"
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "yuzu/multiplayer/message.h"
|
||||
#include "yuzu/multiplayer/state.h"
|
||||
#include "yuzu/multiplayer/validation.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#ifdef ENABLE_WEB_SERVICE
|
||||
#include "web_service/web_backend.h"
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2018 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -19,7 +22,7 @@
|
|||
#include "yuzu/multiplayer/lobby.h"
|
||||
#include "yuzu/multiplayer/message.h"
|
||||
#include "yuzu/multiplayer/state.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "qt_common/uisettings.h"
|
||||
#include "yuzu/util/clickable_label.h"
|
||||
|
||||
MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model_,
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -9,8 +12,9 @@
|
|||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/polyfill_thread.h"
|
||||
#include <common/polyfill_thread.h>
|
||||
|
||||
// TODO(crueter): Extract this into frontend_common
|
||||
namespace Service::Account {
|
||||
class ProfileManager;
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QStringLiteral>
|
||||
#include <QWindow>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "yuzu/qt_common.h"
|
||||
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <objc/message.h>
|
||||
#endif
|
||||
|
||||
namespace QtCommon {
|
||||
Core::Frontend::WindowSystemType GetWindowSystemType() {
|
||||
// Determine WSI type based on Qt platform.
|
||||
QString platform_name = QGuiApplication::platformName();
|
||||
if (platform_name == QStringLiteral("windows"))
|
||||
return Core::Frontend::WindowSystemType::Windows;
|
||||
else if (platform_name == QStringLiteral("xcb"))
|
||||
return Core::Frontend::WindowSystemType::X11;
|
||||
else if (platform_name == QStringLiteral("wayland"))
|
||||
return Core::Frontend::WindowSystemType::Wayland;
|
||||
else if (platform_name == QStringLiteral("wayland-egl"))
|
||||
return Core::Frontend::WindowSystemType::Wayland;
|
||||
else if (platform_name == QStringLiteral("cocoa"))
|
||||
return Core::Frontend::WindowSystemType::Cocoa;
|
||||
else if (platform_name == QStringLiteral("android"))
|
||||
return Core::Frontend::WindowSystemType::Android;
|
||||
|
||||
LOG_CRITICAL(Frontend, "Unknown Qt platform {}!", platform_name.toStdString());
|
||||
return Core::Frontend::WindowSystemType::Windows;
|
||||
} // namespace Core::Frontend::WindowSystemType
|
||||
|
||||
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) {
|
||||
Core::Frontend::EmuWindow::WindowSystemInfo wsi;
|
||||
wsi.type = GetWindowSystemType();
|
||||
|
||||
#if defined(WIN32)
|
||||
// Our Win32 Qt external doesn't have the private API.
|
||||
wsi.render_surface = reinterpret_cast<void*>(window->winId());
|
||||
#elif defined(__APPLE__)
|
||||
wsi.render_surface = reinterpret_cast<void* (*)(id, SEL)>(objc_msgSend)(
|
||||
reinterpret_cast<id>(window->winId()), sel_registerName("layer"));
|
||||
#else
|
||||
QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface();
|
||||
wsi.display_connection = pni->nativeResourceForWindow("display", window);
|
||||
if (wsi.type == Core::Frontend::WindowSystemType::Wayland)
|
||||
wsi.render_surface = window ? pni->nativeResourceForWindow("surface", window) : nullptr;
|
||||
else
|
||||
wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr;
|
||||
#endif
|
||||
wsi.render_surface_scale = window ? static_cast<float>(window->devicePixelRatio()) : 1.0f;
|
||||
|
||||
return wsi;
|
||||
}
|
||||
} // namespace QtCommon
|
|
@ -1,15 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWindow>
|
||||
#include "core/frontend/emu_window.h"
|
||||
|
||||
namespace QtCommon {
|
||||
|
||||
Core::Frontend::WindowSystemType GetWindowSystemType();
|
||||
|
||||
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window);
|
||||
|
||||
} // namespace QtCommon
|
|
@ -1,10 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "yuzu/qt_common.h"
|
||||
#include "qt_common/qt_common.h"
|
||||
|
||||
#include "common/dynamic_library.h"
|
||||
#include "common/logging/log.h"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue