more fixes
Some checks failed
eden-build / source (pull_request) Has been skipped
eden-build / android (pull_request) Has been cancelled
eden-build / linux (pull_request) Has been cancelled
eden-build / windows (msvc) (pull_request) Has been cancelled
eden-license / license-header (pull_request_target) Failing after 17s

- replaced some user-facing references to legacy with eden
- added progress bar & threading to migration
- disable Citron migration for now

Signed-off-by: swurl <swurl@swurl.xyz>
This commit is contained in:
swurl 2025-05-11 00:27:11 -04:00
parent 3c17854e05
commit ae3960fefa
Signed by: crueter
GPG key ID: A5A7629F109C8FD1
12 changed files with 233 additions and 145 deletions

View file

@ -238,6 +238,8 @@ add_executable(yuzu
yuzu.qrc yuzu.qrc
yuzu.rc yuzu.rc
migration_dialog.h migration_dialog.cpp migration_dialog.h migration_dialog.cpp
migration_worker.h
migration_worker.cpp
) )
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden") set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")

View file

@ -2656,7 +2656,7 @@
<item row="2" column="0"> <item row="2" column="0">
<widget class="QCheckBox" name="enable_raw_input"> <widget class="QCheckBox" name="enable_raw_input">
<property name="toolTip"> <property name="toolTip">
<string>Requires restarting yuzu</string> <string>Requires restarting eden</string>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -2698,7 +2698,7 @@
<item row="5" column="0"> <item row="5" column="0">
<widget class="QCheckBox" name="enable_joycon_driver"> <widget class="QCheckBox" name="enable_joycon_driver">
<property name="toolTip"> <property name="toolTip">
<string>Requires restarting yuzu</string> <string>Requires restarting eden</string>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -2714,7 +2714,7 @@
<item row="6" column="0"> <item row="6" column="0">
<widget class="QCheckBox" name="enable_procon_driver"> <widget class="QCheckBox" name="enable_procon_driver">
<property name="toolTip"> <property name="toolTip">
<string>Requires restarting yuzu</string> <string>Requires restarting eden</string>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>

View file

@ -3040,8 +3040,8 @@ bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_vi
} }
// Create icon file path // Create icon file path
out_icon_path /= (program_id == 0 ? fmt::format("yuzu-{}.{}", game_file_name, ico_extension) out_icon_path /= (program_id == 0 ? fmt::format("eden-{}.{}", game_file_name, ico_extension)
: fmt::format("yuzu-{:016X}.{}", program_id, ico_extension)); : fmt::format("eden-{:016X}.{}", program_id, ico_extension));
return true; return true;
} }

View file

