Compare commits

...

7 Commits

Author SHA1 Message Date
lizzie cf1d905786 2026-09-15 07:28:16
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 07:28:17 +00:00
lizzie 60003ea642 2026-09-15 06:40:57
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 06:40:58 +00:00
lizzie 43607d0b7e 2026-09-15 06:36:27
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 06:36:27 +00:00
PavelBARABANOV defddec47f [ns] add stubs for cmd936 and cmd4042 (#4429)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------
This is necessary to close Absolum and Hades 2 in qlaunch.

Cmd4042 is necessary that there are no freezes when opening virtual cartridges.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4429
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2026-09-15 08:01:17 +02:00
CamilleLaVey c5405250d1 [common, ui] Refining UI for FX shaders for PC (#4426)
Self-explanatory refinements on the already existing access/usage of post-processing shaders on Eden for PC UI.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4426
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 07:23:12 +02:00
crueter 10c07d700c [cmake] Use a debloated boost distribution (#4198)
This addresses another issue that caused Windows configure time to take significantly longer than other platforms.

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4198
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 07:22:23 +02:00
PavelBARABANOV 505b157647 [qt common] use ConfigurationShared translation context (#4430)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4430
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-09-15 03:42:11 +02:00
15 changed files with 210 additions and 51 deletions
-13
View File
@@ -1,13 +0,0 @@
diff --git a/libs/cobalt/include/boost/cobalt/concepts.hpp b/libs/cobalt/include/boost/cobalt/concepts.hpp
index d49f2ec..a9bdb80 100644
--- a/libs/cobalt/include/boost/cobalt/concepts.hpp
+++ b/libs/cobalt/include/boost/cobalt/concepts.hpp
@@ -62,7 +62,7 @@ struct enable_awaitables
template <typename T>
concept with_get_executor = requires (T& t)
{
- {t.get_executor()} -> asio::execution::executor;
+ t.get_executor();
};
+3 -7
View File
@@ -417,12 +417,9 @@ AddJsonPackage(boost)
set(BOOST_NO_HEADERS ${Boost_ADDED})
if (Boost_ADDED)
if (MSVC OR ANDROID)
add_compile_definitions(YUZU_BOOST_v1)
endif()
add_compile_definitions(YUZU_BOOST_v1)
if (NOT MSVC OR CXX_CLANG)
# boost sucks
# solaris sucks
if (SOLARIS)
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-pthreads>)
endif()
@@ -431,8 +428,7 @@ if (Boost_ADDED)
target_compile_options(boost_icl INTERFACE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-shadow>)
target_compile_options(boost_asio INTERFACE
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-conversion>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>
)
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-implicit-fallthrough>)
endif()
endif()
+6 -9
View File
@@ -6,22 +6,19 @@
"version": "v0.19.0"
},
"boost": {
"artifact": "%VERSION%-cmake.tar.xz",
"artifact": "boost-%VERSION%.tar.zst",
"find_args": "CONFIG OPTIONAL_COMPONENTS headers context system fiber filesystem",
"hash": "6ae6e94664fe7f2fb01976b59b276ac5df8085c7503fa829d810fbfe495960cfec44fa2c36e2cb23480bc19c956ed199d4952b02639a00a6c07625d4e7130c2d",
"hash": "681d97be4386767662e230b2e7c9754d45e709cc5db4e747c23c27d1f5b0e87770bdf19b0bc44dcb0e8349324887bbb8fffb432098f4d0ce74a5043021a90afc",
"min_version": "1.57",
"package": "Boost",
"patches": [
"0001-clang-cl.patch"
],
"repo": "boostorg/boost",
"version": "boost-1.90.0"
"repo": "eden-emulator/ext-boost",
"version": "1.92.0"
},
"boost_headers": {
"bundled": true,
"hash": "4ef845775e2277a8104ded6ddf749aa262ce52cf8438042869a048f9a0156dd772fbbcfa74efa1378fecef339b7286f6fe4b4feb5c45d49966b35d08e3e83507",
"hash": "c5fa2cd72f6e6666b7963b97bc359c75284b8fb540c30f3629a028b85270c9bc66c8a051383964f2bd4c1e005a4691593d15696e7ef39ea87cf6cff9e5691fb2",
"repo": "boostorg/headers",
"version": "boost-1.90.0"
"version": "boost-1.91.0"
},
"catch2": {
"hash": "7eea385d79d88a5690cde131fe7ccda97d5c54ea09d6f515000d7bf07c828809d61c1ac99912c1ee507cf933f61c1c47ecdcc45df7850ffa82714034b0fccf35",
+2
View File
@@ -810,6 +810,8 @@ add_library(core STATIC
hle/service/ns/ecommerce_interface.h
hle/service/ns/factory_reset_interface.cpp
hle/service/ns/factory_reset_interface.h
hle/service/ns/i_async_result.cpp
hle/service/ns/i_async_result.h
hle/service/ns/language.cpp
hle/service/ns/language.h
hle/service/ns/ns.cpp
@@ -228,9 +228,9 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{930, nullptr, "Unknown930"}, //20.0.0+
{931, nullptr, "Unknown931"}, //20.0.0+
{933, nullptr, "Unknown933"}, //20.0.0+
{934, nullptr, "Unknown934"}, //20.0.0+
{935, nullptr, "Unknown935"}, //20.0.0+
{936, nullptr, "Unknown936"}, //20.0.0+
{934, nullptr, "Unknown934"}, //21.0.0+
{935, nullptr, "Unknown935"}, //21.0.0+
{936, D<&IApplicationManagerInterface::Unknown936>, "Unknown936"}, //21.0.0+
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
{1001, nullptr, "CorruptApplicationForDebug"},
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
@@ -422,7 +422,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{4039, nullptr, "Unknown4039"}, //20.0.0+
{4040, nullptr, "Unknown4040"}, //20.0.0+
{4041, nullptr, "Unknown4041"}, //20.0.0+
{4042, nullptr, "Unknown4042"}, //20.0.0+
{4042, D<&IApplicationManagerInterface::Unknown4042>, "Unknown4042"}, //20.0.0+
{4043, nullptr, "Unknown4043"}, //20.0.0+
{4044, nullptr, "Unknown4044"}, //20.0.0+
{4045, nullptr, "Unknown4045"}, //20.0.0+
@@ -639,6 +639,12 @@ Result IApplicationManagerInterface::IsGameCardApplicationRunning(Out<bool> out_
R_SUCCEED();
}
Result IApplicationManagerInterface::Unknown936(Out<u64> out_result) {
LOG_WARNING(Service_NS, "(STUBBED) called.");
*out_result = 0;
R_SUCCEED();
}
Result IApplicationManagerInterface::IsAnyApplicationEntityInstalled(
Out<bool> out_is_any_application_entity_installed) {
LOG_WARNING(Service_NS, "(STUBBED) called");
@@ -862,6 +868,15 @@ Result IApplicationManagerInterface::Unknown4023(Out<u64> out_result) {
R_SUCCEED();
}
Result IApplicationManagerInterface::Unknown4042(OutInterface<IAsyncResult> out_interface,
OutCopyHandle<Kernel::KReadableEvent> out_event,
u64 arg1, u64 arg2) {
LOG_WARNING(Service_NS, "(STUBBED) called, arg1={:016X}, arg2={:016X}", arg1, arg2);
*out_event = unknown_event.GetHandle();
*out_interface = std::make_shared<IAsyncResult>(system, &unknown_event);
R_SUCCEED();
}
Result IApplicationManagerInterface::Unknown4053() {
LOG_WARNING(Service_NS, "(STUBBED) called.");
R_SUCCEED();
@@ -7,6 +7,7 @@
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/i_async_result.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/os/event.h"
@@ -34,6 +35,7 @@ public:
Result GetGameCardMountFailureEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetGameCardWakenReadyEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsGameCardApplicationRunning(Out<bool> out_is_running);
Result Unknown936(Out<u64> out_result);
Result IsAnyApplicationEntityInstalled(Out<bool> out_is_any_application_entity_installed);
Result GetApplicationViewDeprecated(
OutArray<ApplicationViewV19, BufferAttr_HipcMapAlias> out_application_views,
@@ -71,6 +73,9 @@ public:
InBuffer<BufferAttr_HipcMapAlias> logo_path_buffer);
Result Unknown4022(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result Unknown4023(Out<u64> out_result);
Result Unknown4042(OutInterface<IAsyncResult> out_interface,
OutCopyHandle<Kernel::KReadableEvent> out_event,
u64 arg1, u64 arg2);
Result Unknown4053();
Result Unknown4105();
@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/i_async_result.h"
#include <cstring>
namespace Service::NS {
IAsyncResult::IAsyncResult(Core::System& system_, Service::Event* event_)
: ServiceFramework{system_, "nn::ns::detail::IAsyncResult"}, event{event_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Get"},
{1, D<&IAsyncResult::Cancel>, "Cancel"},
{2, nullptr, "GetErrorContext"}, // 4.0.0+
};
// clang-format on
RegisterHandlers(functions);
}
IAsyncResult::~IAsyncResult() = default;
Result IAsyncResult::Cancel() {
LOG_DEBUG(Service_NS, "called");
if (event != nullptr) {
event->Signal(system.Kernel());
}
R_SUCCEED();
}
} // namespace Service::NS
+19
View File
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/service.h"
namespace Service::NS {
class IAsyncResult final : public ServiceFramework<IAsyncResult> {
public:
explicit IAsyncResult(Core::System& system_, Service::Event* event_);
~IAsyncResult() override;
private:
Result Cancel();
Service::Event* event{};
};
} // namespace Service::NS
+6 -3
View File
@@ -23,7 +23,7 @@ namespace ConfigurationShared {
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); };
const auto& tr = [](const char* text) -> QString { return QCoreApplication::translate("ConfigurationShared", text); };
#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \
translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{(NAME), (TOOLTIP)}})
@@ -151,6 +151,9 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA "
"can produce a more stable picture in lower resolutions."));
INSERT(Settings, post_shader_chain, QString(), QString());
INSERT(Settings, post_shader_preset, QString(), QString());
INSERT(Settings, post_shader_enabled, tr("Enable post-processing effects"),
tr("Applies post-processing effects to the final image."));
INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"),
tr("The method used to render the window in fullscreen.\nBorderless offers the best "
"compatibility with the on-screen keyboard that some games request for "
@@ -368,8 +371,8 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* 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 = "") {
return parent->tr(text, context);
const auto& tr = [](const char* text, const char* context = "") {
return QCoreApplication::translate("ConfigurationShared", text, context);
};
#define PAIR(ENUM, VALUE, TRANSLATION) {static_cast<u32>(Settings::ENUM::VALUE), (TRANSLATION)}
+4
View File
@@ -444,6 +444,10 @@ if (YUZU_ROOM)
target_link_libraries(yuzu PRIVATE yuzu-room)
endif()
if (LINKER STREQUAL "lld")
target_link_options(yuzu-cmd PRIVATE "LINKER:--icf=all")
endif()
if (NOT MSVC AND (APPLE OR NOT YUZU_STATIC_BUILD))
# needed for vma
target_compile_options(yuzu PRIVATE
@@ -37,6 +37,10 @@
#include "yuzu/configuration/configure_graphics.h"
#include "yuzu/configuration/shared_widget.h"
#ifdef HAS_RESHADE
#include "yuzu/configuration/configure_post_processing.h"
#endif
ConfigureGraphics::ConfigureGraphics(
const Core::System& system_, std::vector<VkDeviceInfo::Record>& records_,
const std::function<void()>& expose_compute_option_,
@@ -216,6 +220,12 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
std::vector<QWidget*> hold_api;
for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) {
#ifndef HAS_RESHADE
if (setting->Id() == Settings::values.post_shader_enabled.Id()) {
continue;
}
#endif
ConfigurationShared::Widget* widget = [&]() {
if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
// FSR needs a reversed slider and a 0.5 multiplier
@@ -295,6 +305,23 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
// Keep track of the resolution combobox to update other UI tabs that need it
resolution_combobox = widget->combobox;
hold_graphics.emplace(setting->Id(), widget);
#ifdef HAS_RESHADE
} else if (setting->Id() == Settings::values.post_shader_enabled.Id()) {
QPushButton* post_shader_button = new QPushButton(tr("Configure Effects..."), widget);
post_shader_button->setVisible(widget->checkbox->isChecked());
connect(post_shader_button, &QAbstractButton::clicked, this, [this]() {
ConfigurePostProcessing dialog(this);
dialog.exec();
});
connect(widget->checkbox, &QCheckBox::toggled, post_shader_button,
&QWidget::setVisible);
QBoxLayout* row = qobject_cast<QBoxLayout*>(widget->layout());
row->insertWidget(1, post_shader_button);
hold_graphics.emplace(setting->Id(), widget);
#endif
} else {
hold_graphics.emplace(setting->Id(), widget);
}
@@ -70,10 +70,8 @@ ConfigurePostProcessing::ConfigurePostProcessing(QWidget* parent) : QDialog(pare
auto* root = new QVBoxLayout(this);
auto* description = new QLabel(
tr("ReShade FX effects are loaded from the post_shaders folder in the Eden data "
"directory. Changes apply immediately while a game is running."),
this);
auto* description =
new QLabel(tr("Changes apply immediately while a game is running."), this);
description->setWordWrap(true);
root->addWidget(description);
@@ -128,17 +126,15 @@ ConfigurePostProcessing::ConfigurePostProcessing(QWidget* parent) : QDialog(pare
});
preset_row->addWidget(save_button);
auto* delete_button = new QPushButton(tr("Delete"), this);
connect(delete_button, &QPushButton::clicked, this, [this]() {
const QString name = preset_combo->currentData().toString();
if (name.isEmpty()) {
return;
}
VideoCore::DeleteFxPreset(name.toStdString());
PopulatePresetCombo();
RefreshPresetStatus();
auto* clear_button = new QPushButton(tr("Clear"), this);
clear_button->setToolTip(tr("Remove every effect in use and deselect the preset."));
connect(clear_button, &QPushButton::clicked, this, [this]() {
VideoCore::FxChain::Instance().Clear();
VideoCore::SetActiveFxPreset(std::string());
preset_combo->setCurrentIndex(0);
ApplyStructuralChange();
});
preset_row->addWidget(delete_button);
preset_row->addWidget(clear_button);
root->addLayout(preset_row);
@@ -203,6 +199,7 @@ void ConfigurePostProcessing::ApplyStructuralChange() {
void ConfigurePostProcessing::PopulatePresetCombo() {
const QString previous = preset_combo->currentData().toString();
preset_combo->clear();
preset_combo->addItem(tr("None"), QString());
for (const auto& preset : VideoCore::GetFxPresetCatalog()) {
const QString name = QString::fromStdString(preset.name);
@@ -212,7 +209,7 @@ void ConfigurePostProcessing::PopulatePresetCombo() {
}
const int restored = preset_combo->findData(previous);
if (restored >= 0) {
if (!previous.isEmpty() && restored >= 0) {
preset_combo->setCurrentIndex(restored);
return;
}
@@ -220,12 +217,21 @@ void ConfigurePostProcessing::PopulatePresetCombo() {
const int active = preset_combo->findData(QString::fromStdString(VideoCore::GetActiveFxPreset()));
if (active >= 0) {
preset_combo->setCurrentIndex(active);
return;
}
preset_combo->setCurrentIndex(0);
}
void ConfigurePostProcessing::RefreshPresetStatus() {
const std::string active = VideoCore::GetActiveFxPreset();
if (active.empty()) {
if (VideoCore::FxChain::Instance().Size() == 0) {
preset_status->setText(
tr("No effects in use. Pick a preset and press Apply, or add effects one "
"by one."));
return;
}
preset_status->setText(tr("Custom chain. Pick a preset above and press Apply to replace it."));
return;
}
+57
View File
@@ -15,6 +15,7 @@
#include "render/performance_overlay.h"
#ifdef HAS_RESHADE
#include "configuration/configure_post_processing.h"
#include "video_core/post_processing/fx_preset.h"
#endif
#include "updater/update_dialog.h"
@@ -1090,6 +1091,41 @@ void MainWindow::InitializeWidgets() {
statusBar()->insertPermanentWidget(0, volume_button);
#ifdef HAS_RESHADE
post_shader_status_button = new QPushButton();
post_shader_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
post_shader_status_button->setFocusPolicy(Qt::NoFocus);
post_shader_status_button->setCheckable(true);
connect(post_shader_status_button, &QPushButton::clicked, this, [this] {
const bool enabled = Settings::values.post_shader_enabled.GetValue();
Settings::values.post_shader_enabled.SetValue(!enabled);
UpdatePostShaderText();
});
UpdatePostShaderText();
post_shader_status_button->setContextMenuPolicy(Qt::CustomContextMenu);
connect(post_shader_status_button, &QPushButton::customContextMenuRequested,
[this](const QPoint& menu_location) {
QMenu context_menu;
for (auto const& preset : VideoCore::GetFxPresetCatalog()) {
context_menu.addAction(QString::fromStdString(preset.name),
[this, name = preset.name] {
VideoCore::ApplyFxPreset(name);
Settings::values.post_shader_enabled.SetValue(true);
UpdatePostShaderText();
});
}
context_menu.addSeparator();
context_menu.addAction(tr("Configure Effects..."), this,
&MainWindow::OnPostProcessingShaders);
context_menu.exec(post_shader_status_button->mapToGlobal(menu_location));
post_shader_status_button->repaint();
});
statusBar()->insertPermanentWidget(0, post_shader_status_button);
#endif
// setup AA button
aa_status_button = new QPushButton();
aa_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
@@ -3908,6 +3944,7 @@ void MainWindow::OnPostProcessingShaders() {
connect(post_processing_dialog, &QDialog::finished, post_processing_dialog, [this]() {
post_processing_dialog->deleteLater();
post_processing_dialog = nullptr;
UpdatePostShaderText();
});
}
@@ -4262,6 +4299,26 @@ void MainWindow::UpdateAAText() {
: aa_text.toUpper());
}
#ifdef HAS_RESHADE
void MainWindow::UpdatePostShaderText() {
const bool enabled = Settings::values.post_shader_enabled.GetValue();
post_shader_status_button->setChecked(enabled);
if (!enabled) {
post_shader_status_button->setText(tr("NO FX"));
return;
}
const std::string preset = VideoCore::GetActiveFxPreset();
if (preset.empty()) {
post_shader_status_button->setText(tr("FX"));
return;
}
post_shader_status_button->setText(QString::fromStdString(preset).toUpper());
}
#endif
void MainWindow::UpdateVolumeUI() {
const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
volume_slider->setValue(volume_value);
+2
View File
@@ -448,6 +448,7 @@ private:
void UpdateAPIText();
void UpdateFilterText();
void UpdateAAText();
void UpdatePostShaderText();
void UpdateVolumeUI();
void UpdateStatusBar();
void UpdateGPUAccuracyButton();
@@ -524,6 +525,7 @@ private:
QPushButton* dock_status_button = nullptr;
QPushButton* filter_status_button = nullptr;
QPushButton* aa_status_button = nullptr;
QPushButton* post_shader_status_button = nullptr;
VolumeButton* volume_button = nullptr;
QWidget* volume_popup = nullptr;
QSlider* volume_slider = nullptr;
+4
View File
@@ -67,6 +67,10 @@ endif()
create_target_directory_groups(yuzu-cmd)
if (LINKER STREQUAL "lld")
target_link_options(yuzu-cmd PRIVATE "LINKER:--icf=all")
endif()
# needed for vma
if (NOT MSVC)
target_compile_options(yuzu-cmd PRIVATE