& mask,
const UniformBufferSizes* sizes) {
- const bool mask_changed = channel_state->enabled_uniform_buffer_masks != mask;
- if (mask_changed) {
- channel_state->fast_bound_uniform_buffers.fill(0);
- if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
+ if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
+ if (channel_state->enabled_uniform_buffer_masks != mask) {
+ if constexpr (IS_OPENGL) {
+ channel_state->fast_bound_uniform_buffers.fill(0);
+ }
channel_state->dirty_uniform_buffers.fill(~u32{0});
channel_state->uniform_buffer_binding_sizes.fill({});
}
@@ -805,7 +806,7 @@ void BufferCache::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size;
if (should_fast_bind) {
// We only have to bind when the currently bound buffer is not the fast version
- channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index;
+ channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index;
channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
runtime.BindFastUniformBuffer(stage, binding_index, size);
}
@@ -814,22 +815,13 @@ void BufferCache
::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
return;
}
}
- channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index;
- channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
+ if constexpr (IS_OPENGL) {
+ channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index;
+ channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
+ }
// Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan
const std::span span = runtime.BindMappedUniformBuffer(stage, binding_index, size);
-#ifdef YUZU_DEBUG
- ASSERT(binding_index < NUM_GRAPHICS_UNIFORM_BUFFERS);
- ASSERT(span.size() >= size && "UBO stream span too small");
- if (!device_memory.ReadBlockFastChecked(device_addr, span.data(), size)) {
- LOG_CRITICAL(Render, "DeviceMemory OOB/unmapped: addr=0x{:x} size={}", device_addr, size);
- channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index);
- ASSERT(false);
- return;
- }
-#else
device_memory.ReadBlockUnsafe(device_addr, span.data(), size);
-#endif
return;
}
// Classic cached path
@@ -838,8 +830,7 @@ void BufferCache::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
}
// Skip binding if it's not needed and if the bound buffer is not the fast version
// This exists to avoid instances where the fast buffer is bound and a GPU write happens
- const bool was_fast_bound = HasFastUniformBufferBound(stage, binding_index);
- needs_bind |= was_fast_bound;
+ needs_bind |= HasFastUniformBufferBound(stage, binding_index);
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
needs_bind |= channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size;
}
@@ -848,6 +839,9 @@ void BufferCache
::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
}
const u32 offset = buffer.Offset(device_addr);
if constexpr (IS_OPENGL) {
+ // Fast buffer will be unbound
+ channel_state->fast_bound_uniform_buffers[stage] &= ~(1U << binding_index);
+
// Mark the index as dirty if offset doesn't match
const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset();
channel_state->dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index;
@@ -861,7 +855,6 @@ void BufferCache
::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
} else {
runtime.BindUniformBuffer(buffer, offset, size);
}
- channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index);
}
template
@@ -1796,7 +1789,12 @@ std::span BufferCache::ImmediateBuffer(size_t wanted_capacity) {
template
bool BufferCache::HasFastUniformBufferBound(size_t stage, u32 binding_index) const noexcept {
- return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1u) != 0;
+ if constexpr (IS_OPENGL) {
+ return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1) != 0;
+ } else {
+ // Only OpenGL has fast uniform buffers
+ return false;
+ }
}
template
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h
index 09631ffd83..486d19fb79 100644
--- a/src/video_core/buffer_cache/buffer_cache_base.h
+++ b/src/video_core/buffer_cache/buffer_cache_base.h
@@ -53,7 +53,6 @@ constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8;
constexpr u32 NUM_STORAGE_BUFFERS = 16;
constexpr u32 NUM_TEXTURE_BUFFERS = 32;
constexpr u32 NUM_STAGES = 5;
-static_assert(NUM_GRAPHICS_UNIFORM_BUFFERS <= 32, "fast bitmask must fit u32");
using UniformBufferSizes = std::array, NUM_STAGES>;
using ComputeUniformBufferSizes = std::array;
@@ -138,8 +137,8 @@ public:
u32 written_compute_texture_buffers = 0;
u32 image_compute_texture_buffers = 0;
- std::array uniform_cache_hits{};
- std::array uniform_cache_shots{};
+ std::array uniform_cache_hits{};
+ std::array uniform_cache_shots{};
u32 uniform_buffer_skip_cache_size = DEFAULT_SKIP_CACHE_SIZE;
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
index 0fbe707b04..ecc4f77dc7 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
@@ -25,12 +25,12 @@ namespace {
using namespace Common::Literals;
-// Minimum alignment we want to enforce for the streaming ring
-constexpr VkDeviceSize MIN_STREAM_ALIGNMENT = 256;
+// Maximum potential alignment of a Vulkan buffer
+constexpr VkDeviceSize MAX_ALIGNMENT = 256;
// Stream buffer size in bytes
constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB;
-size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) {
+size_t GetStreamBufferSize(const Device& device) {
VkDeviceSize size{0};
if (device.HasDebuggingToolAttached()) {
bool found_heap = false;
@@ -53,9 +53,8 @@ size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) {
// Clamp to the configured maximum, align up for safety, and ensure a sane minimum so
// region_size (stream_buffer_size / NUM_SYNCS) never becomes zero.
- const VkDeviceSize aligned =
- (std::min)(Common::AlignUp(size, alignment), MAX_STREAM_BUFFER_SIZE);
- const VkDeviceSize min_size = alignment * StagingBufferPool::NUM_SYNCS;
+ const VkDeviceSize aligned = (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE);
+ const VkDeviceSize min_size = MAX_ALIGNMENT * StagingBufferPool::NUM_SYNCS;
return static_cast((std::max)(aligned, min_size));
}
} // Anonymous namespace
@@ -63,10 +62,8 @@ size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) {
StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_,
Scheduler& scheduler_)
: device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
- stream_alignment{std::max(device_.GetUniformBufferAlignment(),
- MIN_STREAM_ALIGNMENT)},
- stream_buffer_size{GetStreamBufferSize(device_, stream_alignment)},
- region_size{stream_buffer_size / StagingBufferPool::NUM_SYNCS} {
+ stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size /
+ StagingBufferPool::NUM_SYNCS} {
VkBufferCreateInfo stream_ci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
@@ -119,11 +116,10 @@ void StagingBufferPool::TickFrame() {
}
StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
- const size_t alignment = static_cast(stream_alignment);
- const size_t aligned_size = Common::AlignUp(size, alignment);
+ const size_t aligned_size = Common::AlignUp(size, MAX_ALIGNMENT);
const bool wraps = iterator + size >= stream_buffer_size;
const size_t new_iterator =
- wraps ? aligned_size : Common::AlignUp(iterator + size, alignment);
+ wraps ? aligned_size : Common::AlignUp(iterator + size, MAX_ALIGNMENT);
const size_t begin_region = wraps ? 0 : Region(iterator);
const size_t last_byte = new_iterator == 0 ? 0 : new_iterator - 1;
const size_t end_region = (std::min)(Region(last_byte) + 1, NUM_SYNCS);
@@ -149,7 +145,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
current_tick);
used_iterator = 0;
iterator = 0;
- free_iterator = aligned_size;
+ free_iterator = size;
const size_t head_last_byte = aligned_size == 0 ? 0 : aligned_size - 1;
const size_t head_end_region = (std::min)(Region(head_last_byte) + 1, NUM_SYNCS);
if (AreRegionsActive(0, head_end_region)) {
@@ -164,7 +160,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
iterator = new_iterator;
if (!wraps) {
- free_iterator = (std::max)(free_iterator, offset + aligned_size);
+ free_iterator = (std::max)(free_iterator, offset + size);
}
return StagingBufferRef{
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
index 5c40ca069f..f63a203272 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
@@ -1,6 +1,3 @@
-// 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-3.0-or-later
@@ -105,7 +102,6 @@ private:
MemoryAllocator& memory_allocator;
Scheduler& scheduler;
- VkDeviceSize stream_alignment;
vk::Buffer stream_buffer;
std::span stream_pointer;
VkDeviceSize stream_buffer_size;
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index c03f7a3abf..010a3db174 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -234,6 +234,9 @@ add_executable(yuzu
deps_dialog.cpp
deps_dialog.h
deps_dialog.ui
+
+ data_dialog.h data_dialog.cpp data_dialog.ui
+ data_widget.ui
)
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")
@@ -390,7 +393,7 @@ endif()
target_link_libraries(yuzu PRIVATE nlohmann_json::nlohmann_json)
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 Boost::headers glad Qt6::Widgets Qt6::Concurrent)
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
if (NOT WIN32)
@@ -405,25 +408,6 @@ if (UNIX AND NOT APPLE)
endif()
endif()
-target_compile_definitions(yuzu PRIVATE
- # Use QStringBuilder for string concatenation to reduce
- # the overall number of temporary strings created.
- QT_USE_QSTRINGBUILDER
-
- # Disable implicit conversions from/to C strings
- QT_NO_CAST_FROM_ASCII
- QT_NO_CAST_TO_ASCII
-
- # Disable implicit type narrowing in signal/slot connect() calls.
- QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
-
- # Disable unsafe overloads of QProcess' start() function.
- QT_NO_PROCESS_COMBINED_ARGUMENT_START
-
- # Disable implicit QString->QUrl conversions to enforce use of proper resolving functions.
- QT_NO_URL_CAST_FROM_STRING
-)
-
if (YUZU_ENABLE_COMPATIBILITY_REPORTING)
target_compile_definitions(yuzu PRIVATE YUZU_ENABLE_COMPATIBILITY_REPORTING)
endif()
diff --git a/src/yuzu/compatdb.cpp b/src/yuzu/compatdb.cpp
index 0e58f17405..6d5d263e16 100644
--- a/src/yuzu/compatdb.cpp
+++ b/src/yuzu/compatdb.cpp
@@ -1,10 +1,13 @@
+// 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
#include
#include
#include
-#include
+#include
#include "common/logging/log.h"
#include "ui_compatdb.h"
#include "yuzu/compatdb.h"
diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp
index 15a0029901..7a693be10c 100644
--- a/src/yuzu/configuration/configure_web.cpp
+++ b/src/yuzu/configuration/configure_web.cpp
@@ -14,7 +14,7 @@
#include
#endif
-#include
+#include
#include "common/settings.h"
#include "ui_configure_web.h"
#include "qt_common/uisettings.h"
diff --git a/src/yuzu/data_dialog.cpp b/src/yuzu/data_dialog.cpp
new file mode 100644
index 0000000000..d7c937e7ed
--- /dev/null
+++ b/src/yuzu/data_dialog.cpp
@@ -0,0 +1,105 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "data_dialog.h"
+#include "frontend_common/data_manager.h"
+#include "qt_common/qt_content_util.h"
+#include "qt_common/qt_frontend_util.h"
+#include "qt_common/qt_progress_dialog.h"
+#include "qt_common/qt_string_lookup.h"
+#include "ui_data_dialog.h"
+
+#include
+#include
+#include
+#include
+#include
+
+DataDialog::DataDialog(QWidget *parent)
+ : QDialog(parent)
+ , ui(std::make_unique())
+{
+ ui->setupUi(this);
+
+ // TODO: Should we make this a single widget that pulls data from a model?
+#define WIDGET(name) \
+ ui->page->addWidget(new DataWidget(FrontendCommon::DataManager::DataDir::name, \
+ QtCommon::StringLookup::name##Tooltip, \
+ this));
+
+ WIDGET(Saves)
+ WIDGET(Shaders)
+ WIDGET(UserNand)
+ WIDGET(SysNand)
+ WIDGET(Mods)
+
+#undef WIDGET
+
+ connect(ui->labels, &QListWidget::itemSelectionChanged, this, [this]() {
+ ui->page->setCurrentIndex(ui->labels->currentRow());
+ });
+}
+
+DataDialog::~DataDialog() = default;
+
+DataWidget::DataWidget(FrontendCommon::DataManager::DataDir data_dir,
+ QtCommon::StringLookup::StringKey tooltip,
+ QWidget *parent)
+ : QWidget(parent)
+ , ui(std::make_unique())
+ , m_dir(data_dir)
+{
+ ui->setupUi(this);
+
+ ui->tooltip->setText(QtCommon::StringLookup::Lookup(tooltip));
+
+ ui->clear->setIcon(QIcon::fromTheme(QStringLiteral("user-trash")));
+ ui->open->setIcon(QIcon::fromTheme(QStringLiteral("folder")));
+ ui->upload->setIcon(QIcon::fromTheme(QStringLiteral("upload")));
+ ui->download->setIcon(QIcon::fromTheme(QStringLiteral("download")));
+
+ connect(ui->clear, &QPushButton::clicked, this, &DataWidget::clear);
+ connect(ui->open, &QPushButton::clicked, this, &DataWidget::open);
+ connect(ui->upload, &QPushButton::clicked, this, &DataWidget::upload);
+ connect(ui->download, &QPushButton::clicked, this, &DataWidget::download);
+
+ scan();
+}
+
+void DataWidget::clear()
+{
+ QtCommon::Content::ClearDataDir(m_dir);
+ scan();
+}
+
+void DataWidget::open()
+{
+ QDesktopServices::openUrl(QUrl::fromLocalFile(
+ QString::fromStdString(FrontendCommon::DataManager::GetDataDir(m_dir))));
+}
+
+void DataWidget::upload()
+{
+ QtCommon::Content::ExportDataDir(m_dir);
+}
+
+void DataWidget::download()
+{
+ QtCommon::Content::ImportDataDir(m_dir, std::bind(&DataWidget::scan, this));
+}
+
+void DataWidget::scan() {
+ ui->size->setText(tr("Calculating..."));
+
+ QFutureWatcher *watcher = new QFutureWatcher(this);
+
+ connect(watcher, &QFutureWatcher::finished, this, [=, this]() {
+ u64 size = watcher->result();
+ ui->size->setText(
+ QString::fromStdString(FrontendCommon::DataManager::ReadableBytesSize(size)));
+ watcher->deleteLater();
+ });
+
+ watcher->setFuture(
+ QtConcurrent::run([this]() { return FrontendCommon::DataManager::DataDirSize(m_dir); }));
+}
diff --git a/src/yuzu/data_dialog.h b/src/yuzu/data_dialog.h
new file mode 100644
index 0000000000..8a64659965
--- /dev/null
+++ b/src/yuzu/data_dialog.h
@@ -0,0 +1,50 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef DATA_DIALOG_H
+#define DATA_DIALOG_H
+
+#include
+#include "frontend_common/data_manager.h"
+#include "qt_common/qt_string_lookup.h"
+
+#include "ui_data_widget.h"
+
+namespace Ui {
+class DataDialog;
+}
+
+class DataDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit DataDialog(QWidget *parent = nullptr);
+ ~DataDialog();
+
+private:
+ std::unique_ptr ui;
+};
+
+class DataWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit DataWidget(FrontendCommon::DataManager::DataDir data_dir,
+ QtCommon::StringLookup::StringKey tooltip,
+ QWidget *parent = nullptr);
+
+public slots:
+ void clear();
+ void open();
+ void upload();
+ void download();
+
+ void scan();
+
+private:
+ std::unique_ptr ui;
+ FrontendCommon::DataManager::DataDir m_dir;
+};
+
+#endif // DATA_DIALOG_H
diff --git a/src/yuzu/data_dialog.ui b/src/yuzu/data_dialog.ui
new file mode 100644
index 0000000000..06751e2fb1
--- /dev/null
+++ b/src/yuzu/data_dialog.ui
@@ -0,0 +1,148 @@
+
+
+ DataDialog
+
+
+
+ 0
+ 0
+ 480
+ 320
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 300
+ 320
+
+
+
+ Data Manager
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
-
+
+ Saves
+
+
+ -
+
+ Shaders
+
+
+ -
+
+ UserNAND
+
+
+ -
+
+ SysNAND
+
+
+ -
+
+ Mods
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 275
+ 200
+
+
+
+ -1
+
+
+
+
+
+ -
+
+
+ 10
+
+
-
+
+
+ Deleting ANY data is IRREVERSABLE!
+
+
+
+ -
+
+
+ Qt::Orientation::Horizontal
+
+
+ QDialogButtonBox::StandardButton::Ok
+
+
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ DataDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ DataDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/yuzu/data_widget.ui b/src/yuzu/data_widget.ui
new file mode 100644
index 0000000000..99010d8856
--- /dev/null
+++ b/src/yuzu/data_widget.ui
@@ -0,0 +1,205 @@
+
+
+ DataWidget
+
+
+
+ 0
+ 0
+ 275
+ 200
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+ Tooltip
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+
+ 10
+ true
+
+
+
+ Size
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ true
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 1
+ 1
+
+
+
+
+ 52
+ 47
+
+
+
+ Open with your system file manager
+
+
+ QPushButton {
+max-width: 50px;
+max-height: 45px;
+min-width: 50px;
+min-height: 45px;
+}
+
+
+
+
+
+
+ 28
+ 28
+
+
+
+
+ -
+
+
+
+ 1
+ 1
+
+
+
+
+ 52
+ 47
+
+
+
+ Delete all data in this directory. THIS IS 100% IRREVERSABLE!
+
+
+ QPushButton {
+max-width: 50px;
+max-height: 45px;
+min-width: 50px;
+min-height: 45px;
+}
+
+
+
+
+
+
+ 28
+ 28
+
+
+
+
+ -
+
+
+
+ 1
+ 1
+
+
+
+
+ 52
+ 47
+
+
+
+ Export all data in this directory. This may take a while!
+
+
+ QPushButton {
+max-width: 50px;
+max-height: 45px;
+min-width: 50px;
+min-height: 45px;
+}
+
+
+
+
+
+
+ 28
+ 28
+
+
+
+
+ -
+
+
+
+ 1
+ 1
+
+
+
+
+ 52
+ 47
+
+
+
+ Import data for this directory. This may take a while, and will delete ALL EXISTING DATA!
+
+
+ QPushButton {
+max-width: 50px;
+max-height: 45px;
+min-width: 50px;
+min-height: 45px;
+}
+
+
+
+
+
+
+ 28
+ 28
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 44ed29f141..21c92c495f 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -156,6 +156,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "yuzu/debugger/console.h"
#include "yuzu/debugger/controller.h"
#include "yuzu/debugger/wait_tree.h"
+#include "yuzu/data_dialog.h"
#include "yuzu/deps_dialog.h"
#include "yuzu/discord.h"
#include "yuzu/game_list.h"
@@ -1705,6 +1706,7 @@ void GMainWindow::ConnectMenuEvents() {
connect_menu(ui->action_Install_Keys, &GMainWindow::OnInstallDecryptionKeys);
connect_menu(ui->action_About, &GMainWindow::OnAbout);
connect_menu(ui->action_Eden_Dependencies, &GMainWindow::OnEdenDependencies);
+ connect_menu(ui->action_Data_Manager, &GMainWindow::OnDataDialog);
}
void GMainWindow::UpdateMenuState() {
@@ -3934,6 +3936,15 @@ void GMainWindow::OnEdenDependencies() {
depsDialog.exec();
}
+void GMainWindow::OnDataDialog() {
+ DataDialog dataDialog(this);
+ dataDialog.exec();
+
+ // refresh stuff in case it was cleared
+ OnGameListRefresh();
+
+}
+
void GMainWindow::OnToggleFilterBar() {
game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
if (ui->action_Show_Filter_Bar->isChecked()) {
@@ -4474,11 +4485,15 @@ void GMainWindow::SetFirmwareVersion() {
if (result.IsError() || !CheckFirmwarePresence()) {
LOG_INFO(Frontend, "Installed firmware: No firmware available");
+ ui->menu_Applets->setEnabled(false);
+ ui->menu_Create_Shortcuts->setEnabled(false);
firmware_label->setVisible(false);
return;
}
firmware_label->setVisible(true);
+ ui->menu_Applets->setEnabled(true);
+ ui->menu_Create_Shortcuts->setEnabled(true);
const std::string display_version(firmware_data.display_version.data());
const std::string display_title(firmware_data.display_title.data());
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index e3922759b0..a3e99c05fe 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -387,6 +387,7 @@ private slots:
void OnInstallDecryptionKeys();
void OnAbout();
void OnEdenDependencies();
+ void OnDataDialog();
void OnToggleFilterBar();
void OnToggleStatusBar();
void OnGameListRefresh();
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index 5f56c9e6d1..12ff4efdf1 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -158,13 +158,23 @@
+
diff --git a/src/yuzu/multiplayer/chat_room.cpp b/src/yuzu/multiplayer/chat_room.cpp
index 4c2c41ea2a..53beda0f8e 100644
--- a/src/yuzu/multiplayer/chat_room.cpp
+++ b/src/yuzu/multiplayer/chat_room.cpp
@@ -16,7 +16,7 @@
#include
#include
#include
-#include
+#include
#include "common/logging/log.h"
#include "network/announce_multiplayer_session.h"
#include "ui_chat_room.h"
diff --git a/src/yuzu/multiplayer/client_room.cpp b/src/yuzu/multiplayer/client_room.cpp
index 93d6662c1e..4e995c044f 100644
--- a/src/yuzu/multiplayer/client_room.cpp
+++ b/src/yuzu/multiplayer/client_room.cpp
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
#include "common/logging/log.h"
#include "network/announce_multiplayer_session.h"
#include "ui_client_room.h"
diff --git a/src/yuzu/multiplayer/direct_connect.cpp b/src/yuzu/multiplayer/direct_connect.cpp
index deac3b9e59..6291979fe6 100644
--- a/src/yuzu/multiplayer/direct_connect.cpp
+++ b/src/yuzu/multiplayer/direct_connect.cpp
@@ -9,7 +9,7 @@
#include
#include
#include
-#include
+#include
#include "common/settings.h"
#include "core/core.h"
#include "core/internal_network/network_interface.h"
diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp
index 4dd3958550..cc163a5420 100644
--- a/src/yuzu/multiplayer/host_room.cpp
+++ b/src/yuzu/multiplayer/host_room.cpp
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp
index 84723041df..e8daa0c6eb 100644
--- a/src/yuzu/multiplayer/lobby.cpp
+++ b/src/yuzu/multiplayer/lobby.cpp
@@ -6,7 +6,7 @@
#include
#include
-#include
+#include
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"