@ -0,0 +1,123 @@
#include "migration_worker.h"
#include <filesystem>
#include "common/fs/path_util.h"
MigrationWorker::MigrationWorker(const LegacyEmu selected_legacy_emu_,
const bool clear_shader_cache_,
const MigrationStrategy strategy_)
: QObject()
, selected_legacy_emu(selected_legacy_emu_)
, clear_shader_cache(clear_shader_cache_)
, strategy(strategy_)
{}
void MigrationWorker::process()
{
namespace fs = std::filesystem;
const auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive;
std::string legacy_user_dir;
std::string legacy_config_dir;
std::string legacy_cache_dir;
#define LEGACY_EMU(emu) \
case LegacyEmu::emu: \
legacy_user_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##Dir).string(); \
legacy_config_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##ConfigDir) \
.string(); \
legacy_cache_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##CacheDir) \
.string(); \
break;
switch (selected_legacy_emu) {
LEGACY_EMU(Citron)
LEGACY_EMU(Sudachi)
LEGACY_EMU(Yuzu)
LEGACY_EMU(Suyu)
}
#undef LEGACY_EMU
fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir);
fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir);
fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir);
fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
try {
fs::remove_all(eden_dir);
} catch (fs::filesystem_error &_) {
// ignore because linux does stupid crap sometimes.
}
switch (strategy) {
case MigrationStrategy::Link:
// Create symlinks/directory junctions if requested
// Windows 11 has random permission nonsense to deal with.
try {
fs::create_directory_symlink(legacy_user_dir, eden_dir);
} catch (const fs::filesystem_error &e) {
emit error(tr("Linking the old directory failed. You may need to re-run with "
"administrative privileges on Windows.\nOS gave error: %1")
.arg(tr(e.what())));
return;
}
// Windows doesn't need any more links, because cache and config
// are already children of the root directory
#ifndef WIN32
if (fs::is_directory(legacy_config_dir)) {
fs::create_directory_symlink(legacy_config_dir, config_dir);
}
if (fs::is_directory(legacy_cache_dir)) {
fs::create_directory_symlink(legacy_cache_dir, cache_dir);
}
#endif
break;
case MigrationStrategy::Move:
// Rename directories if deletion is requested (achieves the same result)
fs::rename(legacy_user_dir, eden_dir);
// Windows doesn't need any more renames, because cache and config
// are already children of the root directory
#ifndef WIN32
if (fs::is_directory(legacy_config_dir)) {
fs::rename(legacy_config_dir, config_dir);
}
if (fs::is_directory(legacy_cache_dir)) {
fs::rename(legacy_cache_dir, cache_dir);
}
#endif
break;
case MigrationStrategy::Copy:
default:
// Default behavior: copy
fs::copy(legacy_user_dir, eden_dir, copy_options);
if (fs::is_directory(legacy_config_dir)) {
fs::copy(legacy_config_dir, config_dir, copy_options);
}
if (fs::is_directory(legacy_cache_dir)) {
fs::copy(legacy_cache_dir, cache_dir, copy_options);
}
success_text.append(tr("\n\nIf you wish to clean up the files which were left in the old "
"data location, you can do so by deleting the following directory:\n"
"%1")
.arg(QString::fromStdString(legacy_user_dir)));
break;
}
// Delete and re-create shader dir
if (clear_shader_cache) {
fs::remove_all(shader_dir);
fs::create_directory(shader_dir);
}
emit finished(success_text);
}

View file

@ -0,0 +1,41 @@
#ifndef MIGRATION_WORKER_H
#define MIGRATION_WORKER_H
#include <QObject>
class MigrationWorker : public QObject
{
Q_OBJECT
public:
enum class LegacyEmu {
Citron,
Sudachi,
Yuzu,
Suyu,
};
enum class MigrationStrategy {
Copy,
Move,
Link,
};
MigrationWorker(const LegacyEmu selected_legacy_emu,
const bool clear_shader_cache,
const MigrationStrategy strategy);
public slots:
void process();
signals:
void finished(const QString &success_text);
void error(const QString &error_message);
private:
LegacyEmu selected_legacy_emu;
bool clear_shader_cache;
MigrationStrategy strategy;
QString success_text = tr("Data was migrated successfully.");
};
#endif // MIGRATION_WORKER_H

View file

