summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/applets/profile_select.cpp10
-rw-r--r--src/yuzu/applets/profile_select.h8
-rw-r--r--src/yuzu/bootmanager.cpp59
-rw-r--r--src/yuzu/bootmanager.h14
-rw-r--r--src/yuzu/configuration/config.cpp3
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp11
-rw-r--r--src/yuzu/configuration/configure_per_general.cpp10
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp11
-rw-r--r--src/yuzu/configuration/configure_system.cpp45
-rw-r--r--src/yuzu/configuration/configure_system.h3
-rw-r--r--src/yuzu/configuration/configure_system.ui166
-rw-r--r--src/yuzu/game_list_worker.cpp114
-rw-r--r--src/yuzu/main.cpp2
-rw-r--r--src/yuzu/main.h2
-rw-r--r--src/yuzu/ui_settings.h1
15 files changed, 227 insertions, 232 deletions
diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/profile_select.cpp
index 7fbc9deeb..42e26b978 100644
--- a/src/yuzu/applets/profile_select.cpp
+++ b/src/yuzu/applets/profile_select.cpp
@@ -27,20 +27,20 @@ constexpr std::array<u8, 107> backup_jpeg{
0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9,
};
-QString FormatUserEntryText(const QString& username, Service::Account::UUID uuid) {
+QString FormatUserEntryText(const QString& username, Common::UUID uuid) {
return QtProfileSelectionDialog::tr(
"%1\n%2", "%1 is the profile username, %2 is the formatted UUID (e.g. "
"00112233-4455-6677-8899-AABBCCDDEEFF))")
.arg(username, QString::fromStdString(uuid.FormatSwitch()));
}
-QString GetImagePath(Service::Account::UUID uuid) {
+QString GetImagePath(Common::UUID uuid) {
const auto path = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
"/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg";
return QString::fromStdString(path);
}
-QPixmap GetIcon(Service::Account::UUID uuid) {
+QPixmap GetIcon(Common::UUID uuid) {
QPixmap icon{GetImagePath(uuid)};
if (!icon) {
@@ -154,12 +154,12 @@ QtProfileSelector::QtProfileSelector(GMainWindow& parent) {
QtProfileSelector::~QtProfileSelector() = default;
void QtProfileSelector::SelectProfile(
- std::function<void(std::optional<Service::Account::UUID>)> callback) const {
+ std::function<void(std::optional<Common::UUID>)> callback) const {
this->callback = std::move(callback);
emit MainWindowSelectProfile();
}
-void QtProfileSelector::MainWindowFinishedSelection(std::optional<Service::Account::UUID> uuid) {
+void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) {
// Acquire the HLE mutex
std::lock_guard lock{HLE::g_hle_lock};
callback(uuid);
diff --git a/src/yuzu/applets/profile_select.h b/src/yuzu/applets/profile_select.h
index 1c2922e54..c5b90a78e 100644
--- a/src/yuzu/applets/profile_select.h
+++ b/src/yuzu/applets/profile_select.h
@@ -9,6 +9,7 @@
#include <QList>
#include <QTreeView>
#include "core/frontend/applets/profile_select.h"
+#include "core/hle/service/acc/profile_manager.h"
class GMainWindow;
class QDialogButtonBox;
@@ -60,14 +61,13 @@ public:
explicit QtProfileSelector(GMainWindow& parent);
~QtProfileSelector() override;
- void SelectProfile(
- std::function<void(std::optional<Service::Account::UUID>)> callback) const override;
+ void SelectProfile(std::function<void(std::optional<Common::UUID>)> callback) const override;
signals:
void MainWindowSelectProfile() const;
private:
- void MainWindowFinishedSelection(std::optional<Service::Account::UUID> uuid);
+ void MainWindowFinishedSelection(std::optional<Common::UUID> uuid);
- mutable std::function<void(std::optional<Service::Account::UUID>)> callback;
+ mutable std::function<void(std::optional<Common::UUID>)> callback;
};
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index eeee603d1..afec33b61 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -26,6 +26,8 @@
EmuThread::EmuThread(GRenderWindow* render_window) : render_window(render_window) {}
+EmuThread::~EmuThread() = default;
+
void EmuThread::run() {
render_window->MakeCurrent();
@@ -185,7 +187,7 @@ private:
bool do_painting;
};
-GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
+GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread)
: QWidget(parent), emu_thread(emu_thread) {
setWindowTitle(QStringLiteral("yuzu %1 | %2-%3")
.arg(QString::fromUtf8(Common::g_build_name),
@@ -194,8 +196,7 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
setAttribute(Qt::WA_AcceptTouchEvents);
InputCommon::Init();
- connect(this, &GRenderWindow::FirstFrameDisplayed, static_cast<GMainWindow*>(parent),
- &GMainWindow::OnLoadComplete);
+ connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
}
GRenderWindow::~GRenderWindow() {
@@ -247,9 +248,9 @@ void GRenderWindow::PollEvents() {}
void GRenderWindow::OnFramebufferSizeChanged() {
// Screen changes potentially incur a change in screen DPI, hence we should update the
// framebuffer size
- qreal pixelRatio = GetWindowPixelRatio();
- unsigned width = child->QPaintDevice::width() * pixelRatio;
- unsigned height = child->QPaintDevice::height() * pixelRatio;
+ const qreal pixel_ratio = GetWindowPixelRatio();
+ const u32 width = child->QPaintDevice::width() * pixel_ratio;
+ const u32 height = child->QPaintDevice::height() * pixel_ratio;
UpdateCurrentFramebufferLayout(width, height);
}
@@ -266,7 +267,7 @@ void GRenderWindow::ForwardKeyReleaseEvent(QKeyEvent* event) {
}
void GRenderWindow::BackupGeometry() {
- geometry = ((QWidget*)this)->saveGeometry();
+ geometry = QWidget::saveGeometry();
}
void GRenderWindow::RestoreGeometry() {
@@ -283,10 +284,11 @@ void GRenderWindow::restoreGeometry(const QByteArray& geometry) {
QByteArray GRenderWindow::saveGeometry() {
// If we are a top-level widget, store the current geometry
// otherwise, store the last backup
- if (parent() == nullptr)
- return ((QWidget*)this)->saveGeometry();
- else
- return geometry;
+ if (parent() == nullptr) {
+ return QWidget::saveGeometry();
+ }
+
+ return geometry;
}
qreal GRenderWindow::GetWindowPixelRatio() const {
@@ -294,10 +296,10 @@ qreal GRenderWindow::GetWindowPixelRatio() const {
return windowHandle() ? windowHandle()->screen()->devicePixelRatio() : 1.0f;
}
-std::pair<unsigned, unsigned> GRenderWindow::ScaleTouch(const QPointF pos) const {
+std::pair<u32, u32> GRenderWindow::ScaleTouch(const QPointF pos) const {
const qreal pixel_ratio = GetWindowPixelRatio();
- return {static_cast<unsigned>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})),
- static_cast<unsigned>(std::max(std::round(pos.y() * pixel_ratio), qreal{0.0}))};
+ return {static_cast<u32>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})),
+ static_cast<u32>(std::max(std::round(pos.y() * pixel_ratio), qreal{0.0}))};
}
void GRenderWindow::closeEvent(QCloseEvent* event) {
@@ -353,7 +355,7 @@ void GRenderWindow::focusOutEvent(QFocusEvent* event) {
InputCommon::GetKeyboard()->ReleaseAllKeys();
}
-void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) {
+void GRenderWindow::OnClientAreaResized(u32 width, u32 height) {
NotifyClientAreaSizeChanged(std::make_pair(width, height));
}
@@ -394,7 +396,7 @@ void GRenderWindow::InitRenderTarget() {
context->setShareContext(shared_context.get());
context->setFormat(fmt);
context->create();
- fmt.setSwapInterval(false);
+ fmt.setSwapInterval(0);
child = new GGLWidgetInternal(this, shared_context.get());
container = QWidget::createWindowContainer(child, this);
@@ -424,24 +426,29 @@ void GRenderWindow::InitRenderTarget() {
BackupGeometry();
}
-void GRenderWindow::CaptureScreenshot(u16 res_scale, const QString& screenshot_path) {
+void GRenderWindow::CaptureScreenshot(u32 res_scale, const QString& screenshot_path) {
auto& renderer = Core::System::GetInstance().Renderer();
- if (!res_scale)
+ if (res_scale == 0) {
res_scale = VideoCore::GetResolutionScaleFactor(renderer);
+ }
const Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale(res_scale)};
screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32);
- renderer.RequestScreenshot(screenshot_image.bits(),
- [=] {
- screenshot_image.mirrored(false, true).save(screenshot_path);
- LOG_INFO(Frontend, "The screenshot is saved.");
- },
- layout);
+ renderer.RequestScreenshot(
+ screenshot_image.bits(),
+ [=] {
+ const std::string std_screenshot_path = screenshot_path.toStdString();
+ if (screenshot_image.mirrored(false, true).save(screenshot_path)) {
+ LOG_INFO(Frontend, "Screenshot saved to \"{}\"", std_screenshot_path);
+ } else {
+ LOG_ERROR(Frontend, "Failed to save screenshot to \"{}\"", std_screenshot_path);
+ }
+ },
+ layout);
}
-void GRenderWindow::OnMinimalClientAreaChangeRequest(
- const std::pair<unsigned, unsigned>& minimal_size) {
+void GRenderWindow::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
setMinimumSize(minimal_size.first, minimal_size.second);
}
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 3df33aca1..2fc64895f 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -27,11 +27,12 @@ namespace VideoCore {
enum class LoadCallbackStage;
}
-class EmuThread : public QThread {
+class EmuThread final : public QThread {
Q_OBJECT
public:
explicit EmuThread(GRenderWindow* render_window);
+ ~EmuThread() override;
/**
* Start emulation (on new thread)
@@ -114,7 +115,7 @@ class GRenderWindow : public QWidget, public Core::Frontend::EmuWindow {
Q_OBJECT
public:
- GRenderWindow(QWidget* parent, EmuThread* emu_thread);
+ GRenderWindow(GMainWindow* parent, EmuThread* emu_thread);
~GRenderWindow() override;
// EmuWindow implementation
@@ -133,17 +134,17 @@ public:
QByteArray saveGeometry(); // overridden
qreal GetWindowPixelRatio() const;
- std::pair<unsigned, unsigned> ScaleTouch(const QPointF pos) const;
+ std::pair<u32, u32> ScaleTouch(QPointF pos) const;
void closeEvent(QCloseEvent* event) override;
bool event(QEvent* event) override;
void focusOutEvent(QFocusEvent* event) override;
- void OnClientAreaResized(unsigned width, unsigned height);
+ void OnClientAreaResized(u32 width, u32 height);
void InitRenderTarget();
- void CaptureScreenshot(u16 res_scale, const QString& screenshot_path);
+ void CaptureScreenshot(u32 res_scale, const QString& screenshot_path);
public slots:
void moveContext(); // overridden
@@ -162,8 +163,7 @@ private:
void TouchUpdateEvent(const QTouchEvent* event);
void TouchEndEvent();
- void OnMinimalClientAreaChangeRequest(
- const std::pair<unsigned, unsigned>& minimal_size) override;
+ void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
QWidget* container = nullptr;
GGLWidgetInternal* child = nullptr;
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index db27da23e..b1942bedc 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -645,6 +645,8 @@ void Config::ReadUIGamelistValues() {
UISettings::values.icon_size = ReadSetting(QStringLiteral("icon_size"), 64).toUInt();
UISettings::values.row_1_text_id = ReadSetting(QStringLiteral("row_1_text_id"), 3).toUInt();
UISettings::values.row_2_text_id = ReadSetting(QStringLiteral("row_2_text_id"), 2).toUInt();
+ UISettings::values.cache_game_list =
+ ReadSetting(QStringLiteral("cache_game_list"), true).toBool();
qt_config->endGroup();
}
@@ -1009,6 +1011,7 @@ void Config::SaveUIGamelistValues() {
WriteSetting(QStringLiteral("icon_size"), UISettings::values.icon_size, 64);
WriteSetting(QStringLiteral("row_1_text_id"), UISettings::values.row_1_text_id, 3);
WriteSetting(QStringLiteral("row_2_text_id"), UISettings::values.row_2_text_id, 2);
+ WriteSetting(QStringLiteral("cache_game_list"), UISettings::values.cache_game_list, true);
qt_config->endGroup();
}
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 08ea41b0f..6daf82ab1 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -51,17 +51,15 @@ Resolution FromResolutionFactor(float factor) {
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
: QWidget(parent), ui(new Ui::ConfigureGraphics) {
-
ui->setupUi(this);
- this->setConfiguration();
+ setConfiguration();
- ui->frame_limit->setEnabled(Settings::values.use_frame_limit);
- connect(ui->toggle_frame_limit, &QCheckBox::stateChanged, ui->frame_limit,
- &QSpinBox::setEnabled);
+ connect(ui->toggle_frame_limit, &QCheckBox::toggled, ui->frame_limit, &QSpinBox::setEnabled);
connect(ui->bg_button, &QPushButton::clicked, this, [this] {
const QColor new_bg_color = QColorDialog::getColor(bg_color);
- if (!new_bg_color.isValid())
+ if (!new_bg_color.isValid()) {
return;
+ }
UpdateBackgroundColorButton(new_bg_color);
});
}
@@ -74,6 +72,7 @@ void ConfigureGraphics::setConfiguration() {
ui->resolution_factor_combobox->setCurrentIndex(
static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor)));
ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
+ ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked());
ui->frame_limit->setValue(Settings::values.frame_limit);
ui->use_compatibility_profile->setEnabled(runtime_lock);
ui->use_compatibility_profile->setChecked(Settings::values.use_compatibility_profile);
diff --git a/src/yuzu/configuration/configure_per_general.cpp b/src/yuzu/configuration/configure_per_general.cpp
index 2bdfc8e5a..c3e68fdf5 100644
--- a/src/yuzu/configuration/configure_per_general.cpp
+++ b/src/yuzu/configuration/configure_per_general.cpp
@@ -13,6 +13,8 @@
#include <QTimer>
#include <QTreeView>
+#include "common/common_paths.h"
+#include "common/file_util.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/xts_archive.h"
@@ -79,6 +81,14 @@ void ConfigurePerGameGeneral::applyConfiguration() {
disabled_addons.push_back(item.front()->text().toStdString());
}
+ auto current = Settings::values.disabled_addons[title_id];
+ std::sort(disabled_addons.begin(), disabled_addons.end());
+ std::sort(current.begin(), current.end());
+ if (disabled_addons != current) {
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP +
+ "game_list" + DIR_SEP + fmt::format("{:016X}.pv.txt", title_id));
+ }
+
Settings::values.disabled_addons[title_id] = disabled_addons;
}
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 002a51780..6d7d04c98 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -33,14 +33,13 @@ constexpr std::array<u8, 107> backup_jpeg{
0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9,
};
-QString GetImagePath(Service::Account::UUID uuid) {
+QString GetImagePath(Common::UUID uuid) {
const auto path = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
"/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg";
return QString::fromStdString(path);
}
-QString GetAccountUsername(const Service::Account::ProfileManager& manager,
- Service::Account::UUID uuid) {
+QString GetAccountUsername(const Service::Account::ProfileManager& manager, Common::UUID uuid) {
Service::Account::ProfileBase profile;
if (!manager.GetProfileBase(uuid, profile)) {
return {};
@@ -51,14 +50,14 @@ QString GetAccountUsername(const Service::Account::ProfileManager& manager,
return QString::fromStdString(text);
}
-QString FormatUserEntryText(const QString& username, Service::Account::UUID uuid) {
+QString FormatUserEntryText(const QString& username, Common::UUID uuid) {
return ConfigureProfileManager::tr("%1\n%2",
"%1 is the profile username, %2 is the formatted UUID (e.g. "
"00112233-4455-6677-8899-AABBCCDDEEFF))")
.arg(username, QString::fromStdString(uuid.FormatSwitch()));
}
-QPixmap GetIcon(Service::Account::UUID uuid) {
+QPixmap GetIcon(Common::UUID uuid) {
QPixmap icon{GetImagePath(uuid)};
if (!icon) {
@@ -190,7 +189,7 @@ void ConfigureProfileManager::AddUser() {
return;
}
- const auto uuid = Service::Account::UUID::Generate();
+ const auto uuid = Common::UUID::Generate();
profile_manager->CreateNewUser(uuid, username.toStdString());
item_model->appendRow(new QStandardItem{GetIcon(uuid), FormatUserEntryText(username, uuid)});
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index ff18ace40..e588b21f2 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -16,28 +16,8 @@
#include "ui_configure_system.h"
#include "yuzu/configuration/configure_system.h"
-namespace {
-constexpr std::array<int, 12> days_in_month = {{
- 31,
- 29,
- 31,
- 30,
- 31,
- 30,
- 31,
- 31,
- 30,
- 31,
- 30,
- 31,
-}};
-} // Anonymous namespace
-
ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureSystem) {
ui->setupUi(this);
- connect(ui->combo_birthmonth,
- static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
- &ConfigureSystem::UpdateBirthdayComboBox);
connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
&ConfigureSystem::RefreshConsoleID);
@@ -101,31 +81,6 @@ void ConfigureSystem::applyConfiguration() {
Settings::Apply();
}
-void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
- if (birthmonth_index < 0 || birthmonth_index >= 12)
- return;
-
- // store current day selection
- int birthday_index = ui->combo_birthday->currentIndex();
-
- // get number of days in the new selected month
- int days = days_in_month[birthmonth_index];
-
- // if the selected day is out of range,
- // reset it to 1st
- if (birthday_index < 0 || birthday_index >= days)
- birthday_index = 0;
-
- // update the day combo box
- ui->combo_birthday->clear();
- for (int i = 1; i <= days; ++i) {
- ui->combo_birthday->addItem(QString::number(i));
- }
-
- // restore the day selection
- ui->combo_birthday->setCurrentIndex(birthday_index);
-}
-
void ConfigureSystem::RefreshConsoleID() {
QMessageBox::StandardButton reply;
QString warning_text = tr("This will replace your current virtual Switch with a new one. "
diff --git a/src/yuzu/configuration/configure_system.h b/src/yuzu/configuration/configure_system.h
index cf1e54de5..41d03c56f 100644
--- a/src/yuzu/configuration/configure_system.h
+++ b/src/yuzu/configuration/configure_system.h
@@ -26,14 +26,11 @@ public:
private:
void ReadSystemSettings();
- void UpdateBirthdayComboBox(int birthmonth_index);
void RefreshConsoleID();
std::unique_ptr<Ui::ConfigureSystem> ui;
bool enabled = false;
- int birthmonth = 0;
- int birthday = 0;
int language_index = 0;
int sound_index = 0;
};
diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui
index 073327298..65745a2f8 100644
--- a/src/yuzu/configuration/configure_system.ui
+++ b/src/yuzu/configuration/configure_system.ui
@@ -22,14 +22,21 @@
<string>System Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="2" column="0">
+ <item row="1" column="0">
<widget class="QLabel" name="label_sound">
<property name="text">
<string>Sound output mode</string>
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_console_id">
+ <property name="text">
+ <string>Console ID:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
<widget class="QComboBox" name="combo_language">
<property name="toolTip">
<string>Note: this can be overridden when region setting is auto-select</string>
@@ -121,108 +128,14 @@
</item>
</widget>
</item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_birthday2">
- <item>
- <widget class="QComboBox" name="combo_birthmonth">
- <item>
- <property name="text">
- <string>January</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>February</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>March</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>April</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>May</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>June</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>July</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>August</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>September</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>October</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>November</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>December</string>
- </property>
- </item>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="combo_birthday"/>
- </item>
- </layout>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_console_id">
- <property name="text">
- <string>Console ID:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_birthday">
- <property name="text">
- <string>Birthday</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QPushButton" name="button_regenerate_console_id">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
+ <item row="4" column="0">
+ <widget class="QCheckBox" name="rng_seed_checkbox">
<property name="text">
- <string>Regenerate</string>
+ <string>RNG Seed</string>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="1" column="1">
<widget class="QComboBox" name="combo_sound">
<item>
<property name="text">
@@ -241,49 +154,37 @@
</item>
</widget>
</item>
- <item row="5" column="0">
- <widget class="QCheckBox" name="rng_seed_checkbox">
- <property name="text">
- <string>RNG Seed</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
+ <item row="0" column="0">
<widget class="QLabel" name="label_language">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
- <item row="5" column="1">
- <widget class="QLineEdit" name="rng_seed_edit">
+ <item row="2" column="1">
+ <widget class="QPushButton" name="button_regenerate_console_id">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="font">
- <font>
- <family>Lucida Console</family>
- </font>
- </property>
- <property name="inputMask">
- <string notr="true">HHHHHHHH</string>
+ <property name="layoutDirection">
+ <enum>Qt::RightToLeft</enum>
</property>
- <property name="maxLength">
- <number>8</number>
+ <property name="text">
+ <string>Regenerate</string>
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="3" column="0">
<widget class="QCheckBox" name="custom_rtc_checkbox">
<property name="text">
<string>Custom RTC</string>
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="3" column="1">
<widget class="QDateTimeEdit" name="custom_rtc_edit">
<property name="minimumDate">
<date>
@@ -297,6 +198,27 @@
</property>
</widget>
</item>
+ <item row="4" column="1">
+ <widget class="QLineEdit" name="rng_seed_edit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <family>Lucida Console</family>
+ </font>
+ </property>
+ <property name="inputMask">
+ <string notr="true">HHHHHHHH</string>
+ </property>
+ <property name="maxLength">
+ <number>8</number>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index 82d2826ba..4f30e9147 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -8,7 +8,9 @@
#include <vector>
#include <QDir>
+#include <QFile>
#include <QFileInfo>
+#include <QSettings>
#include "common/common_paths.h"
#include "common/file_util.h"
@@ -30,13 +32,108 @@
#include "yuzu/ui_settings.h"
namespace {
+
+QString GetGameListCachedObject(const std::string& filename, const std::string& ext,
+ const std::function<QString()>& generator) {
+ if (!UISettings::values.cache_game_list || filename == "0000000000000000") {
+ return generator();
+ }
+
+ const auto path = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + "game_list" +
+ DIR_SEP + filename + '.' + ext;
+
+ FileUtil::CreateFullPath(path);
+
+ if (!FileUtil::Exists(path)) {
+ const auto str = generator();
+
+ QFile file{QString::fromStdString(path)};
+ if (file.open(QFile::WriteOnly)) {
+ file.write(str.toUtf8());
+ }
+
+ return str;
+ }
+
+ QFile file{QString::fromStdString(path)};
+ if (file.open(QFile::ReadOnly)) {
+ return QString::fromUtf8(file.readAll());
+ }
+
+ return generator();
+}
+
+std::pair<std::vector<u8>, std::string> GetGameListCachedObject(
+ const std::string& filename, const std::string& ext,
+ const std::function<std::pair<std::vector<u8>, std::string>()>& generator) {
+ if (!UISettings::values.cache_game_list || filename == "0000000000000000") {
+ return generator();
+ }
+
+ const auto path1 = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + "game_list" +
+ DIR_SEP + filename + ".jpeg";
+ const auto path2 = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + "game_list" +
+ DIR_SEP + filename + ".appname.txt";
+
+ FileUtil::CreateFullPath(path1);
+
+ if (!FileUtil::Exists(path1) || !FileUtil::Exists(path2)) {
+ const auto [icon, nacp] = generator();
+
+ QFile file1{QString::fromStdString(path1)};
+ if (!file1.open(QFile::WriteOnly)) {
+ LOG_ERROR(Frontend, "Failed to open cache file.");
+ return generator();
+ }
+
+ if (!file1.resize(icon.size())) {
+ LOG_ERROR(Frontend, "Failed to resize cache file to necessary size.");
+ return generator();
+ }
+
+ if (file1.write(reinterpret_cast<const char*>(icon.data()), icon.size()) != icon.size()) {
+ LOG_ERROR(Frontend, "Failed to write data to cache file.");
+ return generator();
+ }
+
+ QFile file2{QString::fromStdString(path2)};
+ if (file2.open(QFile::WriteOnly)) {
+ file2.write(nacp.data(), nacp.size());
+ }
+
+ return std::make_pair(icon, nacp);
+ }
+
+ QFile file1(QString::fromStdString(path1));
+ QFile file2(QString::fromStdString(path2));
+
+ if (!file1.open(QFile::ReadOnly)) {
+ LOG_ERROR(Frontend, "Failed to open cache file for reading.");
+ return generator();
+ }
+
+ if (!file2.open(QFile::ReadOnly)) {
+ LOG_ERROR(Frontend, "Failed to open cache file for reading.");
+ return generator();
+ }
+
+ std::vector<u8> vec(file1.size());
+ if (file1.read(reinterpret_cast<char*>(vec.data()), vec.size()) !=
+ static_cast<s64>(vec.size())) {
+ return generator();
+ }
+
+ const auto data = file2.readAll();
+ return std::make_pair(vec, data.toStdString());
+}
+
void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, const FileSys::NCA& nca,
std::vector<u8>& icon, std::string& name) {
- auto [nacp, icon_file] = patch_manager.ParseControlNCA(nca);
- if (icon_file != nullptr)
- icon = icon_file->ReadAllBytes();
- if (nacp != nullptr)
- name = nacp->GetApplicationName();
+ std::tie(icon, name) = GetGameListCachedObject(
+ fmt::format("{:016X}", patch_manager.GetTitleID()), {}, [&patch_manager, &nca] {
+ const auto [nacp, icon_f] = patch_manager.ParseControlNCA(nca);
+ return std::make_pair(icon_f->ReadAllBytes(), nacp->GetApplicationName());
+ });
}
bool HasSupportedFileExtension(const std::string& file_name) {
@@ -114,8 +211,11 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
};
if (UISettings::values.show_add_ons) {
- list.insert(
- 2, new GameListItem(FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable())));
+ const auto 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));
}
return list;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index cef2cc1ae..f8a0daebd 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1396,6 +1396,8 @@ void GMainWindow::OnMenuInstallToNAND() {
tr("The file was successfully installed."));
game_list->PopulateAsync(UISettings::values.game_directory_path,
UISettings::values.game_directory_deepscan);
+ FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) +
+ DIR_SEP + "game_list");
};
const auto failed = [this]() {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 7bf82e665..1137bbc7a 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -104,7 +104,7 @@ signals:
void ErrorDisplayFinished();
- void ProfileSelectorFinishedSelection(std::optional<Service::Account::UUID> uuid);
+ void ProfileSelectorFinishedSelection(std::optional<Common::UUID> uuid);
void SoftwareKeyboardFinishedText(std::optional<std::u16string> text);
void SoftwareKeyboardFinishedCheckDialog();
diff --git a/src/yuzu/ui_settings.h b/src/yuzu/ui_settings.h
index dbd318e20..a62cd6911 100644
--- a/src/yuzu/ui_settings.h
+++ b/src/yuzu/ui_settings.h
@@ -79,6 +79,7 @@ struct Values {
uint8_t row_1_text_id;
uint8_t row_2_text_id;
std::atomic_bool is_game_list_reload_pending{false};
+ bool cache_game_list;
};
extern Values values;