From dfca07f4e3df72b243828268d0a3c4a49279ff9f Mon Sep 17 00:00:00 2001 From: xbzk Date: Wed, 1 Oct 2025 00:10:59 +0200 Subject: [PATCH 1/6] Initial a9 (minsdk=28) support (#2600) Minimal changes to make android 10 installable and emulationFragment not immediately crashable. Testers (mainly android 10) NEEDED!!! Co-authored-by: Allison Cunha Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2600 Reviewed-by: Lizzie Co-authored-by: xbzk Co-committed-by: xbzk --- src/android/app/build.gradle.kts | 2 +- .../org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt | 5 +++-- src/common/host_memory.cpp | 10 ++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index d3a05cf3e2..e8d8141711 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -59,7 +59,7 @@ android { defaultConfig { // TODO If this is ever modified, change application_id in strings.xml applicationId = "dev.eden.eden_emulator" - minSdk = 30 + minSdk = 28 targetSdk = 36 versionName = getGitVersion() diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt index 8a66ebf11f..2c35e7349a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt @@ -19,6 +19,7 @@ import org.yuzu.yuzu_emu.adapters.GameAdapter import androidx.core.view.doOnNextLayout import org.yuzu.yuzu_emu.YuzuApplication import androidx.preference.PreferenceManager +import androidx.core.view.WindowInsetsCompat /** * CarouselRecyclerView encapsulates all carousel logic for the games UI. @@ -205,8 +206,8 @@ class CarouselRecyclerView @JvmOverloads constructor( if (enabled) { useCustomDrawingOrder = true - val insets = rootWindowInsets - val bottomInset = insets?.getInsets(android.view.WindowInsets.Type.systemBars())?.bottom ?: 0 + val insets = rootWindowInsets?.let { WindowInsetsCompat.toWindowInsetsCompat(it, this) } + val bottomInset = insets?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: 0 val internalFactor = resources.getFraction(R.fraction.carousel_card_size_factor, 1, 1) val userFactor = preferences.getFloat(CAROUSEL_CARD_SIZE_FACTOR, internalFactor).coerceIn( 0f, diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 2e36d59569..3838c12903 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -56,6 +56,16 @@ #include "common/host_memory.h" #include "common/logging/log.h" +#if defined(__ANDROID__) && __ANDROID_API__ < 30 +#include +#ifndef MFD_CLOEXEC +#define MFD_CLOEXEC 0x0001U +#endif +static int memfd_create(const char* name, unsigned int flags) { + return syscall(__NR_memfd_create, name, flags); +} +#endif + namespace Common { constexpr size_t PageAlignment = 0x1000; From 43a7470a7d09ad412c7d9815ae23402f4bb7acb0 Mon Sep 17 00:00:00 2001 From: Gamer64 Date: Wed, 1 Oct 2025 01:21:12 +0200 Subject: [PATCH 2/6] [Maxwell]: Fix shaders compilation memory leak (#2606) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: collecting "The ObjectPool was never being cleared after use. When compiling complex shaders, this would allocate gigabytes of memory, causing the emulator to run out of RAM and be killed by the operating system. This is a critical fix that prevents out-of-memory crashes on all operating systems when playing games with complex shaders." Co-authored-by: Gamer64 <76565986+Gamer64ytb@users.noreply.github.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2606 Reviewed-by: MaranBr Reviewed-by: Shinmegumi Co-authored-by: Gamer64 Co-committed-by: Gamer64 --- .../frontend/maxwell/structured_control_flow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index b5e1e70b4c..6d325b4aad 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp @@ -991,6 +991,7 @@ IR::AbstractSyntaxList BuildASL(ObjectPool& inst_pool, ObjectPool Date: Mon, 15 Sep 2025 10:53:37 -0600 Subject: [PATCH 3/6] Better domain blocking * Bring in the domain-blocking code from the legacy branch * Make blockedDomains a 'static constexpr const std::array' --- src/core/hle/service/sockets/sfdnsres.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index b07bd3e58e..da34b2e201 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -53,6 +53,16 @@ enum class NetDbError : s32 { NoData = 4, }; +static constexpr const std::array blockedDomains = {"srv.nintendo.net", "battle.net", + "microsoft.com", "mojang.com", + "xboxlive.com", "minecraftservices.com"}; + +static bool IsBlockedHost(const std::string& host) { + return std::any_of( + blockedDomains.begin(), blockedDomains.end(), + [&host](const std::string& domain) { return host.find(domain) != std::string::npos; }); +} + static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) { // These combinations have been verified on console (but are not // exhaustive). @@ -154,7 +164,7 @@ static std::pair GetHostByNameRequestImpl(HLERequestConte // For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions. // Prevent resolution of Nintendo servers - if (host.find("srv.nintendo.net") != std::string::npos) { + if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); return {0, GetAddrInfoError::AGAIN}; } @@ -271,7 +281,7 @@ static std::pair GetAddrInfoRequestImpl(HLERequestContext const std::string host = Common::StringFromBuffer(host_buffer); // Prevent resolution of Nintendo servers - if (host.find("srv.nintendo.net") != std::string::npos) { + if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); return {0, GetAddrInfoError::AGAIN}; } @@ -359,5 +369,4 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) { rb.Push(ResultSuccess); rb.Push(0); // bsd errno } - } // namespace Service::Sockets From 91fb1df624bdd58f4636c74cb6bc922325cebbbf Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 1 Oct 2025 05:07:59 +0200 Subject: [PATCH 4/6] [meta] allow customisation of auto-updater, remove hardcoded title names and fix dup title names (#2588) Right now on all platforms, sdl2 will display something like "Eden Eden | master-8gd8fg8", this fixes so it only displays `Eden` (the REPO_NAME) once. Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2588 Reviewed-by: crueter Co-authored-by: lizzie Co-committed-by: lizzie --- CMakeModules/GenerateSCMRev.cmake | 6 +++++- src/common/scm_rev.cpp.in | 7 +++++++ src/common/scm_rev.h | 3 +++ src/yuzu/about_dialog.cpp | 9 +++++---- src/yuzu/main.cpp | 20 ++++++++++--------- src/yuzu/update_checker.cpp | 8 ++++++-- src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 2 +- .../emu_window/emu_window_sdl2_gl.cpp | 7 +++++-- 8 files changed, 43 insertions(+), 19 deletions(-) diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake index 2d7081b7db..1ae608c085 100644 --- a/CMakeModules/GenerateSCMRev.cmake +++ b/CMakeModules/GenerateSCMRev.cmake @@ -31,7 +31,11 @@ set(GIT_DESC ${BUILD_VERSION}) set(REPO_NAME "Eden") set(BUILD_ID ${GIT_REFSPEC}) set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ") - set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") +# Auto-updater metadata! Must somewhat mirror GitHub API endpoint +set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com") +set(BUILD_AUTO_UPDATE_API "http://api.github.com") +set(BUILD_AUTO_UPDATE_REPO "eden-emulator/Releases") + configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY) diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in index 1630ceae83..08b8c68835 100644 --- a/src/common/scm_rev.cpp.in +++ b/src/common/scm_rev.cpp.in @@ -18,6 +18,9 @@ #define TITLE_BAR_FORMAT_RUNNING "@TITLE_BAR_FORMAT_RUNNING@" #define IS_DEV_BUILD @IS_DEV_BUILD@ #define COMPILER_ID "@CXX_COMPILER@" +#define BUILD_AUTO_UPDATE_WEBISTE "@BUILD_AUTO_UPDATE_WEBISTE@" +#define BUILD_AUTO_UPDATE_API "@BUILD_AUTO_UPDATE_API@" +#define BUILD_AUTO_UPDATE_REPO "@BUILD_AUTO_UPDATE_REPO@" namespace Common { @@ -34,4 +37,8 @@ constexpr const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING; constexpr const char g_compiler_id[] = COMPILER_ID; constexpr const bool g_is_dev_build = IS_DEV_BUILD; +constexpr const char g_build_auto_update_website[] = BUILD_AUTO_UPDATE_WEBISTE; +constexpr const char g_build_auto_update_api[] = BUILD_AUTO_UPDATE_API; +constexpr const char g_build_auto_update_repo[] = BUILD_AUTO_UPDATE_REPO; + } // namespace Common diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index 8f48241557..b89de95a3d 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h @@ -21,5 +21,8 @@ extern const char g_title_bar_format_running[]; extern const char g_shader_cache_version[]; extern const char g_compiler_id[]; extern const bool g_is_dev_build; +extern const char g_build_auto_update_website[]; +extern const char g_build_auto_update_api[]; +extern const char g_build_auto_update_repo[]; } // namespace Common diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp index b7c0cd58d5..9f7597f471 100644 --- a/src/yuzu/about_dialog.cpp +++ b/src/yuzu/about_dialog.cpp @@ -14,11 +14,12 @@ AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent) , ui{std::make_unique()} { - static const std::string description = std::string{Common::g_build_version}; static const std::string build_id = std::string{Common::g_build_id}; - static const std::string compiler = std::string{Common::g_compiler_id}; - - static const std::string yuzu_build = fmt::format("Eden | {} | {}", description, compiler); + static const std::string yuzu_build = fmt::format("{} | {} | {}", + std::string{Common::g_build_name}, + std::string{Common::g_build_version}, + std::string{Common::g_compiler_id} + ); const auto override_build = fmt::format(fmt::runtime( std::string(Common::g_title_bar_format_idle)), diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index d2c12c9d40..71cc0a7e6b 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -4192,23 +4192,25 @@ void GMainWindow::OnEmulatorUpdateAvailable() { update_prompt.addButton(QMessageBox::Yes); update_prompt.addButton(QMessageBox::Ignore); update_prompt.setText( - tr("Update %1 for Eden is available.\nWould you like to download it?").arg(version_string)); + tr("Download the %1 update?").arg(version_string)); update_prompt.exec(); if (update_prompt.button(QMessageBox::Yes) == update_prompt.clickedButton()) { - QDesktopServices::openUrl( - QUrl(QString::fromStdString("https://github.com/eden-emulator/Releases/releases/tag/") + - version_string)); + auto const full_url = fmt::format("{}/{}/releases/tag/", + std::string{Common::g_build_auto_update_website}, + std::string{Common::g_build_auto_update_repo} + ); + QDesktopServices::openUrl(QUrl(QString::fromStdString(full_url) + version_string)); } } #endif void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version, std::string_view gpu_vendor) { - static const std::string description = std::string{Common::g_build_version}; - static const std::string build_id = std::string{Common::g_build_id}; - static const std::string compiler = std::string{Common::g_compiler_id}; - - static const std::string yuzu_title = fmt::format("Eden | {} | {}", description, compiler); + static const std::string yuzu_title = fmt::format("{} | {} | {}", + std::string{Common::g_build_name}, + std::string{Common::g_build_version}, + std::string{Common::g_compiler_id} + ); const auto override_title = fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); diff --git a/src/yuzu/update_checker.cpp b/src/yuzu/update_checker.cpp index 8291987d73..76b436d1d1 100644 --- a/src/yuzu/update_checker.cpp +++ b/src/yuzu/update_checker.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -12,6 +15,7 @@ #include #include #include +#include "common/scm_rev.h" std::optional UpdateChecker::GetResponse(std::string url, std::string path) { @@ -54,8 +58,8 @@ std::optional UpdateChecker::GetResponse(std::string url, std::stri std::optional UpdateChecker::GetLatestRelease(bool include_prereleases) { - constexpr auto update_check_url = "http://api.github.com"; - std::string update_check_path = "/repos/eden-emulator/Releases"; + constexpr auto update_check_url = std::string{Common::g_build_auto_update_api}; + std::string update_check_path = fmt::format("/repos/{}", std::string{Common::g_build_auto_update_repo}); try { if (include_prereleases) { // This can return either a prerelease or a stable release, // whichever is more recent. diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 9ec6b1d594..4b56f3794b 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -229,7 +229,7 @@ void EmuWindow_SDL2::WaitEvent() { const u32 current_time = SDL_GetTicks(); if (current_time > last_time + 2000) { const auto results = system.GetAndResetPerfStats(); - const auto title = fmt::format("Eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)", + const auto title = fmt::format("{} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc, diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 4b012fe134..32f365e0d0 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -90,7 +93,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste } SDL_GL_SetSwapInterval(0); - std::string window_title = fmt::format("Eden {} | {}-{}", Common::g_build_fullname, + std::string window_title = fmt::format("{} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), @@ -138,7 +141,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste OnResize(); OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); SDL_PumpEvents(); - LOG_INFO(Frontend, "Eden Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, + LOG_INFO(Frontend, "Build string: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); Settings::LogSettings(); } From 9a098441def2cfc4281ab1af6b2e8b34200800c0 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Wed, 1 Oct 2025 05:33:37 +0200 Subject: [PATCH 5/6] [audio_core] Fix audio issue in The Legend of Zelda - Echoes of Wisdom (#2594) This fixes the audio issue in The Legend of Zelda - Echoes of Wisdom on Windows. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2594 Reviewed-by: CamilleLaVey Co-authored-by: MaranBr Co-committed-by: MaranBr --- src/audio_core/renderer/behavior/info_updater.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index 3dae6069f7..48fe1f8975 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -162,6 +165,12 @@ Result InfoUpdater::UpdateEffectsVersion1(EffectContext& effect_context, const b reinterpret_cast(output), effect_count}; for (u32 i = 0; i < effect_count; i++) { +#ifdef _WIN32 + // There's a bug in Windows where using this effect causes extreme noise. So let's skip it. + if (in_params[i].type == EffectInfoBase::Type::Reverb) { + continue; + } +#endif auto effect_info{&effect_context.GetInfo(i)}; if (effect_info->GetType() != in_params[i].type) { effect_info->ForceUnmapBuffers(pool_mapper); @@ -209,6 +218,12 @@ Result InfoUpdater::UpdateEffectsVersion2(EffectContext& effect_context, const b reinterpret_cast(output), effect_count}; for (u32 i = 0; i < effect_count; i++) { +#ifdef _WIN32 + // There's a bug in Windows where using this effect causes extreme noise. So let's skip it. + if (in_params[i].type == EffectInfoBase::Type::Reverb) { + continue; + } +#endif auto effect_info{&effect_context.GetInfo(i)}; if (effect_info->GetType() != in_params[i].type) { effect_info->ForceUnmapBuffers(pool_mapper); From 986d4011203a50ab5db98d409e34f011a383f57a Mon Sep 17 00:00:00 2001 From: Calchan Date: Mon, 15 Sep 2025 10:53:37 -0600 Subject: [PATCH 6/6] Better domain blocking * Bring in the domain-blocking code from the legacy branch * Make blockedDomains a 'static constexpr const std::array' --- src/core/hle/service/sockets/sfdnsres.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index b07bd3e58e..da34b2e201 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -53,6 +53,16 @@ enum class NetDbError : s32 { NoData = 4, }; +static constexpr const std::array blockedDomains = {"srv.nintendo.net", "battle.net", + "microsoft.com", "mojang.com", + "xboxlive.com", "minecraftservices.com"}; + +static bool IsBlockedHost(const std::string& host) { + return std::any_of( + blockedDomains.begin(), blockedDomains.end(), + [&host](const std::string& domain) { return host.find(domain) != std::string::npos; }); +} + static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) { // These combinations have been verified on console (but are not // exhaustive). @@ -154,7 +164,7 @@ static std::pair GetHostByNameRequestImpl(HLERequestConte // For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions. // Prevent resolution of Nintendo servers - if (host.find("srv.nintendo.net") != std::string::npos) { + if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); return {0, GetAddrInfoError::AGAIN}; } @@ -271,7 +281,7 @@ static std::pair GetAddrInfoRequestImpl(HLERequestContext const std::string host = Common::StringFromBuffer(host_buffer); // Prevent resolution of Nintendo servers - if (host.find("srv.nintendo.net") != std::string::npos) { + if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); return {0, GetAddrInfoError::AGAIN}; } @@ -359,5 +369,4 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) { rb.Push(ResultSuccess); rb.Push(0); // bsd errno } - } // namespace Service::Sockets