@ -14,9 +14,12 @@
#include "migration_dialog.h" #include "migration_dialog.h"
// Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263 // Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263
#include <QApplication>
#include <QButtonGroup> #include <QButtonGroup>
#include <QCheckBox> #include <QCheckBox>
#include <QProgressDialog>
#include <QRadioButton> #include <QRadioButton>
#include <QThread>
#include <filesystem> #include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -88,13 +91,13 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
// Reflection would make this code 10x better // Reflection would make this code 10x better
// but for now... MACRO MADNESS!!!! // but for now... MACRO MADNESS!!!!
QMap<QString, bool> found; QMap<QString, bool> found;
QMap<QString, LegacyEmu> legacyMap; QMap<QString, MigrationWorker::LegacyEmu> legacyMap;
QMap<QString, QAbstractButton *> buttonMap; QMap<QString, QAbstractButton *> buttonMap;
#define EMU_MAP(name) \ #define EMU_MAP(name) \
const bool name##_found = fs::is_directory( \ const bool name##_found = fs::is_directory( \
Common::FS::GetLegacyPath(Common::FS::LegacyPath::name##Dir)); \ Common::FS::GetLegacyPath(Common::FS::LegacyPath::name##Dir)); \
legacyMap[main_window->tr(#name)] = LegacyEmu::name; \ legacyMap[main_window->tr(#name)] = MigrationWorker::LegacyEmu::name; \
found[main_window->tr(#name)] = name##_found; \ found[main_window->tr(#name)] = name##_found; \
if (name##_found) \ if (name##_found) \
any_found = true; any_found = true;
@ -116,7 +119,15 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
if (!iter.value()) if (!iter.value())
continue; continue;
buttonMap[iter.key()] = migration_prompt.addButton(iter.key()); QAbstractButton *button = migration_prompt.addButton(iter.key());
// TMP: disable citron
if (iter.key() == main_window->tr("Citron")) {
button->setEnabled(false);
button->setToolTip(
main_window->tr("Citron migration is known to cause issues. It's recommended "
"to manually set up your data again."));
}
buttonMap[iter.key()] = button;
promptText.append(main_window->tr("\n- %1").arg(iter.key())); promptText.append(main_window->tr("\n- %1").arg(iter.key()));
} }
@ -127,13 +138,13 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window)
migration_prompt.exec(); migration_prompt.exec();
MigrationStrategy strategy; MigrationWorker::MigrationStrategy strategy;
if (link->isChecked()) { if (link->isChecked()) {
strategy = MigrationStrategy::Link; strategy = MigrationWorker::MigrationStrategy::Link;
} else if (clear_old->isChecked()) { } else if (clear_old->isChecked()) {
strategy = MigrationStrategy::Move; strategy = MigrationWorker::MigrationStrategy::Move;
} else { } else {
strategy = MigrationStrategy::Copy; strategy = MigrationWorker::MigrationStrategy::Copy;
} }
QMapIterator buttonIter(buttonMap); QMapIterator buttonIter(buttonMap);
@ -171,120 +182,37 @@ void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow *main_window)
} }
void UserDataMigrator::MigrateUserData(QMainWindow *main_window, void UserDataMigrator::MigrateUserData(QMainWindow *main_window,
const LegacyEmu selected_legacy_emu, const MigrationWorker::LegacyEmu selected_legacy_emu,
const bool clear_shader_cache, const bool clear_shader_cache,
const MigrationStrategy strategy) const MigrationWorker::MigrationStrategy strategy)
{ {
namespace fs = std::filesystem; // Create a dialog to let the user know it's migrating, some users noted confusion.
const auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive; QProgressDialog *progress = new QProgressDialog(main_window);
progress->setWindowTitle(main_window->tr("Migrating"));
progress->setLabelText(main_window->tr("Migrating, this may take a while..."));
progress->setRange(0, 0);
progress->setCancelButton(nullptr);
progress->setWindowModality(Qt::WindowModality::ApplicationModal);
QString success_text = main_window->tr("Data was migrated successfully."); QThread *thread = new QThread(main_window);
MigrationWorker *worker = new MigrationWorker(selected_legacy_emu, clear_shader_cache, strategy);
worker->moveToThread(thread);
std::string legacy_user_dir; thread->connect(thread, &QThread::started, worker, &MigrationWorker::process);
std::string legacy_config_dir;
std::string legacy_cache_dir;
#define LEGACY_EMU(emu) \ thread->connect(worker, &MigrationWorker::finished, progress, [=](const QString &success_text) {
case LegacyEmu::emu: \ progress->close();
legacy_user_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##Dir).string(); \ QMessageBox::information(main_window,
legacy_config_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##ConfigDir) \ main_window->tr("Migration"),
.string(); \ success_text,
legacy_cache_dir = Common::FS::GetLegacyPath(Common::FS::LegacyPath::emu##CacheDir) \ QMessageBox::Ok);
.string(); \
break;
switch (selected_legacy_emu) { thread->quit();
LEGACY_EMU(Citron) });
LEGACY_EMU(Sudachi)
LEGACY_EMU(Yuzu)
LEGACY_EMU(Suyu)
}
#undef LEGACY_EMU thread->connect(worker, &MigrationWorker::finished, worker, &QObject::deleteLater);
thread->connect(thread, &QThread::finished, thread, &QObject::deleteLater);
fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir); thread->start();
fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir); progress->exec();
fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir);
fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
fs::remove_all(eden_dir);
switch (strategy) {
case MigrationStrategy::Link:
// Create symlinks/directory junctions if requested
// Windows 11 has random permission nonsense to deal with.
try {
fs::create_directory_symlink(legacy_user_dir, eden_dir);
} catch (const fs::filesystem_error &e) {
QMessageBox::critical(
main_window,
main_window->tr("Link Failed"),
main_window
->tr("Linking the old directory failed. You may need to re-run with "
"administrative privileges on Windows.\nOS gave error: %1")
.arg(main_window->tr(e.what())));
std::exit(127);
}
// Windows doesn't need any more links, because cache and config
// are already children of the root directory
#ifndef WIN32
if (fs::is_directory(legacy_config_dir)) {
fs::create_directory_symlink(legacy_config_dir, config_dir);
}
if (fs::is_directory(legacy_cache_dir)) {
fs::create_directory_symlink(legacy_cache_dir, cache_dir);
}
#endif
break;
case MigrationStrategy::Move:
// Rename directories if deletion is requested (achieves the same result)
fs::rename(legacy_user_dir, eden_dir);
// Windows doesn't need any more renames, because cache and config
// are already children of the root directory
#ifndef WIN32
if (fs::is_directory(legacy_config_dir)) {
fs::rename(legacy_config_dir, config_dir);
}
if (fs::is_directory(legacy_cache_dir)) {
fs::rename(legacy_cache_dir, cache_dir);
}
#endif
break;
case MigrationStrategy::Copy:
default:
// Default behavior: copy
fs::copy(legacy_user_dir, eden_dir, copy_options);
if (fs::is_directory(legacy_config_dir)) {
fs::copy(legacy_config_dir, config_dir, copy_options);
}
if (fs::is_directory(legacy_cache_dir)) {
fs::copy(legacy_cache_dir, cache_dir, copy_options);
}
success_text.append(
main_window
->tr("\n\nIf you wish to clean up the files which were left in the old "
"data location, you can do so by deleting the following directory:\n"
"%1")
.arg(QString::fromStdString(legacy_user_dir)));
break;
}
// Delete and re-create shader dir
if (clear_shader_cache) {
fs::remove_all(shader_dir);
fs::create_directory(shader_dir);
}
QMessageBox::information(main_window,
main_window->tr("Migration"),
success_text,
QMessageBox::Ok);
} }

View file

@ -8,27 +8,17 @@
#pragma once #pragma once
#include <QMainWindow> #include <QMainWindow>
#include "migration_worker.h"
class UserDataMigrator { class UserDataMigrator {
public: public:
UserDataMigrator(QMainWindow* main_window); UserDataMigrator(QMainWindow* main_window);
private: private:
enum class LegacyEmu {
Citron,
Sudachi,
Yuzu,
Suyu,
};
enum class MigrationStrategy {
Copy,
Move,
Link,
};
void ShowMigrationPrompt(QMainWindow* main_window); void ShowMigrationPrompt(QMainWindow* main_window);
void ShowMigrationCancelledMessage(QMainWindow* main_window); void ShowMigrationCancelledMessage(QMainWindow* main_window);
void MigrateUserData(QMainWindow* main_window, const LegacyEmu selected_legacy_emu, void MigrateUserData(QMainWindow* main_window,
const bool clear_shader_cache, const MigrationStrategy strategy); const MigrationWorker::LegacyEmu selected_legacy_emu,
const bool clear_shader_cache,
const MigrationWorker::MigrationStrategy strategy);
}; };

View file

@ -223,10 +223,12 @@ void EmuWindow_SDL2::WaitEvent() {
const u32 current_time = SDL_GetTicks(); const u32 current_time = SDL_GetTicks();
if (current_time > last_time + 2000) { if (current_time > last_time + 2000) {
const auto results = system.GetAndResetPerfStats(); const auto results = system.GetAndResetPerfStats();
const auto title = const auto title = fmt::format("eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)",
fmt::format("yuzu {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, Common::g_build_fullname,
Common::g_scm_branch, Common::g_scm_desc, results.average_game_fps, Common::g_scm_branch,
results.emulation_speed * 100.0); Common::g_scm_desc,
results.average_game_fps,
results.emulation_speed * 100.0);
SDL_SetWindowTitle(render_window, title.c_str()); SDL_SetWindowTitle(render_window, title.c_str());
last_time = current_time; last_time = current_time;
} }
@ -236,7 +238,7 @@ void EmuWindow_SDL2::WaitEvent() {
void EmuWindow_SDL2::SetWindowIcon() { void EmuWindow_SDL2::SetWindowIcon() {
SDL_RWops* const yuzu_icon_stream = SDL_RWFromConstMem((void*)yuzu_icon, yuzu_icon_size); SDL_RWops* const yuzu_icon_stream = SDL_RWFromConstMem((void*)yuzu_icon, yuzu_icon_size);
if (yuzu_icon_stream == nullptr) { if (yuzu_icon_stream == nullptr) {
LOG_WARNING(Frontend, "Failed to create yuzu icon stream."); LOG_WARNING(Frontend, "Failed to create eden icon stream.");
return; return;
} }
SDL_Surface* const window_icon = SDL_LoadBMP_RW(yuzu_icon_stream, 1); SDL_Surface* const window_icon = SDL_LoadBMP_RW(yuzu_icon_stream, 1);

View file

@ -90,7 +90,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste
} }
SDL_GL_SetSwapInterval(0); SDL_GL_SetSwapInterval(0);
std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_fullname, std::string window_title = fmt::format("eden {} | {}-{}", Common::g_build_fullname,
Common::g_scm_branch, Common::g_scm_desc); Common::g_scm_branch, Common::g_scm_desc);
render_window = render_window =
SDL_CreateWindow(window_title.c_str(), SDL_CreateWindow(window_title.c_str(),

View file

@ -23,7 +23,7 @@
EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_,
Core::System& system_, bool fullscreen) Core::System& system_, bool fullscreen)
: EmuWindow_SDL2{input_subsystem_, system_} { : EmuWindow_SDL2{input_subsystem_, system_} {
const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)", Common::g_build_name,
Common::g_scm_branch, Common::g_scm_desc); Common::g_scm_branch, Common::g_scm_desc);
render_window = render_window =
SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,

View file

@ -18,8 +18,10 @@
EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_,
Core::System& system_, bool fullscreen) Core::System& system_, bool fullscreen)
: EmuWindow_SDL2{input_subsystem_, system_} { : EmuWindow_SDL2{input_subsystem_, system_} {
const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)",
Common::g_scm_branch, Common::g_scm_desc); Common::g_build_name,
Common::g_scm_branch,
Common::g_scm_desc);
render_window = render_window =
SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height,

View file

@ -81,7 +81,7 @@ static void PrintHelp(const char* argv0) {
} }
static void PrintVersion() { static void PrintVersion() {
std::cout << "yuzu " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; std::cout << "eden " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl;
} }
static void OnStateChanged(const Network::RoomMember::State& state) { static void OnStateChanged(const Network::RoomMember::State& state) {