Compare commits

..

35 commits

Author SHA1 Message Date
2ca36e1bd7
[doc] fix line endings and update macos
All checks were successful
eden-license / license-header (pull_request) Successful in 33s
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-09-07 19:16:06 -04:00
911ace690f
[cmake] CPMUtil: formatting, git_host, and more
I promise I'm a UI developer

- mbedtls can now be used as a system package
- zycore can now be used as a system package
- cleaned up dynarmic externals
- fixed libusb incorrectly showing as bundled
- add version/tag formatting to JSON
- add custom GIT_HOST option for packages
- moved some of my repos to my new git
- slightly better version identification
- combined VUL/VH since they are codependent (using my combo vendor)

This PR succeeds #383 since it includes it

Signed-off-by: crueter <crueter@eden-emu.dev>
2025-09-07 19:16:06 -04:00
9e313227be
oops
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-09-07 19:16:06 -04:00
1399f32cf3
[ci] update header script for cmake
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-09-07 19:16:06 -04:00
32024e4708
[cmake] chore: clean up linking, definitions, etc
general clean up of the currently very poorly organized linking/compile
def system. This is very incomplete and needs further work, but chances
are qt_common will mess with it so I will probably merge this into
qt_common.

Signed-off-by: crueter <crueter@eden-emu.dev>
2025-09-07 19:16:06 -04:00
da0823f46f
[cmake, doc] update freebsd docs & fix ext and bundled defaults
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-09-07 19:16:06 -04:00
48ee7afce1
[cmake] Fix FreeBSD building process again 2025-09-07 19:16:06 -04:00
f6e47c8c97
Fix license headers 2025-09-07 19:15:58 -04:00
8cb98b0c41
[breakpad] enable Solaris crash dumps
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-09-07 19:15:58 -04:00
2f82b63e6a
[user] prioritize 'user' directory if it exists (without needing a portable build) + docs (#338)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #338
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-08 00:57:08 +02:00
43c41e4db5
[compat] openbsd port fixes (#273)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #273
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-08 00:54:48 +02:00
10dd003d0f
[dynarmic, cmake] allow LTO build for dynarmic (#252)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #252
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-08 00:49:46 +02:00
37e0b80766
[hle] Added missing error codes and increased audio renderer revision (#390)
Co-authored-by: Jarrod Norwell <official.antique@gmail.com>

Fixes Animal Well

Co-authored-by: Gamer64 <76565986+Gamer64ytb@users.noreply.github.com>
Reviewed-on: #390
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Gamer64 <gamer64@eden-emu.dev>
Co-committed-by: Gamer64 <gamer64@eden-emu.dev>
2025-09-07 19:20:45 +02:00
718891d11f
[fs] temporarely disable nca verification (#298)
Some checks failed
eden-license / license-header (pull_request) Failing after 25s
This adds a passthrough to basically disable nca verification for newer NCAs, this fixes (tested) Pokemon 4.0.0 update and other newer SDK games and updates (as reported on the discord)

This is implemented as toggle that is default enabled, this needs proper implementation in the future.

Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #298
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Maufeat <sahyno1996@gmail.com>
Co-committed-by: Maufeat <sahyno1996@gmail.com>
2025-09-05 00:04:37 +02:00
bbcd8aded6
Revert "[heap_tracker] Use ankerl map instead of rb tree (#249)" (#382)
This reverts commit c9a3baab5d.

this commit caused issues in ender magnolia or something, need to make
sure I didn't mess up the revert

Reviewed-on: #382
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@outlook.com>
2025-09-04 16:04:42 +02:00
2bc792e211
[cmake] fix yuzu_cmd, bundled overrides (#381)
Fixes yuzu_cmd not linking to vma (just link to vma for now, but should
be linked to video_core maybe?)

also fixes the weird precedence of bundled packages esp w.r.t json where
an effectively garbage value was passed into the BUNDLED_PACKAGE
argument (was forced to on)

Signed-off-by: crueter <crueter@eden-emu.dev>

Reviewed-on: #381
2025-09-03 04:36:21 +02:00
e7560183fa
[android] minor ui tweaks + translations (#326)
CHANGES:
fix drawer pause/unpause sync (upon leaving/returning to app)
add quick toggle controller overlay to drawer (for players with multiple gear style)
added translation for emulation_hide_overlay
changed Show overlay to Show controller in all langs
added missing translations for values-de

WHAT TO TEST:
sync of pause/resume when you leave eden (screenshot, home, alt tab, etc).
show controller toggle: if it works it works.

Co-authored-by: Allison Cunha <allisonbzk@gmail.com>
Reviewed-on: #326
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2025-09-03 03:55:19 +02:00
84fadd1506
[cmake] fix unordered-dense deps (#380)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #380
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-02 03:25:27 +02:00
Bix
be7a3e1e86
[Hotfix] Update recommended driver from T21 to T22 (#379)
Help crueters workload.
Signed-off-by: Bix <bix@bixed.xyz>

Reviewed-on: #379
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Bix <bix@bixed.xyz>
Co-committed-by: Bix <bix@bixed.xyz>
2025-09-01 22:25:26 +02:00
6aa8be1da8
[cmake] fix gh dependencies (#377)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #377
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-01 21:14:54 +02:00
innix
e28b0d2590
[android]: Force app to use the displays max set refresh rate (#373)
Since Android 15, google automatically forces "games" to be 60 hrz. This ensures the display's max refresh rate is actually used. Tested on a Google Pixel 7 Pro with Android 16

Co-authored-by: innix <dev@innix.space>
Reviewed-on: #373
Co-committed-by: innix <dev@innix.space>
2025-09-01 14:18:30 +02:00
innix
6fcfe7f4f3
[macOS, compat] Allow games to boot in MacOS (#372)
This fixes the crashes on game launch caused by MacOS not being present in host_manager.cpp and enables primitiveRestart for MoltenVK to suppress a bunch of errors given in the log about  MoltenVK requiring primitiveRestart. Fixes an crash when switching kingdoms in Mario Odyssey as well

EDS is forced to 0, otherwise games do not show graphics

Note: For now only dynarmicc is working, performance will be slow
Reviewed-on: #372
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@outlook.com>
Co-authored-by: innix <dev@innix.space>
Co-committed-by: innix <dev@innix.space>
2025-09-01 09:23:03 +02:00
e60fd4b68b
[VMA] Phase 3:- Hand all allocation & binding to VMA (#362)
This patch completely removes the Custom Sub allocator with VMA and delegates everything to the VMA.
Overall, the patch integrates VMA and simplifies memory management.
Once these changes pass the testing, it will be used as a base for further improvement.
Note to testers, test for stability and performance.

Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #362
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@outlook.com>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-09-01 00:20:03 +02:00
10c76568b8
[common, fs] include missing header introduced on #330 (#370)
Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-on: #370
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-08-31 08:40:46 +02:00
8dba6a2cb4
[gpu/NVDRV] Finalize, improve AllocObjCtx (#333)
Improves object allocation per channel, only allowing max amount of 6 objects contexts per channel.
Previously objects were stored in a heap allocated vector which is sub-optimal for performance reasons.
The new implementation instead uses a stack based array with a O(1) approach.
This should boost performance in games which heavily rely on object context creation.

Co-authored-by: MaranBr <maranbr@outlook.com>
Reviewed-on: #333
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
2025-08-31 07:32:54 +02:00
4b5a8e0621
[cmake] changed app id from org.eden_emu.eden to dev.eden_emu.eden (#237)
it is better to match app id with website domain

Reviewed-on: #237
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Guo Yunhe <i@guoyunhe.me>
Co-committed-by: Guo Yunhe <i@guoyunhe.me>
2025-08-31 04:56:23 +02:00
39e27bc954
[android] fix intent-auto-driver-install (#369)
Resolving drivers based on the artifact name was too buggy and inconsistent, this PR improves it. Well, I like to think it does

Reviewed-on: #369
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: Producdevity <y.gherbi.dev@gmail.com>
Co-committed-by: Producdevity <y.gherbi.dev@gmail.com>
2025-08-31 03:33:54 +02:00
21c77bdcac
[cmake] fix ffmpeg libdrm on macos (#367)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #367
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2025-08-31 03:10:34 +02:00
1c3ca17cfb
[dynarmic] fix annoying gcc/clang error (#365)
caused qt creator to crash somehow geg

Signed-off-by: crueter <crueter@eden-emu.dev>

Reviewed-on: #365
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@outlook.com>
2025-08-31 00:12:06 +02:00
7ca197d900
[qt, compat] fix freedesktop stuffs on Solaris/OpenBSD (#360)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #360
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-30 23:08:04 +02:00
3b4c1beb0c
[desktop] only warn on firmware for qlaunch/games (#363)
- only warns about too new/missing for home menu
- only warns about missing for games that need it (mk8dx)

Signed-off-by: crueter <crueter@eden-emu.dev>

Reviewed-on: #363
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@outlook.com>
2025-08-30 20:32:28 +02:00
76de9d6c8c
[cmake, compat] fix solaris boost build once and for all (#364)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #364
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-30 20:32:21 +02:00
ab015bc730
[VK] Fix asserts with incorrect memory allocations (#357)
This fixes many assertions with incorrect memory allocations. Regression introduced in PR 334.

Co-authored-by: JPikachu <jpikachu.eden@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Reviewed-on: #357
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: JPikachu <jpikachu@eden-emu.dev>
Co-committed-by: JPikachu <jpikachu@eden-emu.dev>
2025-08-30 19:35:53 +02:00
f005f6a3ab
[compat] fix freebsd mmap virtual base (#354)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #354
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-30 17:03:56 +02:00
47b703067e
[settings] fix unreachable code warning in fastmem bool (#347)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #347
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-08-30 15:17:30 +02:00
146 changed files with 2801 additions and 1789 deletions

View file

@ -1,6 +1,7 @@
#!/bin/sh -e
HEADER="$(cat "$PWD/.ci/license/header.txt")"
HEADER_HASH="$(cat "$PWD/.ci/license/header-hash.txt")"
echo "Getting branch changes"
@ -13,41 +14,86 @@ FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
echo "Done"
check_header() {
CONTENT="`head -n3 < $1`"
case "$CONTENT" in
"$HEADER"*) ;;
*) BAD_FILES="$BAD_FILES $1" ;;
esac
}
check_cmake_header() {
CONTENT="`head -n3 < $1`"
case "$CONTENT" in
"$HEADER_HASH"*) ;;
*)
BAD_CMAKE="$BAD_CMAKE $1" ;;
esac
}
for file in $FILES; do
[ -f "$file" ] || continue
if [ `basename -- "$file"` = "CMakeLists.txt" ]; then
check_cmake_header "$file"
continue
fi
EXTENSION="${file##*.}"
case "$EXTENSION" in
kts|kt|cpp|h)
CONTENT="`cat $file`"
case "$CONTENT" in
"$HEADER"*) ;;
*) BAD_FILES="$BAD_FILES $file" ;;
esac
check_header "$file"
;;
cmake)
check_cmake_header "$file"
;;
esac
done
if [ "$BAD_FILES" = "" ]; then
if [ "$BAD_FILES" = "" ] && [ "$BAD_CMAKE" = "" ]; then
echo
echo "All good."
exit
fi
echo "The following files have incorrect license headers:"
if [ "$BAD_FILES" != "" ]; then
echo "The following source files have incorrect license headers:"
echo
for file in $BAD_FILES; do echo $file; done
cat << EOF
The following license header should be added to the start of all offending files:
The following license header should be added to the start of all offending SOURCE files:
=== BEGIN ===
$HEADER
=== END ===
EOF
fi
if [ "$BAD_CMAKE" != "" ]; then
echo "The following CMake files have incorrect license headers:"
echo
for file in $BAD_CMAKE; do echo $file; done
cat << EOF
The following license header should be added to the start of all offending CMake files:
=== BEGIN ===
$HEADER_HASH
=== END ===
EOF
fi
cat << EOF
If some of the code in this PR is not being contributed by the original author,
the files which have been exclusively changed by that code can be ignored.
If this happens, this PR requirement can be bypassed once all other files are addressed.
@ -70,6 +116,17 @@ if [ "$FIX" = "true" ]; then
git add $file
done
for file in $BAD_CMAKE; do
cat $file > $file.bak
cat .ci/license/header-hash.txt > $file
echo >> $file
cat $file.bak >> $file
rm $file.bak
git add $file
done
echo "License headers fixed."
if [ "$COMMIT" = "true" ]; then

View file

@ -0,0 +1,2 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later

View file

@ -104,6 +104,7 @@ cmake .. -G Ninja \
-DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \
-DYUZU_USE_FASTER_LD=ON \
-DYUZU_ENABLE_LTO=ON \
-DDYNARMIC_ENABLE_LTO=ON \
"${EXTRA_CMAKE_FLAGS[@]}"
ninja -j${NPROC}

View file

@ -1,6 +1,6 @@
AppRun
eden.desktop
org.eden_emu.eden.desktop
dev.eden_emu.eden.desktop
shared/bin/eden
shared/lib/lib.path
shared/lib/ld-linux-x86-64.so.2

View file

@ -59,15 +59,15 @@ VERSION="$(echo "$EDEN_TAG")"
mkdir -p ./AppDir
cd ./AppDir
cp ../dist/org.eden_emu.eden.desktop .
cp ../dist/org.eden_emu.eden.svg .
cp ../dist/dev.eden_emu.eden.desktop .
cp ../dist/dev.eden_emu.eden.svg .
ln -sf ./org.eden_emu.eden.svg ./.DirIcon
ln -sf ./dev.eden_emu.eden.svg ./.DirIcon
UPINFO='gh-releases-zsync|eden-emulator|Releases|latest|*.AppImage.zsync'
if [ "$DEVEL" = 'true' ]; then
sed -i 's|Name=Eden|Name=Eden Nightly|' ./org.eden_emu.eden.desktop
sed -i 's|Name=Eden|Name=Eden Nightly|' ./dev.eden_emu.eden.desktop
UPINFO="$(echo "$UPINFO" | sed 's|Releases|nightly|')"
fi

View file

@ -6,7 +6,7 @@
which png2icns || [ which yay && yay libicns ] || exit
which magick || exit
export EDEN_SVG_ICO="dist/org.eden_emu.eden.svg"
export EDEN_SVG_ICO="dist/dev.eden_emu.eden.svg"
svgo --multipass $EDEN_SVG_ICO
magick -density 256x256 -background transparent $EDEN_SVG_ICO \

View file

@ -52,6 +52,7 @@ cmake .. -G Ninja \
-DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \
-DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \
-DYUZU_ENABLE_LTO=ON \
-DDYNARMIC_ENABLE_LTO=ON \
"${EXTRA_CMAKE_FLAGS[@]}"
ninja

View file

@ -0,0 +1,22 @@
From e59d30b7b12e1d04cc2fc9c6219e35bda447c17e Mon Sep 17 00:00:00 2001
From: Lizzie <159065448+Lizzie841@users.noreply.github.com>
Date: Fri, 16 May 2025 04:12:13 +0100
Subject: [PATCH] Update CMakeLists.txt
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b5f4c4f..c5c6f31 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@ target_include_directories(
target_compile_features(unordered_dense INTERFACE cxx_std_17)
-if(_unordered_dense_is_toplevel_project)
+if(_unordered_dense_is_toplevel_project OR UNORDERED_DENSE_INSTALL)
# locations are provided by GNUInstallDirs
install(
TARGETS unordered_dense

View file

@ -48,10 +48,10 @@ endif()
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
CMAKE_DEPENDENT_OPTION(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF)
set(EXT_DEFAULT ON)
if (PLATFORM_FREEBSD)
set(EXT_DEFAULT OFF)
if (MSVC OR ANDROID)
set(EXT_DEFAULT ON)
endif()
CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ${EXT_DEFAULT} "ENABLE_SDL2;NOT MSVC" OFF)
@ -67,14 +67,13 @@ option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
option(YUZU_USE_CPM "Use CPM to fetch Eden dependencies if needed" ON)
option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched." ${EXT_DEFAULT})
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF)
option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan Utility Headers from externals" ${EXT_DEFAULT})
option(YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS "Use SPIRV-Tools from externals" ${EXT_DEFAULT})
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
@ -93,10 +92,12 @@ option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ${EXT_DEFAULT})
# TODO(crueter): CI this?
option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON)
option(FORCE_DOWNLOAD_WIN_BUNDLES "Forcefully download bundled Windows dependencies (useful for CI)" OFF)
# TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system
if (YUZU_USE_CPM AND ENABLE_SDL2)
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}")
endif()
@ -105,18 +106,14 @@ CMAKE_DEPENDENT_OPTION(YUZU_ROOM "Enable dedicated room functionality" ON "NOT A
CMAKE_DEPENDENT_OPTION(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROID" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_CMD "Compile the eden-cli executable" ON "ENABLE_SDL2;NOT ANDROID" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF)
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ${EXT_DEFAULT})
option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF)
option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" ON)
option(YUZU_ENABLE_PORTABLE "Allow yuzu to enable portable mode if a user folder is found in the CWD" ON)
CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "NOT WIN32" OFF)
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead of the bundled one)" OFF "APPLE" OFF)
@ -194,53 +191,6 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/hooks/pre-commit AND NOT EXISTS ${PROJECT_SOURCE
endif()
endif()
# Sanity check : Check that all submodules are present
# =======================================================================
function(check_submodules_present)
file(READ "${PROJECT_SOURCE_DIR}/.gitmodules" gitmodules)
string(REGEX MATCHALL "path *= *[^ \t\r\n]*" gitmodules ${gitmodules})
foreach(module ${gitmodules})
string(REGEX REPLACE "path *= *" "" module ${module})
file(GLOB RESULT "${PROJECT_SOURCE_DIR}/${module}/*")
list(LENGTH RESULT RES_LEN)
if(RES_LEN EQUAL 0)
message(FATAL_ERROR "Git submodule ${module} not found. "
"Please run: \ngit submodule update --init --recursive")
endif()
if (EXISTS "${PROJECT_SOURCE_DIR}/${module}/.git")
set(SUBMODULE_DIR "${PROJECT_SOURCE_DIR}/${module}")
execute_process(
COMMAND git rev-parse --short=10 HEAD
WORKING_DIRECTORY ${SUBMODULE_DIR}
OUTPUT_VARIABLE SUBMODULE_SHA
)
# would probably be better to do string parsing, but whatever
execute_process(
COMMAND git remote get-url origin
WORKING_DIRECTORY ${SUBMODULE_DIR}
OUTPUT_VARIABLE SUBMODULE_URL
)
string(REGEX REPLACE "\n|\r" "" SUBMODULE_SHA ${SUBMODULE_SHA})
string(REGEX REPLACE "\n|\r|\\.git" "" SUBMODULE_URL ${SUBMODULE_URL})
get_filename_component(SUBMODULE_NAME ${SUBMODULE_DIR} NAME)
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_NAMES ${SUBMODULE_NAME})
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS ${SUBMODULE_SHA})
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_URLS ${SUBMODULE_URL})
endif()
endforeach()
endfunction()
if(EXISTS ${PROJECT_SOURCE_DIR}/.gitmodules AND YUZU_CHECK_SUBMODULES)
check_submodules_present()
endif()
configure_file(${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
COPYONLY)
@ -277,7 +227,7 @@ function(detect_architecture symbol arch)
if (ARCHITECTURE_${arch})
set(ARCHITECTURE "${arch}" PARENT_SCOPE)
set(ARCHITECTURE_${arch} 1 PARENT_SCOPE)
add_definitions(-DARCHITECTURE_${arch}=1)
add_compile_definitions(ARCHITECTURE_${arch}=1)
endif()
endif()
endfunction()
@ -299,7 +249,7 @@ endif()
if (NOT DEFINED ARCHITECTURE)
set(ARCHITECTURE "GENERIC")
set(ARCHITECTURE_GENERIC 1)
add_definitions(-DARCHITECTURE_GENERIC=1)
add_compile_definitions(ARCHITECTURE_GENERIC=1)
endif()
message(STATUS "Target architecture: ${ARCHITECTURE}")
@ -311,16 +261,16 @@ if (MSVC AND ARCHITECTURE_x86)
endif()
if (UNIX)
add_definitions(-DYUZU_UNIX=1)
add_compile_definitions(YUZU_UNIX=1)
endif()
if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX))
set(HAS_NCE 1)
add_definitions(-DHAS_NCE=1)
add_compile_definitions(HAS_NCE=1)
endif()
if (YUZU_ROOM)
add_definitions(-DYUZU_ROOM)
add_compile_definitions(YUZU_ROOM)
endif()
# Build/optimization presets
@ -406,8 +356,10 @@ if (YUZU_USE_CPM)
if (NOT MSVC)
# boost sucks
if (NOT PLATFORM_LINUX AND NOT ANDROID)
target_compile_definitions(boost_container INTERFACE BOOST_HAS_PTHREADS)
# Solaris (and probably other NIXes) need explicit pthread definition
if (PLATFORM_SUN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthreads")
endif()
target_compile_options(boost_heap INTERFACE -Wno-shadow)
@ -599,7 +551,6 @@ endfunction()
add_subdirectory(externals)
# pass targets from externals
find_package(VulkanHeaders)
find_package(VulkanUtilityLibraries)
find_package(VulkanMemoryAllocator)
find_package(SPIRV-Tools)
@ -734,7 +685,7 @@ if (APPLE)
list(APPEND PLATFORM_LIBRARIES ${ICONV_LIBRARY})
elseif (WIN32)
# Target Windows 10
add_definitions(-D_WIN32_WINNT=0x0A00 -DWINVER=0x0A00)
add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00)
set(PLATFORM_LIBRARIES winmm ws2_32 iphlpapi)
if (MINGW)
# PSAPI is the Process Status API
@ -856,14 +807,14 @@ endif()
# https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html
# https://www.freedesktop.org/software/appstream/docs/
if(ENABLE_QT AND UNIX AND NOT APPLE)
install(FILES "dist/org.eden_emu.eden.desktop"
install(FILES "dist/dev.eden_emu.eden.desktop"
DESTINATION "share/applications")
install(FILES "dist/org.eden_emu.eden.svg"
install(FILES "dist/dev.eden_emu.eden.svg"
DESTINATION "share/icons/hicolor/scalable/apps")
# TODO: these files need to be updated.
install(FILES "dist/org.eden_emu.eden.xml"
install(FILES "dist/dev.eden_emu.eden.xml"
DESTINATION "share/mime/packages")
install(FILES "dist/org.eden_emu.eden.metainfo.xml"
install(FILES "dist/dev.eden_emu.eden.metainfo.xml"
DESTINATION "share/metainfo")
endif()

View file

@ -11,10 +11,11 @@
# Future crueter: Wow this was a lie and a half, at this point I might as well make my own CPN
# haha just kidding... unless?
# TODO(crueter): Remember to get more than 6 hours of sleep whenever making giant cmake changes
if (MSVC OR ANDROID)
set(BUNDLED_DEFAULT OFF)
else()
set(BUNDLED_DEFAULT ON)
else()
set(BUNDLED_DEFAULT OFF)
endif()
option(CPMUTIL_FORCE_BUNDLED
@ -148,11 +149,32 @@ function(AddJsonPackage)
get_json_element("${object}" tag tag "")
get_json_element("${object}" artifact artifact "")
get_json_element("${object}" git_version git_version "")
get_json_element("${object}" git_host git_host "")
get_json_element("${object}" source_subdir source_subdir "")
get_json_element("${object}" bundled bundled "unset")
get_json_element("${object}" find_args find_args "")
get_json_element("${object}" raw_patches patches "")
# okay here comes the fun part: REPLACEMENTS!
# first: tag gets %VERSION% replaced if applicable, with either git_version (preferred) or version
# second: artifact gets %VERSION% and %TAG% replaced accordingly (same rules for VERSION)
if (git_version)
set(version_replace ${git_version})
else()
set(version_replace ${version})
endif()
# TODO(crueter): fmt module for cmake
if (tag)
string(REPLACE "%VERSION%" "${version_replace}" tag ${tag})
endif()
if (artifact)
string(REPLACE "%VERSION%" "${version_replace}" artifact ${artifact})
string(REPLACE "%TAG%" "${tag}" artifact ${artifact})
endif()
# format patchdir
if (raw_patches)
math(EXPR range "${raw_patches_LENGTH} - 1")
@ -184,8 +206,6 @@ function(AddJsonPackage)
# system/bundled
if (bundled STREQUAL "unset" AND DEFINED JSON_BUNDLED_PACKAGE)
set(bundled ${JSON_BUNDLED_PACKAGE})
else()
set(bundled ON)
endif()
AddPackage(
@ -203,6 +223,8 @@ function(AddJsonPackage)
SOURCE_SUBDIR "${source_subdir}"
GIT_VERSION ${git_version}
GIT_HOST ${git_host}
ARTIFACT ${artifact}
TAG ${tag}
)
@ -242,6 +264,7 @@ function(AddPackage)
NAME
VERSION
GIT_VERSION
GIT_HOST
REPO
TAG
@ -259,6 +282,7 @@ function(AddPackage)
KEY
BUNDLED_PACKAGE
FIND_PACKAGE_ARGUMENTS
)
set(multiValueArgs OPTIONS PATCHES)
@ -273,11 +297,17 @@ function(AddPackage)
option(${PKG_ARGS_NAME}_FORCE_SYSTEM "Force the system package for ${PKG_ARGS_NAME}")
option(${PKG_ARGS_NAME}_FORCE_BUNDLED "Force the bundled package for ${PKG_ARGS_NAME}")
if (NOT DEFINED PKG_ARGS_GIT_HOST)
set(git_host github.com)
else()
set(git_host ${PKG_ARGS_GIT_HOST})
endif()
if (DEFINED PKG_ARGS_URL)
set(pkg_url ${PKG_ARGS_URL})
if (DEFINED PKG_ARGS_REPO)
set(pkg_git_url https://github.com/${PKG_ARGS_REPO})
set(pkg_git_url https://${git_host}/${PKG_ARGS_REPO})
else()
if (DEFINED PKG_ARGS_GIT_URL)
set(pkg_git_url ${PKG_ARGS_GIT_URL})
@ -286,7 +316,7 @@ function(AddPackage)
endif()
endif()
elseif (DEFINED PKG_ARGS_REPO)
set(pkg_git_url https://github.com/${PKG_ARGS_REPO})
set(pkg_git_url https://${git_host}/${PKG_ARGS_REPO})
if (DEFINED PKG_ARGS_TAG)
set(pkg_key ${PKG_ARGS_TAG})
@ -317,25 +347,23 @@ function(AddPackage)
cpm_utils_message(STATUS ${PKG_ARGS_NAME} "Download URL is ${pkg_url}")
if (DEFINED PKG_ARGS_GIT_VERSION)
set(git_version ${PKG_ARGS_GIT_VERSION})
elseif(DEFINED PKG_ARGS_VERSION)
set(git_version ${PKG_ARGS_VERSION})
endif()
if (NOT DEFINED PKG_ARGS_KEY)
if (DEFINED PKG_ARGS_SHA)
string(SUBSTRING ${PKG_ARGS_SHA} 0 4 pkg_key)
cpm_utils_message(DEBUG ${PKG_ARGS_NAME}
"No custom key defined, using ${pkg_key} from sha")
elseif (DEFINED git_version)
set(pkg_key ${git_version})
elseif(DEFINED PKG_ARGS_GIT_VERSION)
set(pkg_key ${PKG_ARGS_GIT_VERSION})
cpm_utils_message(DEBUG ${PKG_ARGS_NAME}
"No custom key defined, using ${pkg_key}")
elseif (DEFINED PKG_ARGS_TAG)
set(pkg_key ${PKG_ARGS_TAG})
cpm_utils_message(DEBUG ${PKG_ARGS_NAME}
"No custom key defined, using ${pkg_key}")
elseif (DEFINED PKG_ARGS_VERSION)
set(pkg_key ${PKG_ARGS_VERSION})
cpm_utils_message(DEBUG ${PKG_ARGS_NAME}
"No custom key defined, using ${pkg_key}")
else()
cpm_utils_message(WARNING ${PKG_ARGS_NAME}
"Could not determine cache key, using CPM defaults")
@ -409,9 +437,9 @@ function(AddPackage)
set_precedence(OFF OFF)
elseif (CPMUTIL_FORCE_SYSTEM)
set_precedence(ON ON)
elseif(NOT CPMUTIL_FORCE_BUNDLED)
elseif(CPMUTIL_FORCE_BUNDLED)
set_precedence(OFF OFF)
elseif (DEFINED PKG_ARGS_BUNDLED_PACKAGE)
elseif (DEFINED PKG_ARGS_BUNDLED_PACKAGE AND NOT PKG_ARGS_BUNDLED_PACKAGE STREQUAL "unset")
if (PKG_ARGS_BUNDLED_PACKAGE)
set(local OFF)
else()
@ -446,12 +474,15 @@ function(AddPackage)
if (DEFINED PKG_ARGS_SHA)
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS
${PKG_ARGS_SHA})
elseif(DEFINED git_version)
elseif (DEFINED PKG_ARGS_GIT_VERSION)
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS
${git_version})
${PKG_ARGS_GIT_VERSION})
elseif (DEFINED PKG_ARGS_TAG)
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS
${PKG_ARGS_TAG})
elseif(DEFINED PKG_ARGS_VERSION)
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS
${PKG_ARGS_VERSION})
else()
cpm_utils_message(WARNING ${PKG_ARGS_NAME}
"Package has no specified sha, tag, or version")
@ -496,6 +527,7 @@ function(add_ci_package key)
set(ARTIFACT_DIR ${${ARTIFACT_PACKAGE}_SOURCE_DIR} PARENT_SCOPE)
endfunction()
# TODO(crueter): we could do an AddMultiArchPackage, multiplatformpackage?
# name is the artifact name, package is for find_package override
function(AddCIPackage)
set(oneValueArgs

View file

@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
include(FindPackageHandleStandardArgs)
find_package(PkgConfig QUIET)
pkg_search_module(mbedtls QUIET IMPORTED_TARGET mbedtls)
find_package_handle_standard_args(mbedtls
REQUIRED_VARS mbedtls_LINK_LIBRARIES
VERSION_VAR mbedtls_VERSION
)
pkg_search_module(mbedcrypto QUIET IMPORTED_TARGET mbedcrypto)
find_package_handle_standard_args(mbedcrypto
REQUIRED_VARS mbedcrypto_LINK_LIBRARIES
VERSION_VAR mbedcrypto_VERSION
)

View file

@ -63,6 +63,7 @@ If you would like to contribute, we are open to new developers and pull requests
* **Solaris**: [Solaris Building Guide](./docs/build/Solaris.md)
* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md)
* **macOS**: [macOS Building Guide](./docs/build/macOS.md)
* **OpenBSD**: [OpenBSD Building Guide](./docs/build/OpenBSD.md)
## Download

View file

@ -10,8 +10,8 @@
"boost": {
"package": "Boost",
"repo": "boostorg/boost",
"tag": "boost-1.88.0",
"artifact": "boost-1.88.0-cmake.7z",
"tag": "boost-%VERSION%",
"artifact": "%TAG%-cmake.7z",
"hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01",
"git_version": "1.88.0",
"version": "1.57"

View file

@ -10,7 +10,7 @@ Type=Application
Name=Eden
GenericName=Switch Emulator
Comment=Nintendo Switch video game console emulator
Icon=org.eden_emu.eden
Icon=dev.eden_emu.eden
TryExec=eden
Exec=eden %f
Categories=Game;Emulator;Qt;

View file

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Before After
Before After

View file

@ -23,7 +23,7 @@ CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful u
- `NAME` (required): The package name (must be the same as the `find_package` name if applicable)
- `VERSION`: The minimum version of this package that can be used on the system
- `GIT_VERSION`: The version found within git, only used for identification
- `GIT_VERSION`: The "version" found within git
- `URL`: The URL to fetch.
- `REPO`: The GitHub repo to use (`owner/repo`).
* Only GitHub is supported for now, though other platforms will see support at some point
@ -71,8 +71,9 @@ Hashing strategies, descending order of precedence:
- `KEY`: Custom cache key to use (stored as `.cache/cpm/${packagename_lower}/${key}`)
* Default is based on, in descending order of precedence:
- First 4 characters of the sha
- `GIT_VERSION`, or `VERSION` if not specified
- `GIT_VERSION`
- Tag
- `VERSION`
- Otherwise, CPM defaults will be used. This is not recommended as it doesn't produce reproducible caches
- `DOWNLOAD_ONLY`: Whether or not to configure the downloaded package via CMake
* Useful to turn `OFF` if the project doesn't use CMake

View file

@ -6,6 +6,7 @@
* **Solaris**: [Solaris Building Guide](./build/Solaris.md)
* **FreeBSD**: [FreeBSD Building Guide](./build/FreeBSD.md)
* **macOS**: [macOS Building Guide](./build/macOS.md)
* **OpenBSD**: [OpenBSD Building Guide](./build/OpenBSD.md)
# CPM

11
docs/User.md Normal file
View file

@ -0,0 +1,11 @@
# User configuration
## Configuration directories
Eden will store configuration in the following directories:
- **Windows**: `%AppData%\Roaming`.
- **Android**: Data is stored internally.
- **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`.
If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use that instead.

12
docs/build/FreeBSD.md vendored
View file

@ -1,13 +1,7 @@
## One word of caution before proceeding.
This is not the usual or preferred way to build programs on FreeBSD.
As of writing there is no official fresh port available for Eden, but it is in the works.
After it is available you can find a link to the eden-emu fresh port here and on Escary's github repo.
See this build as an AppImage alternative for FreeBSD.
Eden is not currently available as a port on FreeBSD, though it is in the works. For now, the recommended method of usage is to compile it yourself. Check back often, as the build process frequently changes.
## Dependencies.
Before we start we need some dependencies.
These dependencies are generally needed to build Eden on FreeBSD.
Eden needs the following dependencies:
```
devel/cmake
@ -22,6 +16,8 @@ devel/autoconf
devel/pkgconf
devel/qt6-base
net/enet
multimedia/ffnvcodec-headers
multimedia/ffmpeg

10
docs/build/OpenBSD.md vendored Normal file
View file

@ -0,0 +1,10 @@
# Building for OpenBSD
```sh
pkg_add -u
pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq
git --recursive https://git.eden-emu.dev/eden-emu/eden
cmake -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DDYNARMIC_USE_PRECOMPILED_HEADERS=OFF -DCMAKE_BUILD_TYPE=Debug -DENABLE_QT=OFF -DENABLE_OPENSSL=OFF -DENABLE_WEB_SERVICE=OFF -B /usr/obj/eden
```
- Modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`.

65
docs/build/macOS.md vendored
View file

@ -1,43 +1,36 @@
Please note this article is intended for development, and eden on macOS is not currently ready for regular use.
Please note this article is intended for development, and Eden on macOS is not currently ready for regular use.
This article was written for developers. eden support for macOS is not ready for casual use.
## Method I: ninja
---
If you are compiling on Intel Mac or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` to `/usr/local`.
This article was written for developers. Eden support for macOS is not ready for casual use.
## Dependencies
Install dependencies from Homebrew:
```sh
brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zlib zstd cmake Catch2 molten-vk vulkan-loader
brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools
```
Clone the repo
If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`.
Now, clone the repo:
```sh
git clone --recursive https://git.eden-emu.dev/eden-emu/eden
cd eden
```
## Method I: ninja
---
Build for release
```sh
mkdir build && cd build
export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake"
export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib
cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON
cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON
ninja
```
You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..`
Build with debug symbols (vcpkg is not currently used due to broken boost-context library):
You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON`
```sh
mkdir build && cd build
export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake"
cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
ninja
```
@ -49,40 +42,20 @@ bin/eden.app/Contents/MacOS/eden
## Method II: Xcode
---
If you are compiling on Intel Mac or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` to `/usr/local`.
Install dependencies from Homebrew:
```sh
brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zlib zstd cmake Catch2 molten-vk vulkan-loader
```
Clone the repo
```sh
git clone --recursive https://git.eden-emu.dev/eden-emu/eden
cd eden
```
Build for release
```sh
mkdir build && cd build
export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake"
export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib
cmake .. -GXcode -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON
xcodebuild build -project eden.xcodeproj -scheme "eden" -configuration "RelWithDebInfo"
# Only if having errors about Xcode 15.0
sudo /usr/bin/xcode-select --switch /Users/admin/Downloads/Xcode.ap
cmake -B build -GXcode -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON
xcodebuild build -project yuzu.xcodeproj -scheme "yuzu" -configuration "RelWithDebInfo"
```
You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..`
Build with debug symbols (vcpkg is not currently used due to broken boost-context library):
Build with debug symbols:
```sh
mkdir build && cd build
export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake"
cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
ninja
```

View file

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
@ -33,7 +36,7 @@ endif()
# Xbyak (also used by Dynarmic, so needs to be added first)
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
if (PLATFORM_SUN)
if (PLATFORM_SUN OR PLATFORM_OPENBSD)
AddJsonPackage(xbyak_sun)
else()
AddJsonPackage(xbyak)
@ -67,7 +70,43 @@ if (mbedtls_ADDED)
endif()
# libusb
# TODO(crueter): remove entirely, replace with cpm
if (ENABLE_LIBUSB AND NOT TARGET libusb::usb)
set(module externals/libusb)
file(GLOB RESULT "${PROJECT_SOURCE_DIR}/${module}/")
list(LENGTH RESULT RES_LEN)
if(RES_LEN EQUAL 0)
message(FATAL_ERROR "libusb not found. "
"Please run: \ngit submodule update --init")
endif()
if (EXISTS "${PROJECT_SOURCE_DIR}/${module}/.git")
set(SUBMODULE_DIR "${PROJECT_SOURCE_DIR}/${module}")
execute_process(
COMMAND git rev-parse --short=10 HEAD
WORKING_DIRECTORY ${SUBMODULE_DIR}
OUTPUT_VARIABLE SUBMODULE_SHA
)
# would probably be better to do string parsing, but whatever
execute_process(
COMMAND git remote get-url origin
WORKING_DIRECTORY ${SUBMODULE_DIR}
OUTPUT_VARIABLE SUBMODULE_URL
)
string(REGEX REPLACE "\n|\r" "" SUBMODULE_SHA ${SUBMODULE_SHA})
string(REGEX REPLACE "\n|\r|\\.git" "" SUBMODULE_URL ${SUBMODULE_URL})
get_filename_component(SUBMODULE_NAME ${SUBMODULE_DIR} NAME)
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_NAMES ${SUBMODULE_NAME})
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS ${SUBMODULE_SHA})
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_URLS ${SUBMODULE_URL})
endif()
add_subdirectory(libusb)
endif()
@ -96,15 +135,7 @@ if (ENABLE_WEB_SERVICE)
endif()
# unordered_dense
AddPackage(
NAME unordered_dense
REPO "Lizzie841/unordered_dense"
SHA e59d30b7b1
HASH 71eff7bd9ba4b9226967bacd56a8ff000946f8813167cb5664bb01e96fb79e4e220684d824fe9c59c4d1cc98c606f13aff05b7940a1ed8ab3c95d6974ee34fa0
FIND_PACKAGE_ARGUMENTS "CONFIG"
OPTIONS
"UNORDERED_DENSE_INSTALL OFF"
)
AddJsonPackage(unordered-dense)
# FFMpeg
if (YUZU_USE_BUNDLED_FFMPEG)
@ -115,21 +146,17 @@ if (YUZU_USE_BUNDLED_FFMPEG)
set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
endif()
# Vulkan-Headers
# TODO(crueter): Vk1.4 impl
# VulkanUtilityHeaders - pulls in headers and utility libs
AddJsonPackage(
NAME vulkan-headers
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_HEADERS}
)
# Vulkan-Utility-Libraries
AddJsonPackage(
NAME vulkan-utility-libraries
NAME vulkan-utility-headers
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES}
)
# small hack
if (NOT VulkanUtilityLibraries_ADDED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
endif()
# SPIRV Tools
AddJsonPackage(
NAME spirv-tools
@ -147,6 +174,10 @@ add_subdirectory(nx_tzdb)
# VMA
AddJsonPackage(vulkan-memory-allocator)
if (VulkanMemoryAllocator_ADDED AND MSVC)
target_compile_options(VulkanMemoryAllocator INTERFACE /wd4189)
endif()
if (NOT TARGET LLVM::Demangle)
add_library(demangle demangle/ItaniumDemangle.cpp)
target_include_directories(demangle PUBLIC ./demangle)
@ -243,7 +274,7 @@ if (YUZU_CRASH_DUMPS AND NOT TARGET libbreakpad_client)
file(GLOB_RECURSE LIBBREAKPAD_CLIENT_SOURCES ${breakpad_SOURCE_DIR}/src/client/mac/*.cc ${breakpad_SOURCE_DIR}/src/common/mac/*.cc)
list(APPEND LIBBREAKPAD_CLIENT_SOURCES ${breakpad_SOURCE_DIR}/src/common/mac/MachIPC.mm)
else()
target_compile_definitions(libbreakpad_client PUBLIC -DHAVE_A_OUT_H)
target_compile_definitions(libbreakpad_client PUBLIC HAVE_A_OUT_H)
file(GLOB_RECURSE LIBBREAKPAD_CLIENT_SOURCES ${breakpad_SOURCE_DIR}/src/client/linux/*.cc ${breakpad_SOURCE_DIR}/src/common/linux/*.cc)
endif()
list(APPEND LIBBREAKPAD_CLIENT_SOURCES ${LIBBREAKPAD_COMMON_SOURCES})

View file

@ -3,6 +3,7 @@
"repo": "Mbed-TLS/mbedtls",
"sha": "8c88150ca1",
"hash": "769ad1e94c570671071e1f2a5c0f1027e0bf6bcdd1a80ea8ac970f2c86bc45ce4e31aa88d6d8110fc1bed1de81c48bc624df1b38a26f8b340a44e109d784a966",
"find_args": "MODULE",
"patches": [
"0001-cmake-version.patch"
]
@ -42,18 +43,13 @@
"0002-missing-decl.patch"
]
},
"vulkan-headers": {
"package": "VulkanHeaders",
"version": "1.3.274",
"repo": "KhronosGroup/Vulkan-Headers",
"sha": "89268a6d17",
"hash": "3ab349f74298ba72cafb8561015690c0674d428a09fb91ccd3cd3daca83650d190d46d33fd97b0a8fd4223fe6df2bcabae89136fbbf7c0bfeb8776f9448304c8"
},
"vulkan-utility-libraries": {
"vulkan-utility-headers": {
"package": "VulkanUtilityLibraries",
"repo": "KhronosGroup/Vulkan-Utility-Libraries",
"sha": "df2e358152",
"hash": "3e468c3d9ff93f6d418d71e5527abe0a12c8c7ab5b0b52278bbbee4d02bb87e99073906729b727e0147242b7e3fd5dedf68b803f1878cb4c0e4f730bc2238d79"
"repo": "scripts/VulkanUtilityHeaders",
"tag": "1.4.326",
"artifact": "VulkanUtilityHeaders.tar.zst",
"git_host": "git.crueter.xyz",
"hash": "5924629755cb1605c4aa4eee20ef7957a9dd8d61e4df548be656d98054f2730c4109693c1bd35811f401f4705d2ccff9fc849be32b0d8480bc3f73541a5e0964"
},
"vulkan-memory-allocator": {
"package": "VulkanMemoryAllocator",
@ -74,14 +70,14 @@
},
"xbyak_sun": {
"package": "xbyak",
"repo": "Lizzie841/xbyak",
"sha": "51f507b0b3",
"hash": "4a29a3c2f97f7d5adf667a21a008be03c951fb6696b0d7ba27e7e4afa037bc76eb5e059bb84860e01baf741d4d3ac851b840cd54c99d038812fbe0f1fa6d38a4",
"repo": "herumi/xbyak",
"sha": "9bb219333a",
"hash": "303165d45c8c19387ec49d9fda7d7a4e0d86d4c0153898c23f25ce2d58ece567f44c0bbbfe348239b933edb6e1a1e34f4bc1c0ab3a285bee5da0e548879387b0",
"bundled": true
},
"xbyak": {
"package": "xbyak",
"repo": "Lizzie841/xbyak",
"repo": "herumi/xbyak",
"sha": "4e44f4614d",
"hash": "5824e92159e07fa36a774aedd3b3ef3541d0241371d522cffa4ab3e1f215fa5097b1b77865b47b2481376c704fa079875557ea463ca63d0a7fd6a8a20a589e70",
"bundled": true
@ -105,5 +101,18 @@
"sha": "2bc873e53c",
"hash": "02329058a7f9cf7d5039afaae5ab170d9f42f60f4c01e21eaf4f46073886922b057a9ae30eeac040b3ac182f51b9c1bfe9fe1050a2c9f6ce567a1a9a0ec2c768",
"bundled": true
},
"unordered-dense": {
"package": "unordered_dense",
"repo": "martinus/unordered_dense",
"sha": "73f3cbb237",
"hash": "c08c03063938339d61392b687562909c1a92615b6ef39ec8df19ea472aa6b6478e70d7d5e33d4a27b5d23f7806daf57fe1bacb8124c8a945c918c7663a9e8532",
"find_args": "CONFIG",
"options": [
"UNORDERED_DENSE_INSTALL OFF"
],
"patches": [
"0001-cmake.patch"
]
}
}

View file

@ -63,6 +63,7 @@ if (NOT WIN32 AND NOT ANDROID)
set(FFmpeg_HWACCEL_INCLUDE_DIRS)
set(FFmpeg_HWACCEL_LDFLAGS)
if (NOT APPLE)
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
if(PLATFORM_SUN)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
@ -77,6 +78,7 @@ if (NOT WIN32 AND NOT ANDROID)
endif()
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-libdrm)
endif()
if(LIBVA_FOUND)
find_package(X11 REQUIRED)

View file

@ -1,7 +1,10 @@
{
"tzdb": {
"package": "nx_tzdb",
"url": "https://github.com/crueter/tzdb_to_nx/releases/download/250725/250725.zip",
"repo": "misc/tzdb_to_nx",
"git_host": "git.crueter.xyz",
"artifact": "%VERSION%.zip",
"tag": "%VERSION%",
"hash": "8f60b4b29f285e39c0443f3d5572a73780f3dbfcfd5b35004451fadad77f3a215b2e2aa8d0fffe7e348e2a7b0660882b35228b6178dda8804a14ce44509fd2ca",
"version": "250725"
}

View file

@ -22,16 +22,16 @@ if (MSVC)
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
# Silence "deprecation" warnings
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE _SCL_SECURE_NO_WARNINGS)
# Avoid windows.h junk
add_definitions(-DNOMINMAX)
add_compile_definitions(NOMINMAX)
# Avoid windows.h from including some usually unused libs like winsocks.h, since this might cause some redefinition errors.
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_compile_definitions(WIN32_LEAN_AND_MEAN)
# Ensure that projects are built with Unicode support.
add_definitions(-DUNICODE -D_UNICODE)
add_compile_definitions(UNICODE _UNICODE)
# /W4 - Level 4 warnings
# /MP - Multi-threaded compilation
@ -169,15 +169,15 @@ else()
# glibc, which may default to 32 bits. glibc allows this to be configured
# by setting _FILE_OFFSET_BITS.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
add_definitions(-D_FILE_OFFSET_BITS=64)
add_compile_definitions(_FILE_OFFSET_BITS=64)
endif()
if (MINGW)
add_definitions(-DMINGW_HAS_SECURE_API)
add_compile_definitions(MINGW_HAS_SECURE_API)
add_compile_options("-msse4.1")
if (MINGW_STATIC_BUILD)
add_definitions(-DQT_STATICPLUGIN)
add_compile_definitions(QT_STATICPLUGIN)
add_compile_options("-static")
endif()
endif()

View file

@ -30,8 +30,8 @@ val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toIn
android {
namespace = "org.yuzu.yuzu_emu"
compileSdkVersion = "android-35"
ndkVersion = "26.1.10909125"
compileSdkVersion = "android-36"
ndkVersion = "28.2.13676358"
buildFeatures {
viewBinding = true
@ -173,12 +173,14 @@ android {
"-DENABLE_OPENSSL=ON",
"-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work
"-DYUZU_USE_CPM=ON",
"-DCPMUTIL_FORCE_BUNDLED=ON",
"-DYUZU_USE_BUNDLED_FFMPEG=ON",
"-DYUZU_ENABLE_LTO=ON",
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
"-DBUILD_TESTING=OFF",
"-DYUZU_TESTS=OFF",
"-DDYNARMIC_TESTS=OFF"
"-DDYNARMIC_TESTS=OFF",
"-DDYNARMIC_ENABLE_LTO=ON"
)
abiFilters("arm64-v8a")

View file

@ -36,6 +36,9 @@ import androidx.core.net.toUri
import androidx.core.content.edit
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.utils.NativeConfig
class GameAdapter(private val activity: AppCompatActivity) :
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
@ -229,6 +232,8 @@ class GameAdapter(private val activity: AppCompatActivity) :
binding.root.findNavController().navigate(action)
}
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
if (NativeLibrary.gameRequiresFirmware(game.programId) && !NativeLibrary.isFirmwareAvailable()) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.loader_requires_firmware)
@ -243,6 +248,23 @@ class GameAdapter(private val activity: AppCompatActivity) :
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
} else if (BooleanSetting.DISABLE_NCA_VERIFICATION.getBoolean(false) && !preferences.getBoolean(
Settings.PREF_HIDE_NCA_POPUP, false)) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.nca_verification_disabled)
.setMessage(activity.getString(R.string.nca_verification_disabled_description))
.setPositiveButton(android.R.string.ok) { _, _ ->
launch()
}
.setNeutralButton(R.string.dont_show_again) { _, _ ->
preferences.edit {
putBoolean(Settings.PREF_HIDE_NCA_POPUP, true)
}
launch()
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
} else {
launch()
}

View file

@ -35,6 +35,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_SAMPLE_SHADING("sample_shading"),
PICTURE_IN_PICTURE("picture_in_picture"),
USE_CUSTOM_RTC("custom_rtc_enabled"),
DISABLE_NCA_VERIFICATION("disable_nca_verification"),
BLACK_BACKGROUNDS("black_backgrounds"),
JOYSTICK_REL_CENTER("joystick_rel_center"),
DPAD_SLIDE("dpad_slide"),

View file

@ -37,6 +37,7 @@ object Settings {
const val PREF_SHOULD_SHOW_PRE_ALPHA_WARNING = "ShouldShowPreAlphaWarning"
const val PREF_SHOULD_SHOW_EDENS_VEIL_DIALOG = "ShouldShowEdensVeilDialog"
const val PREF_MEMORY_WARNING_SHOWN = "MemoryWarningShown"
const val PREF_HIDE_NCA_POPUP = "HideNCAVerificationPopup"
const val SECTION_STATS_OVERLAY = "Stats Overlay"
// Deprecated input overlay preference keys

View file

@ -297,7 +297,13 @@ abstract class SettingsItem(
descriptionId = R.string.use_custom_rtc_description
)
)
put(
SwitchSetting(
BooleanSetting.DISABLE_NCA_VERIFICATION,
titleId = R.string.disable_nca_verification,
descriptionId = R.string.disable_nca_verification_description
)
)
put(
StringInputSetting(
StringSetting.WEB_TOKEN,

View file

@ -210,6 +210,7 @@ class SettingsFragmentPresenter(
add(IntSetting.LANGUAGE_INDEX.key)
add(BooleanSetting.USE_CUSTOM_RTC.key)
add(LongSetting.CUSTOM_RTC.key)
add(BooleanSetting.DISABLE_NCA_VERIFICATION.key)
add(HeaderSetting(R.string.network))
add(StringSetting.WEB_TOKEN.key)

View file

@ -79,7 +79,7 @@ class DriverFetcherFragment : Fragment() {
IntRange(600, 639) to "Mr. Purple EOL-24.3.4",
IntRange(640, 699) to "Mr. Purple T19",
IntRange(700, 710) to "KIMCHI 25.2.0_r5",
IntRange(711, 799) to "Mr. Purple T21",
IntRange(711, 799) to "Mr. Purple T22",
IntRange(800, 899) to "GameHub Adreno 8xx",
IntRange(900, Int.MAX_VALUE) to "Unsupported"
)

View file

@ -509,6 +509,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
gpuModel = GpuDriverHelper.getGpuModel().toString()
fwVersion = NativeLibrary.firmwareVersion()
updateQuickOverlayMenuEntry(BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean())
binding.surfaceEmulation.holder.addCallback(this)
binding.doneControlConfig.setOnClickListener { stopConfiguringControls() }
@ -530,6 +532,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
binding.inGameMenu.requestFocus()
emulationViewModel.setDrawerOpen(true)
updateQuickOverlayMenuEntry(BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean())
}
override fun onDrawerClosed(drawerView: View) {
@ -571,25 +574,24 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
R.id.menu_pause_emulation -> {
if (emulationState.isPaused) {
emulationState.run(false)
it.title = resources.getString(R.string.emulation_pause)
it.icon = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_pause,
requireContext().theme
)
updatePauseMenuEntry(false)
} else {
emulationState.pause()
it.title = resources.getString(R.string.emulation_unpause)
it.icon = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_play,
requireContext().theme
)
updatePauseMenuEntry(true)
}
binding.inGameMenu.requestFocus()
true
}
R.id.menu_quick_overlay -> {
val newState = !BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()
BooleanSetting.SHOW_INPUT_OVERLAY.setBoolean(newState)
updateQuickOverlayMenuEntry(newState)
binding.surfaceInputOverlay.refreshControls()
NativeConfig.saveGlobalConfig()
true
}
R.id.menu_settings -> {
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
null,
@ -844,9 +846,50 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
private fun updateQuickOverlayMenuEntry(isVisible: Boolean) {
val menu = binding.inGameMenu.menu
val item = menu.findItem(R.id.menu_quick_overlay)
if (isVisible) {
item.title = getString(R.string.emulation_hide_overlay)
item.icon = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_controller_disconnected,
requireContext().theme
)
} else {
item.title = getString(R.string.emulation_show_overlay)
item.icon = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_controller,
requireContext().theme
)
}
}
private fun updatePauseMenuEntry(isPaused: Boolean) {
val menu = binding.inGameMenu.menu
val pauseItem = menu.findItem(R.id.menu_pause_emulation)
if (isPaused) {
pauseItem.title = getString(R.string.emulation_unpause)
pauseItem.icon = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_play,
requireContext().theme
)
} else {
pauseItem.title = getString(R.string.emulation_pause)
pauseItem.icon = ResourcesCompat.getDrawable(
resources,
R.drawable.ic_pause,
requireContext().theme
)
}
}
override fun onPause() {
if (emulationState.isRunning && emulationActivity?.isInPictureInPictureMode != true) {
emulationState.pause()
updatePauseMenuEntry(true)
}
super.onPause()
}
@ -869,6 +912,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
val socPosition = IntSetting.SOC_OVERLAY_POSITION.getInt()
updateSocPosition(socPosition)
binding.inGameMenu.post {
emulationState?.isPaused?.let { updatePauseMenuEntry(it) }
}
}
private fun resetInputOverlay() {
@ -1391,6 +1438,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
R.id.menu_show_overlay -> {
it.isChecked = !it.isChecked
BooleanSetting.SHOW_INPUT_OVERLAY.setBoolean(it.isChecked)
updateQuickOverlayMenuEntry(it.isChecked)
binding.surfaceInputOverlay.refreshControls()
true
}

View file

@ -31,9 +31,6 @@ class HomeViewModel : ViewModel() {
private val _checkKeys = MutableStateFlow(false)
val checkKeys = _checkKeys.asStateFlow()
private val _checkFirmware = MutableStateFlow(false)
val checkFirmware = _checkFirmware.asStateFlow()
var navigatedToSetup = false
fun setStatusBarShadeVisibility(visible: Boolean) {
@ -66,8 +63,4 @@ class HomeViewModel : ViewModel() {
fun setCheckKeys(value: Boolean) {
_checkKeys.value = value
}
fun setCheckFirmware(value: Boolean) {
_checkFirmware.value = value
}
}

View file

@ -38,6 +38,7 @@ import org.yuzu.yuzu_emu.model.DriverViewModel
import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.model.InstallResult
import android.os.Build
import org.yuzu.yuzu_emu.model.TaskState
import org.yuzu.yuzu_emu.model.TaskViewModel
import org.yuzu.yuzu_emu.utils.*
@ -47,6 +48,7 @@ import java.io.BufferedOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import androidx.core.content.edit
import kotlin.text.compareTo
class MainActivity : AppCompatActivity(), ThemeProvider {
private lateinit var binding: ActivityMainBinding
@ -110,6 +112,19 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
binding = ActivityMainBinding.inflate(layoutInflater)
// Since Android 15, google automatically forces "games" to be 60 hrz
// This ensures the display's max refresh rate is actually used
display?.let {
val supportedModes = it.supportedModes
val maxRefreshRate = supportedModes.maxByOrNull { mode -> mode.refreshRate }
if (maxRefreshRate != null) {
val layoutParams = window.attributes
layoutParams.preferredDisplayModeId = maxRefreshRate.modeId
window.attributes = layoutParams
}
}
setContentView(binding.root)
checkAndRequestBluetoothPermissions()
@ -127,16 +142,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
checkedDecryption = true
}
if (!checkedFirmware) {
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
if (!firstTimeSetup) {
checkFirmware()
showPreAlphaWarningDialog()
}
checkedFirmware = true
}
WindowCompat.setDecorFitsSystemWindows(window, false)
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
@ -183,13 +188,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
if (it) checkKeys()
}
homeViewModel.checkFirmware.collect(
this,
resetState = { homeViewModel.setCheckFirmware(false) }
) {
if (it) checkFirmware()
}
setInsets()
}
@ -228,21 +226,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
).show(supportFragmentManager, MessageDialogFragment.TAG)
}
}
private fun checkFirmware() {
val resultCode: Int = NativeLibrary.verifyFirmware()
if (resultCode == 0) return
val resultString: String =
resources.getStringArray(R.array.verifyFirmwareResults)[resultCode]
MessageDialogFragment.newInstance(
titleId = R.string.firmware_invalid,
descriptionString = resultString,
helpLinkId = R.string.firmware_missing_help
).show(supportFragmentManager, MessageDialogFragment.TAG)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(CHECKED_DECRYPTION, checkedDecryption)
@ -419,7 +402,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
cacheFirmwareDir.copyRecursively(firmwarePath, true)
NativeLibrary.initializeSystem(true)
homeViewModel.setCheckKeys(true)
homeViewModel.setCheckFirmware(true)
getString(R.string.save_file_imported_success)
}
} catch (e: Exception) {
@ -449,7 +431,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
// Optionally reinitialize the system or perform other necessary steps
NativeLibrary.initializeSystem(true)
homeViewModel.setCheckKeys(true)
homeViewModel.setCheckFirmware(true)
messageToShow = getString(R.string.firmware_uninstalled_success)
} else {
messageToShow = getString(R.string.firmware_uninstalled_failure)

View file

@ -124,11 +124,16 @@ object CustomSettingsHandler {
// Check for driver requirements if activity and driverViewModel are provided
if (activity != null && driverViewModel != null) {
val driverPath = extractDriverPath(customSettings)
if (driverPath != null) {
Log.info("[CustomSettingsHandler] Custom settings specify driver: $driverPath")
val rawDriverPath = extractDriverPath(customSettings)
if (rawDriverPath != null) {
// Normalize to local storage path (we only store drivers under driverStoragePath)
val driverFilename = rawDriverPath.substringAfterLast('/')
.substringAfterLast('\\')
val localDriverPath = "${GpuDriverHelper.driverStoragePath}$driverFilename"
Log.info("[CustomSettingsHandler] Custom settings specify driver: $rawDriverPath (normalized: $localDriverPath)")
// Check if driver exists in the driver storage
val driverFile = File(driverPath)
val driverFile = File(localDriverPath)
if (!driverFile.exists()) {
Log.info("[CustomSettingsHandler] Driver not found locally: ${driverFile.name}")
@ -182,7 +187,7 @@ object CustomSettingsHandler {
}
// Attempt to download and install the driver
val driverUri = DriverResolver.ensureDriverAvailable(driverPath, activity) { progress ->
val driverUri = DriverResolver.ensureDriverAvailable(driverFilename, activity) { progress ->
progressChannel.trySend(progress.toInt())
}
@ -209,12 +214,12 @@ object CustomSettingsHandler {
return null
}
// Verify the downloaded driver
val installedFile = File(driverPath)
// Verify the downloaded driver (from normalized local path)
val installedFile = File(localDriverPath)
val metadata = GpuDriverHelper.getMetadataFromZip(installedFile)
if (metadata.name == null) {
Log.error(
"[CustomSettingsHandler] Downloaded driver is invalid: $driverPath"
"[CustomSettingsHandler] Downloaded driver is invalid: $localDriverPath"
)
Toast.makeText(
activity,
@ -232,7 +237,7 @@ object CustomSettingsHandler {
}
// Add to driver list
driverViewModel.onDriverAdded(Pair(driverPath, metadata))
driverViewModel.onDriverAdded(Pair(localDriverPath, metadata))
Log.info(
"[CustomSettingsHandler] Successfully downloaded and installed driver: ${metadata.name}"
)
@ -268,7 +273,7 @@ object CustomSettingsHandler {
// Driver exists, verify it's valid
val metadata = GpuDriverHelper.getMetadataFromZip(driverFile)
if (metadata.name == null) {
Log.error("[CustomSettingsHandler] Invalid driver file: $driverPath")
Log.error("[CustomSettingsHandler] Invalid driver file: $localDriverPath")
Toast.makeText(
activity,
activity.getString(
@ -459,6 +464,8 @@ object CustomSettingsHandler {
if (inGpuDriverSection && trimmed.startsWith("driver_path=")) {
return trimmed.substringAfter("driver_path=")
.trim()
.removeSurrounding("\"", "\"")
}
}

View file

@ -68,6 +68,48 @@ object DriverResolver {
val filename: String
)
// Matching helpers
private val KNOWN_SUFFIXES = listOf(
".adpkg.zip",
".zip",
".7z",
".tar.gz",
".tar.xz",
".rar"
)
private fun stripKnownSuffixes(name: String): String {
var result = name
var changed: Boolean
do {
changed = false
for (s in KNOWN_SUFFIXES) {
if (result.endsWith(s, ignoreCase = true)) {
result = result.dropLast(s.length)
changed = true
}
}
} while (changed)
return result
}
private fun normalizeName(name: String): String {
val base = stripKnownSuffixes(name.lowercase())
// Remove non-alphanumerics to make substring checks resilient
return base.replace(Regex("[^a-z0-9]+"), " ").trim()
}
private fun tokenize(name: String): Set<String> =
normalizeName(name).split(Regex("\\s+")).filter { it.isNotBlank() }.toSet()
// Jaccard similarity between two sets
private fun jaccard(a: Set<String>, b: Set<String>): Double {
if (a.isEmpty() || b.isEmpty()) return 0.0
val inter = a.intersect(b).size.toDouble()
val uni = a.union(b).size.toDouble()
return if (uni == 0.0) 0.0 else inter / uni
}
/**
* Resolve a driver download URL from its filename
* @param filename The driver filename (e.g., "turnip_mrpurple-T19-toasted.adpkg.zip")
@ -98,7 +140,7 @@ object DriverResolver {
async {
searchRepository(repoPath, filename)
}
}.mapNotNull { it.await() }.firstOrNull().also { resolved ->
}.firstNotNullOfOrNull { it.await() }.also { resolved ->
// Cache the result if found
resolved?.let {
urlCache[filename] = it
@ -119,22 +161,56 @@ object DriverResolver {
releaseCache[repoPath] = it
}
// Search through all releases and artifacts
// First pass: exact name (case-insensitive) against asset filenames
val target = filename.lowercase()
for (release in releases) {
for (artifact in release.artifacts) {
if (artifact.name == filename) {
Log.info(
"[DriverResolver] Found $filename in $repoPath/${release.tagName}"
)
if (artifact.name.equals(filename, ignoreCase = true) || artifact.name.lowercase() == target) {
Log.info("[DriverResolver] Found $filename in $repoPath/${release.tagName}")
return@withContext ResolvedDriver(
downloadUrl = artifact.url.toString(),
repoPath = repoPath,
releaseTag = release.tagName,
filename = filename
filename = artifact.name
)
}
}
}
// Second pass: fuzzy match by asset filenames only
val reqNorm = normalizeName(filename)
val reqTokens = tokenize(filename)
var best: ResolvedDriver? = null
var bestScore = 0.0
for (release in releases) {
for (artifact in release.artifacts) {
val artNorm = normalizeName(artifact.name)
val artTokens = tokenize(artifact.name)
var score = jaccard(reqTokens, artTokens)
// Boost if one normalized name contains the other
if (artNorm.contains(reqNorm) || reqNorm.contains(artNorm)) {
score = maxOf(score, 0.92)
}
if (score > bestScore) {
bestScore = score
best = ResolvedDriver(
downloadUrl = artifact.url.toString(),
repoPath = repoPath,
releaseTag = release.tagName,
filename = artifact.name
)
}
}
}
// Threshold to avoid bad guesses, this worked fine in testing but might need tuning
if (best != null && bestScore >= 0.6) {
Log.info("[DriverResolver] Fuzzy matched $filename -> ${best.filename} in ${best.repoPath} (score=%.2f)".format(bestScore))
return@withContext best
}
null
} catch (e: Exception) {
Log.error("[DriverResolver] Failed to search $repoPath: ${e.message}")
@ -296,8 +372,8 @@ object DriverResolver {
context: Context,
onProgress: ((Float) -> Unit)? = null
): Uri? {
// Extract filename from path
val filename = driverPath.substringAfterLast('/')
// Extract filename from path (support both separators)
val filename = driverPath.substringAfterLast('/').substringAfterLast('\\')
// Check if driver already exists locally
val localPath = "${GpuDriverHelper.driverStoragePath}$filename"

View file

@ -17,7 +17,7 @@ add_library(yuzu-android SHARED
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common Vulkan::Headers)
target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common Vulkan::Headers GPUOpen::VulkanMemoryAllocator)
target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log)
if (ARCHITECTURE_arm64)
target_link_libraries(yuzu-android PRIVATE adrenotools)

View file

@ -596,6 +596,8 @@ jstring Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getGpuModel(JNIEnv *env, j
const std::string model_name{device.GetModelName()};
window.release();
return Common::Android::ToJString(env, model_name);
}

View file

@ -8,6 +8,11 @@
android:icon="@drawable/ic_pause"
android:title="@string/emulation_pause" />
<item
android:id="@+id/menu_quick_overlay"
android:icon="@drawable/ic_controller"
android:title="@string/emulation_show_overlay"/>
<item
android:id="@+id/menu_settings"
android:icon="@drawable/ic_settings"

View file

@ -498,6 +498,8 @@
<string name="use_custom_rtc">ساعة مخصصة في الوقت الحقيقي</string>
<string name="use_custom_rtc_description">يسمح لك بتعيين ساعة مخصصة في الوقت الفعلي منفصلة عن وقت النظام الحالي لديك</string>
<string name="set_custom_rtc">تعيين ساعة مخصصة في الوقت الحقيقي</string>
<string name="disable_nca_verification">تعطيل التحقق من NCA</string>
<string name="disable_nca_verification_description">يعطل التحقق من سلامة أرشيفات محتوى NCA. قد يحسن هذا من سرعة التحميل لكنه يخاطر بتلف البيانات أو تمرير ملفات غير صالحة دون اكتشاف. ضروري لجعل الألعاب والتحديثات التي تتطلب نظامًا أساسيًا 20+ تعمل.</string>
<!-- Network settings strings -->
<string name="generate">توليد</string>
@ -733,7 +735,8 @@
<string name="emulation_rel_stick_center">مركز العصا النسبي</string>
<string name="emulation_dpad_slide">مزلاق الأسهم</string>
<string name="emulation_haptics">الاهتزازات الديناميكية</string>
<string name="emulation_show_overlay">عرض التراكب</string>
<string name="emulation_show_overlay">إظهار وحدة التحكم</string>
<string name="emulation_hide_overlay">إخفاء وحدة التحكم</string>
<string name="emulation_toggle_all">الكل</string>
<string name="emulation_control_adjust">ضبط التراكب</string>
<string name="emulation_control_scale">الحجم</string>

View file

@ -482,6 +482,8 @@
<string name="use_custom_rtc">RTCی تایبەتمەند</string>
<string name="use_custom_rtc_description">ڕێگەت پێدەدات کاتژمێرێکی کاتی ڕاستەقینەی تایبەتمەند دابنێیت کە جیاوازە لە کاتی ئێستای سیستەمەکەت.</string>
<string name="set_custom_rtc">دانانی RTCی تایبەتمەند</string>
<string name="disable_nca_verification">ناچالاککردنی پشکنینی NCA</string>
<string name="disable_nca_verification_description">پشکنینی پێکهاتەی ئارشیڤەکانی ناوەڕۆکی NCA ناچالاک دەکات. ئەمە لەوانەیە خێرایی بارکردن به‌ره‌وپێش ببات، بەڵام مەترسی لەناوچوونی داتا یان ئەوەی فایلە نادروستەکان بەبێ ئەوەی دۆزرایەوە تێپەڕبن زیاتر دەکات. بۆ ئەوەی یاری و نوێکردنەوەکان کار بکەن کە پێویستی بە فریموێری 20+ هەیە زۆر پێویستە.</string>
<!-- Network settings strings -->
<string name="generate">بەرهەم هێنان</string>
@ -710,7 +712,8 @@
<string name="emulation_rel_stick_center">ناوەندی گێڕ بەنزیکەیی</string>
<string name="emulation_dpad_slide">خلیسکانی 4 دوگمەکە</string>
<string name="emulation_haptics">لەرینەوەی پەنجەلێدان</string>
<string name="emulation_show_overlay">نیشاندانی داپۆشەر</string>
<string name="emulation_show_overlay">نیشاندانی کۆنتڕۆڵەر</string>
<string name="emulation_hide_overlay">پیشاندانی کۆنتڕۆڵەر</string>
<string name="emulation_toggle_all">گۆڕینی سەرجەم</string>
<string name="emulation_control_adjust">ڕێکخستنی داپۆشەر</string>
<string name="emulation_control_scale">پێوەر</string>

View file

@ -458,6 +458,8 @@
<string name="use_custom_rtc">Vlastní RTC</string>
<string name="use_custom_rtc_description">Vlastní nastavení času</string>
<string name="set_custom_rtc">Nastavit vlastní RTC</string>
<string name="disable_nca_verification">Zakázat ověřování NCA</string>
<string name="disable_nca_verification_description">Zakáže ověřování integrity archivů obsahu NCA. To může zlepšit rychlost načítání, ale hrozí poškození dat nebo neodhalení neplatných souborů. Je nutné, aby fungovaly hry a aktualizace vyžadující firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Generovat</string>
@ -691,7 +693,8 @@
<string name="emulation_rel_stick_center">Relativní střed joysticku</string>
<string name="emulation_dpad_slide">D-pad slide</string>
<string name="emulation_haptics">Haptická odezva</string>
<string name="emulation_show_overlay">Zobrazit překryv</string>
<string name="emulation_show_overlay">Zobrazit ovladač</string>
<string name="emulation_hide_overlay">Skrýt ovladač</string>
<string name="emulation_toggle_all">Přepnout vše</string>
<string name="emulation_control_adjust">Upravit překryv</string>
<string name="emulation_control_scale">Měřítko</string>

View file

@ -486,6 +486,8 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="select_rtc_date">RTC-Datum auswählen</string>
<string name="select_rtc_time">RTC-Zeit auswählen</string>
<string name="use_custom_rtc">Benutzerdefinierte Echtzeituhr</string>
<string name="disable_nca_verification">NCA-Verifizierung deaktivieren</string>
<string name="disable_nca_verification_description">Deaktiviert die Integritätsprüfung von NCA-Inhaltsarchiven. Dies kann die Ladegeschwindigkeit verbessern, riskiert jedoch Datenbeschädigung oder dass ungültige Dateien unentdeckt bleiben. Ist notwendig, um Spiele und Updates, die Firmware 20+ benötigen, zum Laufen zu bringen.</string>
<!-- Network settings strings -->
<string name="generate">Generieren</string>
@ -762,6 +764,13 @@ Wirklich fortfahren?</string>
<string name="emulation_exit">Emulation beenden</string>
<string name="emulation_done">Fertig</string>
<string name="emulation_fps_counter">FPS Zähler</string>
<string name="emulation_thermal_indicator"></string>
<string name="emulation_toggle_controls">Steuerung umschalten</string>
<string name="emulation_rel_stick_center">Relativer Stick-Zentrum</string>
<string name="emulation_dpad_slide">D-Pad-Scrollen</string>
<string name="emulation_haptics">Haptisches Feedback</string>
<string name="emulation_show_overlay">Controller anzeigen</string>
<string name="emulation_hide_overlay">Controller ausblenden</string>
<string name="emulation_toggle_all">Alle umschalten</string>
<string name="emulation_control_adjust">Overlay anpassen</string>
<string name="emulation_control_scale">Größe</string>

View file

@ -506,6 +506,8 @@
<string name="use_custom_rtc">RTC personalizado</string>
<string name="use_custom_rtc_description">Te permite tener un reloj personalizado en tiempo real diferente del tiempo del propio sistema.</string>
<string name="set_custom_rtc">Configurar RTC personalizado</string>
<string name="disable_nca_verification">Desactivar verificación NCA</string>
<string name="disable_nca_verification_description">Desactiva la verificación de integridad de los archivos de contenido NCA. Esto puede mejorar la velocidad de carga, pero arriesga corrupción de datos o que archivos inválidos pasen desapercibidos. Es necesario para que funcionen juegos y actualizaciones que requieren firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Generar</string>
@ -806,7 +808,8 @@
<string name="emulation_rel_stick_center">Centro relativo del stick</string>
<string name="emulation_dpad_slide">Deslizamiento de la cruceta</string>
<string name="emulation_haptics">Toques hápticos</string>
<string name="emulation_show_overlay">Mostrar overlay</string>
<string name="emulation_show_overlay">Mostrar controlador</string>
<string name="emulation_hide_overlay">Ocultar controlador</string>
<string name="emulation_toggle_all">Alternar todo</string>
<string name="emulation_control_adjust">Ajustar overlay</string>
<string name="emulation_control_scale">Escala</string>

View file

@ -504,6 +504,8 @@
<string name="use_custom_rtc">زمان سفارشی</string>
<string name="use_custom_rtc_description">به شما امکان می‌دهد یک ساعت سفارشی جدا از زمان فعلی سیستم خود تنظیم کنید.</string>
<string name="set_custom_rtc">تنظیم زمان سفارشی</string>
<string name="disable_nca_verification">غیرفعال کردن تأیید اعتبار NCA</string>
<string name="disable_nca_verification_description">بررسی صحت آرشیوهای محتوای NCA را غیرفعال می‌کند. این ممکن است سرعت بارگذاری را بهبود بخشد اما خطر خرابی داده یا تشخیص داده نشدن فایل‌های نامعتبر را به همراه دارد. برای کار کردن بازی‌ها و به‌روزرسانی‌هایی که به فرمور ۲۰+ نیاز دارند، ضروری است.</string>
<!-- Network settings strings -->
<string name="generate">تولید</string>
@ -805,7 +807,8 @@
<string name="emulation_rel_stick_center">مرکز نسبی استیک</string>
<string name="emulation_dpad_slide">لغزش دکمه‌های جهتی</string>
<string name="emulation_haptics">لرزش لمسی</string>
<string name="emulation_show_overlay">نشان دادن نمایش روی صفحه</string>
<string name="emulation_show_overlay">نمایش کنترلر</string>
<string name="emulation_hide_overlay">پنهان کردن کنترلر</string>
<string name="emulation_toggle_all">تغییر همه</string>
<string name="emulation_control_adjust">تنظیم نمایش روی صفحه</string>
<string name="emulation_control_scale">مقیاس</string>

View file

@ -506,6 +506,8 @@
<string name="use_custom_rtc">RTC personnalisé</string>
<string name="use_custom_rtc_description">Vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string>
<string name="set_custom_rtc">Définir l\'horloge RTC personnalisée</string>
<string name="disable_nca_verification">Désactiver la vérification NCA</string>
<string name="disable_nca_verification_description">Désactive la vérification d\'intégrité des archives de contenu NCA. Cela peut améliorer la vitesse de chargement mais risque une corruption des données ou que des fichiers invalides ne soient pas détectés. Est nécessaire pour faire fonctionner les jeux et mises à jour nécessitant un firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Générer</string>
@ -854,7 +856,8 @@
<string name="emulation_rel_stick_center">Centre du stick relatif</string>
<string name="emulation_dpad_slide">Glissement du D-pad</string>
<string name="emulation_haptics">Toucher haptique</string>
<string name="emulation_show_overlay">Afficher l\'overlay</string>
<string name="emulation_show_overlay">Afficher la manette</string>
<string name="emulation_hide_overlay">Masquer la manette</string>
<string name="emulation_toggle_all">Tout basculer</string>
<string name="emulation_control_adjust">Ajuster l\'overlay</string>
<string name="emulation_control_scale">Échelle</string>

View file

@ -505,6 +505,8 @@
<string name="use_custom_rtc">RTC מותאם אישית</string>
<string name="use_custom_rtc_description">מאפשר לך לקבוע שעון זמן אמת נפרד משעון המערכת שלך.</string>
<string name="set_custom_rtc">קבע RTC מותאם אישית</string>
<string name="disable_nca_verification">השבת אימות NCA</string>
<string name="disable_nca_verification_description">משבית את אימות השלמות של ארכיוני התוכן של NCA. זה עשוי לשפר את מהירות הטעינה אך מסתכן בשחיקת נתונים או שמא קבצים לא חוקיים יעברו ללא זיהוי. זה הכרחי כדי לגרום למשחקים ועדכונים הדורשים firmware 20+ לעבוד.</string>
<!-- Network settings strings -->
<string name="generate">יצירה</string>
@ -739,7 +741,8 @@
<string name="emulation_rel_stick_center">מרכז ג׳ויסטיק יחסי</string>
<string name="emulation_dpad_slide">החלקת D-pad</string>
<string name="emulation_haptics">רטט מגע</string>
<string name="emulation_show_overlay">הצג את שכבת-העל</string>
<string name="emulation_show_overlay">הצג בקר</string>
<string name="emulation_hide_overlay">הסתר בקר</string>
<string name="emulation_toggle_all">החלף הכל</string>
<string name="emulation_control_adjust">התאם את שכבת-העל</string>
<string name="emulation_control_scale">קנה מידה</string>

View file

@ -501,6 +501,8 @@
<string name="use_custom_rtc">Egyéni RTC</string>
<string name="use_custom_rtc_description">Megadhatsz egy valós idejű órát, amely eltér a rendszer által használt órától.</string>
<string name="set_custom_rtc">Egyéni RTC beállítása</string>
<string name="disable_nca_verification">NCA ellenőrzés letiltása</string>
<string name="disable_nca_verification_description">Letiltja az NCA tartalomarchívumok integritás-ellenőrzését. Ez javíthatja a betöltési sebességet, de az adatsérülés vagy az érvénytelen fájlok észrevétlen maradásának kockázatával jár. Elengedhetetlen a 20+ firmware-et igénylő játékok és frissítések működtetéséhez.</string>
<!-- Network settings strings -->
<string name="generate">Generálás</string>
@ -843,7 +845,8 @@
<string name="emulation_toggle_controls">Irányítás átkapcsolása</string>
<string name="emulation_dpad_slide">D-pad csúsztatása</string>
<string name="emulation_haptics">Érintés haptikája</string>
<string name="emulation_show_overlay">Átfedés mutatása</string>
<string name="emulation_show_overlay">Vezérlő megjelenítése</string>
<string name="emulation_hide_overlay">Vezérlő elrejtése</string>
<string name="emulation_toggle_all">Összes átkapcsolása</string>
<string name="emulation_control_adjust">Átfedés testreszabása</string>
<string name="emulation_control_scale">Skálázás</string>

View file

@ -502,6 +502,8 @@
<string name="use_custom_rtc">RTC Kustom</string>
<string name="use_custom_rtc_description">Memungkinkan Anda untuk mengatur jam waktu nyata kustom yang terpisah dari waktu sistem saat ini Anda.</string>
<string name="set_custom_rtc">Setel RTC Kustom</string>
<string name="disable_nca_verification">Nonaktifkan Verifikasi NCA</string>
<string name="disable_nca_verification_description">Menonaktifkan verifikasi integritas arsip konten NCA. Ini dapat meningkatkan kecepatan pemuatan tetapi berisiko kerusakan data atau file yang tidak valid tidak terdeteksi. Diperlukan untuk membuat game dan pembaruan yang membutuhkan firmware 20+ bekerja.</string>
<!-- Network settings strings -->
<string name="generate">Hasilkan</string>
@ -798,7 +800,8 @@
<string name="emulation_rel_stick_center">Pusat stick relatif</string>
<string name="emulation_dpad_slide">Geser Dpad</string>
<string name="emulation_haptics">Haptik</string>
<string name="emulation_show_overlay">Tampilkan Hamparan</string>
<string name="emulation_show_overlay">Tampilkan Kontroler</string>
<string name="emulation_hide_overlay">Sembunyikan Kontroler</string>
<string name="emulation_toggle_all">Alihkan Semua</string>
<string name="emulation_control_adjust">Menyesuaikan</string>
<string name="emulation_control_scale">Skala</string>

View file

@ -505,6 +505,8 @@
<string name="use_custom_rtc">RTC Personalizzato</string>
<string name="use_custom_rtc_description">Ti permette di impostare un orologio in tempo reale personalizzato, completamente separato da quello di sistema.</string>
<string name="set_custom_rtc">Imposta un orologio in tempo reale personalizzato</string>
<string name="disable_nca_verification">Disabilita verifica NCA</string>
<string name="disable_nca_verification_description">Disabilita la verifica dell\'integrità degli archivi di contenuto NCA. Può migliorare la velocità di caricamento ma rischia il danneggiamento dei dati o che file non validi passino inosservati. Necessario per far funzionare giochi e aggiornamenti che richiedono il firmware 20+.</string>
<!-- Network settings strings -->
<string name="generate">Genera</string>
@ -770,7 +772,8 @@
<string name="emulation_rel_stick_center">Centro relativo degli Stick</string>
<string name="emulation_dpad_slide">DPad A Scorrimento</string>
<string name="emulation_haptics">Feedback Aptico</string>
<string name="emulation_show_overlay">Mostra l\'overlay</string>
<string name="emulation_show_overlay">Mostra l\'controller</string>
<string name="emulation_hide_overlay">Nascondi l\'controller</string>
<string name="emulation_toggle_all">Attiva/Disattiva tutto</string>
<string name="emulation_control_adjust">Regola l\'overlay</string>
<string name="emulation_control_scale">Scala</string>

View file

@ -491,6 +491,8 @@
<string name="use_custom_rtc">カスタム RTC</string>
<string name="use_custom_rtc_description">現在のシステム時間とは別に、任意のリアルタイムクロックを設定できます。</string>
<string name="set_custom_rtc">カスタムRTCを設定</string>
<string name="disable_nca_verification">NCA検証を無効化</string>
<string name="disable_nca_verification_description">NCAコンテンツアーカイブの整合性検証を無効にします。読み込み速度が向上する可能性がありますが、データ破損や不正なファイルが検出されないリスクがあります。ファームウェア20以上が必要なゲームや更新を動作させるために必要です。</string>
<!-- Network settings strings -->
<string name="generate">生成</string>
@ -729,7 +731,8 @@
<string name="emulation_rel_stick_center">スティックを固定しない</string>
<string name="emulation_dpad_slide">十字キーをスライド操作</string>
<string name="emulation_haptics">タッチ振動</string>
<string name="emulation_show_overlay">ボタンを表示</string>
<string name="emulation_show_overlay">コントローラーを表示</string>
<string name="emulation_hide_overlay">コントローラーを非表示</string>
<string name="emulation_toggle_all">すべて切替</string>
<string name="emulation_control_adjust">見た目を調整</string>
<string name="emulation_control_scale">大きさ</string>

View file

@ -501,6 +501,8 @@
<string name="use_custom_rtc">사용자 지정 RTC</string>
<string name="use_custom_rtc_description">현재 시스템 시간과 별도로 사용자 지정 RTC를 설정할 수 있습니다.</string>
<string name="set_custom_rtc">사용자 지정 RTC 설정</string>
<string name="disable_nca_verification">NCA 검증 비활성화</string>
<string name="disable_nca_verification_description">NCA 콘텐츠 아카이브의 무결성 검증을 비활성화합니다. 로딩 속도를 향상시킬 수 있지만 데이터 손상이나 유효하지 않은 파일이 미검증될 위험이 있습니다. 펌웨어 20+가 필요한 게임 및 업데이트를 실행하려면 필요합니다.</string>
<!-- Network settings strings -->
<string name="generate">생성</string>
@ -798,6 +800,7 @@
<string name="emulation_dpad_slide">십자키 슬라이드</string>
<string name="emulation_haptics">터치 햅틱</string>
<string name="emulation_show_overlay">컨트롤러 표시</string>
<string name="emulation_hide_overlay">컨트롤러 숨기기</string>
<string name="emulation_toggle_all">모두 선택</string>
<string name="emulation_control_adjust">컨트롤러 조정</string>
<string name="emulation_control_scale">크기</string>

View file

@ -482,6 +482,8 @@
<string name="use_custom_rtc">Tilpasset Sannhetstidsklokke</string>
<string name="use_custom_rtc_description">Gjør det mulig å stille inn en egendefinert sanntidsklokke separat fra den gjeldende systemtiden.</string>
<string name="set_custom_rtc">Angi tilpasset RTC</string>
<string name="disable_nca_verification">Deaktiver NCA-verifisering</string>
<string name="disable_nca_verification_description">Deaktiverer integritetsverifisering av NCA-innholdsarkiv. Dette kan forbedre lastehastigheten, men medfører risiko for datakorrupsjon eller at ugyldige filer ikke oppdages. Er nødvendig for å få spill og oppdateringer som trenger firmware 20+ til å fungere.</string>
<!-- Network settings strings -->
<string name="generate">Generer</string>
@ -720,7 +722,8 @@
<string name="emulation_rel_stick_center">Relativt pinnesenter</string>
<string name="emulation_dpad_slide">D-pad-skyving</string>
<string name="emulation_haptics">Berøringshaptikk</string>
<string name="emulation_show_overlay">Vis overlegg</string>
<string name="emulation_show_overlay">Vis kontroller</string>
<string name="emulation_hide_overlay">Skjul kontroller</string>
<string name="emulation_toggle_all">Veksle mellom alle</string>
<string name="emulation_control_adjust">Juster overlegg</string>
<string name="emulation_control_scale">Skaler</string>

View file

@ -482,6 +482,8 @@
<string name="use_custom_rtc">Niestandardowy RTC</string>
<string name="use_custom_rtc_description">Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android.</string>
<string name="set_custom_rtc">Ustaw niestandardowy czas RTC</string>
<string name="disable_nca_verification">Wyłącz weryfikację NCA</string>
<string name="disable_nca_verification_description">Wyłącza weryfikację integralności archiwów zawartości NCA. Może to poprawić szybkość ładowania, ale niesie ryzyko uszkodzenia danych lub niezauważenia nieprawidłowych plików. Konieczne, aby działały gry i aktualizacje wymagające firmware\'u 20+.</string>
<!-- Network settings strings -->
<string name="generate">Generuj</string>
@ -718,7 +720,8 @@
<string name="emulation_rel_stick_center">Wycentruj gałki</string>
<string name="emulation_dpad_slide">Ruchomy D-pad</string>
<string name="emulation_haptics">Wibracje haptyczne</string>
<string name="emulation_show_overlay">Pokaż przyciski</string>
<string name="emulation_show_overlay">Pokaż kontroler</string>
<string name="emulation_hide_overlay">Ukryj kontroler</string>
<string name="emulation_toggle_all">Włącz wszystkie</string>
<string name="emulation_control_adjust">Dostosuj nakładkę</string>
<string name="emulation_control_scale">Skala</string>

View file

@ -506,6 +506,8 @@
<string name="use_custom_rtc">Data e hora personalizadas</string>
<string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
<string name="set_custom_rtc">Definir um relógio em tempo real personalizado</string>
<string name="disable_nca_verification">Desativar verificação NCA</string>
<string name="disable_nca_verification_description">Desativa a verificação de integridade de arquivos de conteúdo NCA. Pode melhorar a velocidade de carregamento, mas arrisica corromper dados ou que arquivos inválidos passem despercebidos. É necessário para fazer jogos e atualizações que exigem firmware 20+ funcionarem.</string>
<!-- Network settings strings -->
<string name="generate">Gerar</string>
@ -855,7 +857,8 @@ uma tentativa de mapeamento automático</string>
<string name="emulation_rel_stick_center">Centro Relativo do Analógico</string>
<string name="emulation_dpad_slide">Deslizamento dos Botões Direcionais</string>
<string name="emulation_haptics">Vibração ao tocar</string>
<string name="emulation_show_overlay">Mostrar overlay</string>
<string name="emulation_show_overlay">Mostrar controle</string>
<string name="emulation_hide_overlay">Ocultar controle</string>
<string name="emulation_toggle_all">Marcar/Desmarcar tudo</string>
<string name="emulation_control_adjust">Ajustar overlay</string>
<string name="emulation_control_scale">Escala</string>

View file

@ -506,6 +506,8 @@
<string name="use_custom_rtc">RTC personalizado</string>
<string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
<string name="set_custom_rtc">Defina um relógio em tempo real personalizado</string>
<string name="disable_nca_verification">Desativar verificação NCA</string>
<string name="disable_nca_verification_description">Desativa a verificação de integridade dos arquivos de conteúdo NCA. Pode melhorar a velocidade de carregamento, mas arrisca a corrupção de dados ou que ficheiros inválidos passem despercebidos. É necessário para que jogos e atualizações que necessitam de firmware 20+ funcionem.</string>
<!-- Network settings strings -->
<string name="generate">Gerar</string>
@ -855,7 +857,8 @@ uma tentativa de mapeamento automático</string>
<string name="emulation_rel_stick_center">Centro Relativo de Analógico</string>
<string name="emulation_dpad_slide">Deslizamento dos Botões Direcionais</string>
<string name="emulation_haptics">Vibração ao tocar</string>
<string name="emulation_show_overlay">Mostrar overlay</string>
<string name="emulation_show_overlay">Mostrar comando</string>
<string name="emulation_hide_overlay">Ocultar comando</string>
<string name="emulation_toggle_all">Marcar/Desmarcar tudo</string>
<string name="emulation_control_adjust">Ajustar overlay</string>
<string name="emulation_control_scale">Escala</string>

View file

@ -508,6 +508,8 @@
<string name="use_custom_rtc">Пользовательский RTC</string>
<string name="use_custom_rtc_description">Позволяет установить пользовательские часы реального времени отдельно от текущего системного времени.</string>
<string name="set_custom_rtc">Установить пользовательский RTC</string>
<string name="disable_nca_verification">Отключить проверку NCA</string>
<string name="disable_nca_verification_description">Отключает проверку целостности архивов содержимого NCA. Может улучшить скорость загрузки, но есть риск повреждения данных или того, что недействительные файлы останутся незамеченными. Необходимо для работы игр и обновлений, требующих прошивку 20+.</string>
<!-- Network settings strings -->
<string name="generate">Создать</string>
@ -856,7 +858,8 @@
<string name="emulation_rel_stick_center">Относительный центр стика</string>
<string name="emulation_dpad_slide">Слайд крестовиной</string>
<string name="emulation_haptics">Обратная связь от нажатий</string>
<string name="emulation_show_overlay">Показать оверлей</string>
<string name="emulation_show_overlay">Показать контроллер</string>
<string name="emulation_hide_overlay">Скрыть контроллер</string>
<string name="emulation_toggle_all">Переключить всё</string>
<string name="emulation_control_adjust">Регулировка оверлея</string>
<string name="emulation_control_scale">Масштаб</string>

View file

@ -457,6 +457,8 @@
<string name="use_custom_rtc">Цустом РТЦ</string>
<string name="use_custom_rtc_description">Омогућава вам да поставите прилагођени сат у реалном времену одвојено од тренутног времена система.</string>
<string name="set_custom_rtc">Подесите прилагођени РТЦ</string>
<string name="disable_nca_verification">Искључи верификацију НЦА</string>
<string name="disable_nca_verification_description">Искључује верификацију интегритета НЦА архива садржаја. Ово може побољшати брзину учитавања, али ризикује оштећење података или да неважећи фајлови прођу незапажено. Неопходно је да би игре и ажурирања која захтевају firmware 20+ радили.</string>
<!-- Network settings strings -->
<string name="generate">Генериши</string>
@ -812,7 +814,8 @@
<string name="emulation_rel_stick_center">Релативни центар за штапић</string>
<string name="emulation_dpad_slide">Д-Пад Слиде</string>
<string name="emulation_haptics">Додирните ХАптицс</string>
<string name="emulation_show_overlay">Приказати прекривање</string>
<string name="emulation_show_overlay">Приказати контролер</string>
<string name="emulation_hide_overlay">Сакрити контролер</string>
<string name="emulation_toggle_all">Пребацивати све</string>
<string name="emulation_control_adjust">Подесити прекривање</string>
<string name="emulation_control_scale">Скала</string>

View file

@ -495,6 +495,8 @@
<string name="use_custom_rtc">Свій RTC</string>
<string name="use_custom_rtc_description">Дозволяє встановити власний час (Real-time clock, або RTC), відмінний від системного.</string>
<string name="set_custom_rtc">Встановити RTC</string>
<string name="disable_nca_verification">Вимкнути перевірку NCA</string>
<string name="disable_nca_verification_description">Вимкає перевірку цілісності архівів вмісту NCA. Може покращити швидкість завантаження, але ризикує пошкодженням даних або тим, що недійсні файли залишаться непоміченими. Необхідно для роботи ігор та оновлень, які вимагають прошивки 20+.</string>
<!-- Network settings strings -->
<string name="generate">Створити</string>
@ -749,7 +751,8 @@
<string name="emulation_rel_stick_center">Відносний центр джойстика</string>
<string name="emulation_dpad_slide">Ковзання D-pad</string>
<string name="emulation_haptics">Тактильний відгук</string>
<string name="emulation_show_overlay">Показати накладання</string>
<string name="emulation_show_overlay">Показати контролер</string>
<string name="emulation_hide_overlay">Сховати контролер</string>
<string name="emulation_toggle_all">Перемкнути все</string>
<string name="emulation_control_adjust">Налаштувати накладання</string>
<string name="emulation_control_scale">Масштаб</string>

View file

@ -482,6 +482,8 @@
<string name="use_custom_rtc">RTC tuỳ chỉnh</string>
<string name="use_custom_rtc_description">Cho phép bạn thiết lập một đồng hồ thời gian thực tùy chỉnh riêng biệt so với thời gian hệ thống hiện tại.</string>
<string name="set_custom_rtc">Thiết lập RTC tùy chỉnh</string>
<string name="disable_nca_verification">Tắt xác minh NCA</string>
<string name="disable_nca_verification_description">Tắt xác minh tính toàn vẹn của kho lưu trữ nội dung NCA. Có thể cải thiện tốc độ tải nhưng có nguy cơ hỏng dữ liệu hoặc các tệp không hợp lệ không bị phát hiện. Cần thiết để các trò chơi và bản cập nhật yêu cầu firmware 20+ hoạt động.</string>
<!-- Network settings strings -->
<string name="generate">Tạo</string>
@ -723,7 +725,8 @@
<string name="emulation_rel_stick_center">Trung tâm nút cần xoay tương đối</string>
<string name="emulation_dpad_slide">Trượt D-pad</string>
<string name="emulation_haptics">Chạm haptics</string>
<string name="emulation_show_overlay">Hiện lớp phủ</string>
<string name="emulation_show_overlay">Hiện bộ điều khiển</string>
<string name="emulation_hide_overlay">Ẩn bộ điều khiển</string>
<string name="emulation_toggle_all">Chuyển đổi tất cả</string>
<string name="emulation_control_adjust">Điều chỉnh lớp phủ</string>
<string name="emulation_control_scale">Tỉ lệ thu phóng</string>

View file

@ -500,6 +500,8 @@
<string name="use_custom_rtc">自定义系统时间</string>
<string name="use_custom_rtc_description">此选项允许您设置与目前系统时间相独立的自定义系统时钟。</string>
<string name="set_custom_rtc">设置自定义系统时间</string>
<string name="disable_nca_verification">禁用NCA验证</string>
<string name="disable_nca_verification_description">禁用NCA内容存档的完整性验证。可能会提高加载速度但存在数据损坏或无效文件未被检测到的风险。对于需要固件20+的游戏和更新是必需的。</string>
<!-- Network settings strings -->
<string name="generate">生成</string>
@ -848,7 +850,8 @@
<string name="emulation_rel_stick_center">相对摇杆中心</string>
<string name="emulation_dpad_slide">十字方向键滑动</string>
<string name="emulation_haptics">触觉反馈</string>
<string name="emulation_show_overlay">显示虚拟按键</string>
<string name="emulation_show_overlay">显示控制器</string>
<string name="emulation_hide_overlay">隐藏控制器</string>
<string name="emulation_toggle_all">全部切换</string>
<string name="emulation_control_adjust">调整虚拟按键</string>
<string name="emulation_control_scale">缩放</string>

View file

@ -505,6 +505,8 @@
<string name="use_custom_rtc">自訂 RTC</string>
<string name="use_custom_rtc_description">允許您設定與您的目前系統時間相互獨立的自訂即時時鐘。</string>
<string name="set_custom_rtc">設定自訂 RTC</string>
<string name="disable_nca_verification">停用NCA驗證</string>
<string name="disable_nca_verification_description">停用NCA內容存檔的完整性驗證。可能會提高載入速度但存在資料損毀或無效檔案未被偵測到的風險。對於需要韌體20+的遊戲和更新是必需的。</string>
<!-- Network settings strings -->
<string name="generate">生成</string>
@ -853,7 +855,8 @@
<string name="emulation_rel_stick_center">相對搖桿中心</string>
<string name="emulation_dpad_slide">方向鍵滑動</string>
<string name="emulation_haptics">觸覺回饋技術</string>
<string name="emulation_show_overlay">顯示覆疊</string>
<string name="emulation_show_overlay">顯示控制器</string>
<string name="emulation_hide_overlay">隱藏控制器</string>
<string name="emulation_toggle_all">全部切換</string>
<string name="emulation_control_adjust">調整覆疊</string>
<string name="emulation_control_scale">縮放</string>

View file

@ -474,6 +474,8 @@
<string name="use_custom_rtc">Custom RTC</string>
<string name="use_custom_rtc_description">Allows you to set a custom real-time clock separate from your current system time.</string>
<string name="set_custom_rtc">Set custom RTC</string>
<string name="disable_nca_verification">Disable NCA Verification</string>
<string name="disable_nca_verification_description">Disables integrity verification of NCA content archives. This may improve loading speed but risks data corruption or invalid files going undetected. Some games that require firmware versions 20+ may need this as well.</string>
<string name="generate">Generate</string>
@ -782,6 +784,9 @@
<string name="loader_requires_firmware">Game Requires Firmware</string>
<string name="loader_requires_firmware_description"><![CDATA[The game you are trying to launch requires firmware to boot or to get past the opening menu. Please <a href="https://yuzu-mirror.github.io/help/quickstart"> dump and install firmware</a>, or press "OK" to launch anyways.]]></string>
<string name="nca_verification_disabled">NCA Verification Disabled</string>
<string name="nca_verification_disabled_description">This is required to run new games and updates, but may cause instability or crashes if NCA files are corrupt, modified, or tampered with. If unsure, re-enable verification in Advanced Settings -> System, and use firmware versions of 19.0.1 or below.</string>
<!-- Intent Launch strings -->
<string name="searching_for_game">Searching for game...</string>
<string name="game_not_found_for_title_id">Game not found for Title ID: %1$s</string>
@ -835,7 +840,8 @@
<string name="emulation_rel_stick_center">Relative stick center</string>
<string name="emulation_dpad_slide">D-pad slide</string>
<string name="emulation_haptics">Touch haptics</string>
<string name="emulation_show_overlay">Show overlay</string>
<string name="emulation_show_overlay">Show controller</string>
<string name="emulation_hide_overlay">Hide controller</string>
<string name="emulation_toggle_all">Toggle all</string>
<string name="emulation_control_adjust">Adjust overlay</string>
<string name="emulation_control_scale">Scale</string>

View file

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
@ -229,9 +232,10 @@ endif()
target_include_directories(audio_core PRIVATE ${OPUS_INCLUDE_DIRS})
target_link_libraries(audio_core PUBLIC common core opus)
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_link_libraries(audio_core PRIVATE dynarmic::dynarmic)
endif()
# what?
# if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
# target_link_libraries(audio_core PRIVATE dynarmic::dynarmic)
# endif()
if (ENABLE_CUBEB)
target_sources(audio_core PRIVATE
@ -240,7 +244,7 @@ if (ENABLE_CUBEB)
)
target_link_libraries(audio_core PRIVATE cubeb)
target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
target_compile_definitions(audio_core PRIVATE HAVE_CUBEB=1)
endif()
if (ENABLE_SDL2)

View file

@ -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
@ -13,7 +16,7 @@
#include "common/polyfill_ranges.h"
namespace AudioCore {
constexpr u32 CurrentRevision = 13;
constexpr u32 CurrentRevision = 16;
enum class SupportTags {
CommandProcessingTimeEstimatorVersion4,
@ -54,6 +57,7 @@ constexpr u32 GetRevisionNum(u32 user_revision) {
user_revision -= Common::MakeMagic('R', 'E', 'V', '0');
user_revision >>= 24;
}
return user_revision;
};

View file

@ -162,10 +162,6 @@ add_library(
zstd_compression.h
)
if(YUZU_ENABLE_PORTABLE)
add_compile_definitions(YUZU_ENABLE_PORTABLE)
endif()
if(WIN32)
target_sources(common PRIVATE windows/timer_resolution.cpp
windows/timer_resolution.h)
@ -274,11 +270,6 @@ endif()
target_link_libraries(common PUBLIC fmt::fmt stb::headers Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4 LLVM::Demangle zstd::zstd)
if (TARGET unordered_dense::unordered_dense)
# weird quirk of system installs
target_link_libraries(common PUBLIC unordered_dense::unordered_dense)
endif()
if(ANDROID)
# For ASharedMemory_create
target_link_libraries(common PRIVATE android)

View file

@ -12,7 +12,6 @@
#define PORTABLE_DIR "user"
// Sub-directories contained within a yuzu data directory
#define AMIIBO_DIR "amiibo"
#define CACHE_DIR "cache"
#define CONFIG_DIR "config"
@ -28,11 +27,12 @@
#define SHADER_DIR "shader"
#define TAS_DIR "tas"
#define ICONS_DIR "icons"
// Compatibility with other emulators
#define CITRON_DIR "citron"
#define SUDACHI_DIR "sudachi"
#define YUZU_DIR "yuzu"
#define SUYU_DIR "suyu"
// yuzu-specific files
#define LOG_FILE "eden_log.txt"

View file

@ -101,61 +101,53 @@ public:
legacy_paths.insert_or_assign(legacy_path, new_path);
}
/// In non-android devices, the current directory will first search for "user"
/// if such directory (and it must be a directory) is found, that takes priority
/// over the global configuration directory (in other words, portable directories
/// take priority over the global ones, always)
/// On Android, the behaviour is to look for the current directory only.
void Reinitialize(fs::path eden_path = {}) {
fs::path eden_path_cache;
fs::path eden_path_config;
#ifdef _WIN32
#ifdef YUZU_ENABLE_PORTABLE
// User directory takes priority over global %AppData% directory
eden_path = GetExeDirectory() / PORTABLE_DIR;
#endif
if (!IsDir(eden_path)) {
if (!Exists(eden_path) || !IsDir(eden_path)) {
eden_path = GetAppDataRoamingDirectory() / EDEN_DIR;
}
eden_path_cache = eden_path / CACHE_DIR;
eden_path_config = eden_path / CONFIG_DIR;
#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetAppDataRoamingDirectory() / upperName##_DIR); \
GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetAppDataRoamingDirectory() / upperName##_DIR / CONFIG_DIR); \
GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetAppDataRoamingDirectory() / upperName##_DIR / CACHE_DIR);
LEGACY_PATH(Citron, CITRON)
LEGACY_PATH(Sudachi, SUDACHI)
LEGACY_PATH(Yuzu, YUZU)
LEGACY_PATH(Suyu, SUYU)
#undef LEGACY_PATH
#elif ANDROID
ASSERT(!eden_path.empty());
eden_path_cache = eden_path / CACHE_DIR;
eden_path_config = eden_path / CONFIG_DIR;
#else
#ifdef YUZU_ENABLE_PORTABLE
eden_path = GetCurrentDir() / PORTABLE_DIR;
#endif
if (Exists(eden_path) && IsDir(eden_path)) {
eden_path_cache = eden_path / CACHE_DIR;
eden_path_config = eden_path / CONFIG_DIR;
} else {
if (!Exists(eden_path) || !IsDir(eden_path)) {
eden_path = GetDataDirectory("XDG_DATA_HOME") / EDEN_DIR;
eden_path_cache = GetDataDirectory("XDG_CACHE_HOME") / EDEN_DIR;
eden_path_config = GetDataDirectory("XDG_CONFIG_HOME") / EDEN_DIR;
} else {
eden_path_cache = eden_path / CACHE_DIR;
eden_path_config = eden_path / CONFIG_DIR;
}
#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetDataDirectory("XDG_DATA_HOME") / upperName##_DIR); \
GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetDataDirectory("XDG_CONFIG_HOME") / upperName##_DIR); \
GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetDataDirectory("XDG_CACHE_HOME") / upperName##_DIR);
LEGACY_PATH(Citron, CITRON)
LEGACY_PATH(Sudachi, SUDACHI)
LEGACY_PATH(Yuzu, YUZU)
LEGACY_PATH(Suyu, SUYU)
#undef LEGACY_PATH
#endif
GenerateEdenPath(EdenPath::EdenDir, eden_path);
GenerateEdenPath(EdenPath::AmiiboDir, eden_path / AMIIBO_DIR);
GenerateEdenPath(EdenPath::CacheDir, eden_path_cache);

View file

@ -1,5 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -35,60 +33,68 @@ HeapTracker::~HeapTracker() = default;
void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length,
MemoryPermission perm, bool is_separate_heap) {
bool rebuild_required = false;
// When mapping other memory, map pages immediately.
if (!is_separate_heap) {
m_buffer.Map(virtual_offset, host_offset, length, perm, false);
return;
}
{
// We are mapping part of a separate heap and insert into mappings.
// We are mapping part of a separate heap.
std::scoped_lock lk{m_lock};
m_map_count++;
const auto it = m_mappings.insert_or_assign(virtual_offset, SeparateHeapMap{
auto* const map = new SeparateHeapMap{
.vaddr = virtual_offset,
.paddr = host_offset,
.size = length,
.tick = m_tick++,
.perm = perm,
.is_resident = false,
});
// Update tick before possible rebuild.
it.first->second.tick = m_tick++;
// Check if we need to rebuild.
if (m_resident_map_count >= m_max_resident_map_count)
rebuild_required = true;
// Map the area.
m_buffer.Map(it.first->first, it.first->second.paddr, it.first->second.size, it.first->second.perm, false);
// This map is now resident.
it.first->second.is_resident = true;
m_resident_map_count++;
m_resident_mappings.insert(*it.first);
};
// Insert into mappings.
m_map_count++;
m_mappings.insert(*map);
}
// A rebuild was required, so perform it now.
if (rebuild_required)
this->RebuildSeparateHeapAddressSpace();
// Finally, map.
this->DeferredMapSeparateHeap(virtual_offset);
}
void HeapTracker::Unmap(size_t virtual_offset, size_t size, bool is_separate_heap) {
// If this is a separate heap...
if (is_separate_heap) {
std::scoped_lock lk{m_lock};
const SeparateHeapMap key{
.vaddr = virtual_offset,
};
// Split at the boundaries of the region we are removing.
this->SplitHeapMapLocked(virtual_offset);
this->SplitHeapMapLocked(virtual_offset + size);
// Erase all mappings in range.
auto it = m_mappings.find(virtual_offset);
while (it != m_mappings.end() && it->first < virtual_offset + size) {
auto it = m_mappings.find(key);
while (it != m_mappings.end() && it->vaddr < virtual_offset + size) {
// Get underlying item.
auto* const item = std::addressof(*it);
// If resident, erase from resident map.
if (it->second.is_resident) {
if (item->is_resident) {
ASSERT(--m_resident_map_count >= 0);
m_resident_mappings.erase(m_resident_mappings.find(it->first));
m_resident_mappings.erase(m_resident_mappings.iterator_to(*item));
}
// Erase from map.
ASSERT(--m_map_count >= 0);
it = m_mappings.erase(it);
// Free the item.
delete item;
}
}
// Unmap pages.
m_buffer.Unmap(virtual_offset, size, false);
}
@ -110,51 +116,110 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p
{
std::scoped_lock lk2{m_lock};
const SeparateHeapMap key{
.vaddr = next,
};
// Try to get the next mapping corresponding to this address.
const auto it = m_mappings.find(next);
const auto it = m_mappings.nfind(key);
if (it == m_mappings.end()) {
// There are no separate heap mappings remaining.
next = end;
should_protect = true;
} else if (it->first == cur) {
} else if (it->vaddr == cur) {
// We are in range.
// Update permission bits.
it->second.perm = perm;
it->perm = perm;
// Determine next address and whether we should protect.
next = cur + it->second.size;
should_protect = it->second.is_resident;
next = cur + it->size;
should_protect = it->is_resident;
} else /* if (it->vaddr > cur) */ {
// We weren't in range, but there is a block coming up that will be.
next = it->first;
next = it->vaddr;
should_protect = true;
}
}
// Clamp to end.
next = std::min(next, end);
// Reprotect, if we need to.
if (should_protect)
if (should_protect) {
m_buffer.Protect(cur, next - cur, perm);
}
// Advance.
cur = next;
}
}
bool HeapTracker::DeferredMapSeparateHeap(u8* fault_address) {
if (m_buffer.IsInVirtualRange(fault_address)) {
return this->DeferredMapSeparateHeap(fault_address - m_buffer.VirtualBasePointer());
}
return false;
}
bool HeapTracker::DeferredMapSeparateHeap(size_t virtual_offset) {
bool rebuild_required = false;
{
std::scoped_lock lk{m_lock};
// Check to ensure this was a non-resident separate heap mapping.
const auto it = this->GetNearestHeapMapLocked(virtual_offset);
if (it == m_mappings.end() || it->is_resident) {
return false;
}
// Update tick before possible rebuild.
it->tick = m_tick++;
// Check if we need to rebuild.
if (m_resident_map_count > m_max_resident_map_count) {
rebuild_required = true;
}
// Map the area.
m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false);
// This map is now resident.
it->is_resident = true;
m_resident_map_count++;
m_resident_mappings.insert(*it);
}
if (rebuild_required) {
// A rebuild was required, so perform it now.
this->RebuildSeparateHeapAddressSpace();
}
return true;
}
void HeapTracker::RebuildSeparateHeapAddressSpace() {
std::scoped_lock lk{m_rebuild_lock, m_lock};
ASSERT(!m_resident_mappings.empty());
// Dump half of the mappings.
//
// Despite being worse in theory, this has proven to be better in practice than more
// regularly dumping a smaller amount, because it significantly reduces average case
// lock contention.
std::size_t const desired_count = std::min(m_resident_map_count, m_max_resident_map_count) / 2;
std::size_t const evict_count = m_resident_map_count - desired_count;
const size_t desired_count = std::min(m_resident_map_count, m_max_resident_map_count) / 2;
const size_t evict_count = m_resident_map_count - desired_count;
auto it = m_resident_mappings.begin();
for (std::size_t i = 0; i < evict_count && it != m_resident_mappings.end(); i++) {
for (size_t i = 0; i < evict_count && it != m_resident_mappings.end(); i++) {
// Unmark and unmap.
it->second.is_resident = false;
m_buffer.Unmap(it->first, it->second.size, false);
it->is_resident = false;
m_buffer.Unmap(it->vaddr, it->size, false);
// Advance.
ASSERT(--m_resident_map_count >= 0);
it = m_resident_mappings.erase(it);
@ -163,32 +228,53 @@ void HeapTracker::RebuildSeparateHeapAddressSpace() {
void HeapTracker::SplitHeapMap(VAddr offset, size_t size) {
std::scoped_lock lk{m_lock};
this->SplitHeapMapLocked(offset);
this->SplitHeapMapLocked(offset + size);
}
void HeapTracker::SplitHeapMapLocked(VAddr offset) {
auto it = this->GetNearestHeapMapLocked(offset);
if (it != m_mappings.end() && it->first != offset) {
// Adjust left iterator
auto const orig_size = it->second.size;
auto const left_size = offset - it->first;
it->second.size = left_size;
// Insert the new right map.
auto const right = SeparateHeapMap{
.paddr = it->second.paddr + left_size,
.size = orig_size - left_size,
.tick = it->second.tick,
.perm = it->second.perm,
.is_resident = it->second.is_resident,
};
m_map_count++;
auto rit = m_mappings.insert_or_assign(it->first + left_size, right);
if (rit.first->second.is_resident) {
m_resident_map_count++;
m_resident_mappings.insert(*rit.first);
const auto it = this->GetNearestHeapMapLocked(offset);
if (it == m_mappings.end() || it->vaddr == offset) {
// Not contained or no split required.
return;
}
// Cache the original values.
auto* const left = std::addressof(*it);
const size_t orig_size = left->size;
// Adjust the left map.
const size_t left_size = offset - left->vaddr;
left->size = left_size;
// Create the new right map.
auto* const right = new SeparateHeapMap{
.vaddr = left->vaddr + left_size,
.paddr = left->paddr + left_size,
.size = orig_size - left_size,
.tick = left->tick,
.perm = left->perm,
.is_resident = left->is_resident,
};
// Insert the new right map.
m_map_count++;
m_mappings.insert(*right);
// If resident, also insert into resident map.
if (right->is_resident) {
m_resident_map_count++;
m_resident_mappings.insert(*right);
}
}
HeapTracker::AddrTree::iterator HeapTracker::GetNearestHeapMapLocked(VAddr offset) {
const SeparateHeapMap key{
.vaddr = offset,
};
return m_mappings.find(key);
}
} // namespace Common

View file

@ -1,55 +1,93 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <atomic>
#include <mutex>
#include <set>
#include <shared_mutex>
#include <ankerl/unordered_dense.h>
#include "common/host_memory.h"
#include "common/intrusive_red_black_tree.h"
namespace Common {
struct SeparateHeapMap {
PAddr paddr{}; //8
std::size_t size{}; //8 (16)
std::size_t tick{}; //8 (24)
// 4 bits needed, sync with host_memory.h if needed
MemoryPermission perm : 4 = MemoryPermission::Read;
bool is_resident : 1 = false;
Common::IntrusiveRedBlackTreeNode addr_node{};
Common::IntrusiveRedBlackTreeNode tick_node{};
VAddr vaddr{};
PAddr paddr{};
size_t size{};
size_t tick{};
MemoryPermission perm{};
bool is_resident{};
};
struct SeparateHeapMapAddrComparator {
static constexpr int Compare(const SeparateHeapMap& lhs, const SeparateHeapMap& rhs) {
if (lhs.vaddr < rhs.vaddr) {
return -1;
} else if (lhs.vaddr <= (rhs.vaddr + rhs.size - 1)) {
return 0;
} else {
return 1;
}
}
};
struct SeparateHeapMapTickComparator {
static constexpr int Compare(const SeparateHeapMap& lhs, const SeparateHeapMap& rhs) {
if (lhs.tick < rhs.tick) {
return -1;
} else if (lhs.tick > rhs.tick) {
return 1;
} else {
return SeparateHeapMapAddrComparator::Compare(lhs, rhs);
}
}
};
static_assert(sizeof(SeparateHeapMap) == 32); //half a cache line! good for coherency
class HeapTracker {
public:
explicit HeapTracker(Common::HostMemory& buffer);
~HeapTracker();
void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm, bool is_separate_heap);
void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm,
bool is_separate_heap);
void Unmap(size_t virtual_offset, size_t size, bool is_separate_heap);
void Protect(size_t virtual_offset, size_t length, MemoryPermission perm);
inline u8* VirtualBasePointer() noexcept {
u8* VirtualBasePointer() {
return m_buffer.VirtualBasePointer();
}
bool DeferredMapSeparateHeap(u8* fault_address);
bool DeferredMapSeparateHeap(size_t virtual_offset);
private:
// TODO: You may want to "fake-map" the first 2GB of 64-bit address space
// and dedicate it entirely to a recursive PTE mapping :)
// However Ankerl is way better than using an RB tree, in all senses
using AddrTree = ankerl::unordered_dense::map<VAddr, SeparateHeapMap>;
AddrTree m_mappings;
using TicksTree = ankerl::unordered_dense::map<VAddr, SeparateHeapMap>;
TicksTree m_resident_mappings;
using AddrTreeTraits =
Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&SeparateHeapMap::addr_node>;
using AddrTree = AddrTreeTraits::TreeType<SeparateHeapMapAddrComparator>;
using TickTreeTraits =
Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&SeparateHeapMap::tick_node>;
using TickTree = TickTreeTraits::TreeType<SeparateHeapMapTickComparator>;
AddrTree m_mappings{};
TickTree m_resident_mappings{};
private:
void SplitHeapMap(VAddr offset, size_t size);
void SplitHeapMapLocked(VAddr offset);
AddrTree::iterator GetNearestHeapMapLocked(VAddr offset);
void RebuildSeparateHeapAddressSpace();
inline HeapTracker::AddrTree::iterator GetNearestHeapMapLocked(VAddr offset) noexcept {
return m_mappings.find(offset);
}
private:
Common::HostMemory& m_buffer;
const s64 m_max_resident_map_count;
std::shared_mutex m_rebuild_lock{};
std::mutex m_lock{};
s64 m_map_count{};

View file

@ -12,7 +12,7 @@
#include <windows.h>
#include "common/dynamic_library.h"
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) // ^^^ Windows ^^^ vvv Linux vvv
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__) // ^^^ Windows ^^^ vvv POSIX vvv
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
@ -20,10 +20,18 @@
#include <boost/icl/interval_set.hpp>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/random.h>
#include <unistd.h>
#include "common/scope_exit.h"
#if defined(__linux__)
#include <sys/random.h>
#elif defined(__APPLE__)
#include <sys/types.h>
#include <sys/random.h>
#include <mach/vm_map.h>
#include <mach/mach.h>
#endif
// FreeBSD
#ifndef MAP_NORESERVE
#define MAP_NORESERVE 0
@ -32,8 +40,12 @@
#ifndef MAP_ALIGNED_SUPER
#define MAP_ALIGNED_SUPER 0
#endif
// macOS
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#endif // ^^^ Linux ^^^
#endif // ^^^ POSIX ^^^
#include <mutex>
#include <random>
@ -372,7 +384,7 @@ private:
std::unordered_map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
};
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) // ^^^ Windows ^^^ vvv Linux vvv
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__) // ^^^ Windows ^^^ vvv POSIX vvv
#ifdef ARCHITECTURE_arm64
@ -417,14 +429,11 @@ static void* ChooseVirtualBase(size_t virtual_size) {
#else
static void* ChooseVirtualBase(size_t virtual_size) {
#if defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__managarm__)
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__managarm__) || defined(__AIX__)
void* virtual_base = mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0);
if (virtual_base != MAP_FAILED) {
if (virtual_base != MAP_FAILED)
return virtual_base;
}
#endif
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
}
@ -492,6 +501,13 @@ public:
#elif defined(__FreeBSD__) && __FreeBSD__ < 13
// XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30
fd = shm_open(SHM_ANON, O_RDWR, 0600);
#elif defined(__APPLE__)
// macOS doesn't have memfd_create, use anonymous temporary file
char template_path[] = "/tmp/eden_mem_XXXXXX";
fd = mkstemp(template_path);
if (fd >= 0) {
unlink(template_path);
}
#else
fd = memfd_create("HostMemory", 0);
#endif
@ -648,7 +664,7 @@ private:
FreeRegionManager free_manager{};
};
#else // ^^^ Linux ^^^ vvv Generic vvv
#else // ^^^ POSIX ^^^ vvv Generic vvv
class HostMemory::Impl {
public:

View file

@ -163,8 +163,9 @@ bool IsFastmemEnabled() {
}
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)
return false;
#endif
#else
return true;
#endif
}
static bool is_nce_enabled = false;

View file

@ -217,7 +217,8 @@ struct Values {
true,
true,
&use_speed_limit};
SwitchableSetting<bool> sync_core_speed{linkage, false, "sync_core_speed", Category::Core, Specialization::Default};
SwitchableSetting<bool> sync_core_speed{linkage, false, "sync_core_speed", Category::Core,
Specialization::Default};
// Memory
#ifdef HAS_NCE
@ -551,6 +552,8 @@ struct Values {
3,
#elif defined (ANDROID)
0,
#elif defined (__APPLE__)
0,
#else
2,
#endif
@ -623,6 +626,10 @@ struct Values {
true, true, &rng_seed_enabled};
Setting<std::string> device_name{
linkage, "Eden", "device_name", Category::System, Specialization::Default, true, true};
SwitchableSetting<bool> disable_nca_verification{linkage, true, "disable_nca_verification",
Category::System, Specialization::Default};
Setting<bool> hide_nca_verification_popup{
linkage, false, "hide_nca_verification_popup", Category::System, Specialization::Default};
Setting<s32> current_user{linkage, 0, "current_user", Category::System};

View file

@ -7,6 +7,7 @@
#pragma once
#include <algorithm>
#include <cstddef>
#include <span>
#include <string>

View file

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
@ -88,6 +91,8 @@ add_library(core STATIC
file_sys/fssystem/fssystem_crypto_configuration.h
file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp
file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h
file_sys/fssystem/fssystem_hierarchical_sha3_storage.cpp
file_sys/fssystem/fssystem_hierarchical_sha3_storage.h
file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp
file_sys/fssystem/fssystem_hierarchical_sha256_storage.h
file_sys/fssystem/fssystem_indirect_storage.cpp
@ -102,6 +107,7 @@ add_library(core STATIC
file_sys/fssystem/fssystem_nca_header.cpp
file_sys/fssystem/fssystem_nca_header.h
file_sys/fssystem/fssystem_nca_reader.cpp
file_sys/fssystem/fssystem_passthrough_storage.h
file_sys/fssystem/fssystem_pooled_buffer.cpp
file_sys/fssystem/fssystem_pooled_buffer.h
file_sys/fssystem/fssystem_sparse_storage.cpp
@ -1152,7 +1158,7 @@ add_library(core STATIC
if (ENABLE_WIFI_SCAN)
# find_package(libiw REQUIRED)
target_compile_definitions(core PRIVATE -DENABLE_WIFI_SCAN)
target_compile_definitions(core PRIVATE ENABLE_WIFI_SCAN)
target_link_libraries(core PRIVATE iw)
endif()
@ -1193,13 +1199,13 @@ else()
target_link_libraries(core PUBLIC Boost::headers)
endif()
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API mbedtls)
if (MINGW)
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
endif()
if (ENABLE_WEB_SERVICE)
target_compile_definitions(core PUBLIC -DENABLE_WEB_SERVICE)
target_compile_definitions(core PUBLIC ENABLE_WEB_SERVICE)
target_link_libraries(core PUBLIC web_service)
endif()

View file

@ -3,9 +3,47 @@
#ifdef __linux__
//#include "common/signal_chain.h"
#include "common/signal_chain.h"
#include "core/arm/dynarmic/arm_dynarmic.h"
//#include "core/hle/kernel/k_process.h"
//#include "core/memory.h"
#include "core/hle/kernel/k_process.h"
#include "core/memory.h"
namespace Core {
namespace {
thread_local Core::Memory::Memory* g_current_memory{};
std::once_flag g_registered{};
struct sigaction g_old_segv {};
void HandleSigSegv(int sig, siginfo_t* info, void* ctx) {
if (g_current_memory && g_current_memory->InvalidateSeparateHeap(info->si_addr)) {
return;
}
return g_old_segv.sa_sigaction(sig, info, ctx);
}
} // namespace
ScopedJitExecution::ScopedJitExecution(Kernel::KProcess* process) {
g_current_memory = std::addressof(process->GetMemory());
}
ScopedJitExecution::~ScopedJitExecution() {
g_current_memory = nullptr;
}
void ScopedJitExecution::RegisterHandler() {
std::call_once(g_registered, [] {
struct sigaction sa {};
sa.sa_sigaction = &HandleSigSegv;
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
Common::SigAction(SIGSEGV, std::addressof(sa), std::addressof(g_old_segv));
});
}
} // namespace Core
#endif

View file

@ -26,4 +26,24 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) {
return static_cast<HaltReason>(hr);
}
#ifdef __linux__
class ScopedJitExecution {
public:
explicit ScopedJitExecution(Kernel::KProcess* process);
~ScopedJitExecution();
static void RegisterHandler();
};
#else
class ScopedJitExecution {
public:
explicit ScopedJitExecution(Kernel::KProcess* process) {}
~ScopedJitExecution() {}
static void RegisterHandler() {}
};
#endif
} // namespace Core

View file

@ -343,11 +343,15 @@ bool ArmDynarmic32::IsInThumbMode() const {
}
HaltReason ArmDynarmic32::RunThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic32::StepThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@ -389,6 +393,7 @@ ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProc
m_cp15(std::make_shared<DynarmicCP15>(*this)), m_core_index{core_index} {
auto& page_table_impl = process->GetPageTable().GetBasePageTable().GetImpl();
m_jit = MakeJit(&page_table_impl);
ScopedJitExecution::RegisterHandler();
}
ArmDynarmic32::~ArmDynarmic32() = default;

View file

@ -374,11 +374,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
}
HaltReason ArmDynarmic64::RunThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic64::StepThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@ -418,6 +422,7 @@ ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProc
auto& page_table = process->GetPageTable().GetBasePageTable();
auto& page_table_impl = page_table.GetImpl();
m_jit = MakeJit(&page_table_impl, page_table.GetAddressSpaceWidth());
ScopedJitExecution::RegisterHandler();
}
ArmDynarmic64::~ArmDynarmic64() = default;

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -31,6 +34,10 @@
#include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/loader.h"
#ifndef MBEDTLS_CMAC_C
#error mbedtls was compiled without CMAC support. Check your USE flags (Gentoo) or contact your package maintainer.
#endif
namespace Core::Crypto {
namespace {

View file

@ -7,7 +7,7 @@
#include <boost/asio.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION > 108300 && (!defined(_WINDOWS) && !defined(ANDROID)) || defined(YUZU_BOOST_v1)
#if BOOST_VERSION > 108400 && (!defined(_WINDOWS) && !defined(ANDROID)) || defined(YUZU_BOOST_v1)
#define USE_BOOST_v1
#endif

View file

@ -1,6 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/settings.h"
#include "core/file_sys/errors.h"
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
#include "core/file_sys/fssystem/fssystem_bucket_tree_utils.h"
@ -233,7 +237,10 @@ Result BucketTree::Initialize(VirtualFile node_storage, VirtualFile entry_storag
void BucketTree::Initialize(size_t node_size, s64 end_offset) {
ASSERT(NodeSizeMin <= node_size && node_size <= NodeSizeMax);
ASSERT(Common::IsPowerOfTwo(node_size));
if (!Settings::values.disable_nca_verification.GetValue()) {
ASSERT(end_offset > 0);
}
ASSERT(!this->IsInitialized());
m_node_size = node_size;

View file

@ -5,23 +5,10 @@
#include "common/scope_exit.h"
#include "core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.h"
#include <cmath>
namespace FileSys {
namespace {
s32 Log2(s32 value) {
ASSERT(value > 0);
ASSERT(Common::IsPowerOfTwo(value));
s32 log = 0;
while ((value >>= 1) > 0) {
++log;
}
return log;
}
} // namespace
Result HierarchicalSha256Storage::Initialize(VirtualFile* base_storages, s32 layer_count,
size_t htbs, void* hash_buf, size_t hash_buf_size) {
// Validate preconditions.
@ -31,7 +18,8 @@ Result HierarchicalSha256Storage::Initialize(VirtualFile* base_storages, s32 lay
// Set size tracking members.
m_hash_target_block_size = static_cast<s32>(htbs);
m_log_size_ratio = Log2(m_hash_target_block_size / HashSize);
m_log_size_ratio =
static_cast<s32>(std::log2(static_cast<double>(m_hash_target_block_size) / HashSize));
// Get the base storage size.
m_base_storage_size = base_storages[2]->GetSize();

View file

@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "common/alignment.h"
#include "common/scope_exit.h"
#include "core/file_sys/fssystem/fssystem_hierarchical_sha3_storage.h"
#include <cmath>
namespace FileSys {
Result HierarchicalSha3Storage::Initialize(VirtualFile* base_storages, s32 layer_count, size_t htbs,
void* hash_buf, size_t hash_buf_size) {
ASSERT(layer_count == LayerCount);
ASSERT(Common::IsPowerOfTwo(htbs));
ASSERT(hash_buf != nullptr);
m_hash_target_block_size = static_cast<s32>(htbs);
m_log_size_ratio =
static_cast<s32>(std::log2(static_cast<double>(m_hash_target_block_size) / HashSize));
m_base_storage_size = base_storages[2]->GetSize();
{
auto size_guard = SCOPE_GUARD {
m_base_storage_size = 0;
};
R_UNLESS(m_base_storage_size <= static_cast<s64>(HashSize)
<< m_log_size_ratio << m_log_size_ratio,
ResultHierarchicalSha256BaseStorageTooLarge);
size_guard.Cancel();
}
m_base_storage = base_storages[2];
m_hash_buffer = static_cast<char*>(hash_buf);
m_hash_buffer_size = hash_buf_size;
std::array<u8, HashSize> master_hash{};
base_storages[0]->ReadObject(std::addressof(master_hash));
s64 hash_storage_size = base_storages[1]->GetSize();
ASSERT(Common::IsAligned(hash_storage_size, HashSize));
ASSERT(hash_storage_size <= m_hash_target_block_size);
ASSERT(hash_storage_size <= static_cast<s64>(m_hash_buffer_size));
base_storages[1]->Read(reinterpret_cast<u8*>(m_hash_buffer),
static_cast<size_t>(hash_storage_size), 0);
R_SUCCEED();
}
size_t HierarchicalSha3Storage::Read(u8* buffer, size_t size, size_t offset) const {
if (size == 0)
return size;
ASSERT(buffer != nullptr);
return m_base_storage->Read(buffer, size, offset);
}
} // namespace FileSys

View file

@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <mutex>
#include "core/file_sys/errors.h"
#include "core/file_sys/fssystem/fs_i_storage.h"
#include "core/file_sys/vfs/vfs.h"
namespace FileSys {
class HierarchicalSha3Storage : public IReadOnlyStorage {
YUZU_NON_COPYABLE(HierarchicalSha3Storage);
YUZU_NON_MOVEABLE(HierarchicalSha3Storage);
public:
static constexpr s32 LayerCount = 3;
static constexpr size_t HashSize = 256 / 8; // SHA3-256
public:
HierarchicalSha3Storage() : m_mutex() {}
Result Initialize(VirtualFile* base_storages, s32 layer_count, size_t htbs, void* hash_buf,
size_t hash_buf_size);
virtual size_t GetSize() const override {
return m_base_storage->GetSize();
}
virtual size_t Read(u8* buffer, size_t length, size_t offset) const override;
private:
VirtualFile m_base_storage;
s64 m_base_storage_size{};
char* m_hash_buffer{};
size_t m_hash_buffer_size{};
s32 m_hash_target_block_size{};
s32 m_log_size_ratio{};
std::mutex m_mutex;
};
} // namespace FileSys

View file

@ -1,6 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/settings.h"
#include "core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.h"
#include "core/file_sys/fssystem/fssystem_aes_ctr_storage.h"
#include "core/file_sys/fssystem/fssystem_aes_xts_storage.h"
@ -10,10 +14,12 @@
#include "core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.h"
#include "core/file_sys/fssystem/fssystem_indirect_storage.h"
#include "core/file_sys/fssystem/fssystem_integrity_romfs_storage.h"
#include "core/file_sys/fssystem/fssystem_passthrough_storage.h"
#include "core/file_sys/fssystem/fssystem_memory_resource_buffer_hold_storage.h"
#include "core/file_sys/fssystem/fssystem_nca_file_system_driver.h"
#include "core/file_sys/fssystem/fssystem_sparse_storage.h"
#include "core/file_sys/fssystem/fssystem_switch_storage.h"
#include "core/file_sys/fssystem/fssystem_hierarchical_sha3_storage.h"
#include "core/file_sys/vfs/vfs_offset.h"
#include "core/file_sys/vfs/vfs_vector.h"
@ -299,18 +305,24 @@ Result NcaFileSystemDriver::CreateStorageByRawStorage(VirtualFile* out,
// Process hash/integrity layer.
switch (header_reader->GetHashType()) {
case NcaFsHeader::HashType::HierarchicalSha256Hash:
R_TRY(this->CreateSha256Storage(std::addressof(storage), std::move(storage),
R_TRY(CreateSha256Storage(&storage, std::move(storage),
header_reader->GetHashData().hierarchical_sha256_data));
break;
case NcaFsHeader::HashType::HierarchicalIntegrityHash:
R_TRY(this->CreateIntegrityVerificationStorage(
std::addressof(storage), std::move(storage),
R_TRY(CreateIntegrityVerificationStorage(&storage, std::move(storage),
header_reader->GetHashData().integrity_meta_info));
break;
case NcaFsHeader::HashType::HierarchicalSha3256Hash:
R_TRY(CreateSha3Storage(&storage, std::move(storage),
header_reader->GetHashData().hierarchical_sha256_data));
break;
default:
LOG_ERROR(Loader, "Unhandled Fs HashType enum={}",
static_cast<int>(header_reader->GetHashType()));
R_THROW(ResultInvalidNcaFsHeaderHashType);
}
// Process compression layer.
if (header_reader->ExistsCompressionLayer()) {
R_TRY(this->CreateCompressedStorage(
@ -679,6 +691,7 @@ Result NcaFileSystemDriver::CreateSparseStorageMetaStorageWithVerification(
// Create the verification storage.
VirtualFile integrity_storage;
Result rc = this->CreateIntegrityVerificationStorageForMeta(
std::addressof(integrity_storage), out_layer_info_storage, std::move(decrypted_storage),
meta_offset, meta_data_hash_data_info);
@ -734,8 +747,26 @@ Result NcaFileSystemDriver::CreateSparseStorageWithVerification(
NcaHeader::CtrBlockSize)));
// Check the meta data hash type.
R_UNLESS(meta_data_hash_type == NcaFsHeader::MetaDataHashType::HierarchicalIntegrity,
ResultRomNcaInvalidSparseMetaDataHashType);
if (meta_data_hash_type != NcaFsHeader::MetaDataHashType::HierarchicalIntegrity) {
LOG_ERROR(Loader, "Sparse meta hash type {} not supported for verification; mounting sparse data WITHOUT verification (temporary).", static_cast<int>(meta_data_hash_type));
R_TRY(this->CreateBodySubStorage(std::addressof(body_substorage),
sparse_info.physical_offset,
sparse_info.GetPhysicalSize()));
// Create sparse core directly (no meta verification)
std::shared_ptr<SparseStorage> sparse_storage_fallback;
R_TRY(this->CreateSparseStorageCore(std::addressof(sparse_storage_fallback),
body_substorage, sparse_info.GetPhysicalSize(),
/*meta_storage*/ body_substorage, // dummy; not used
sparse_info, false));
if (out_sparse_storage)
*out_sparse_storage = sparse_storage_fallback;
*out_fs_data_offset = fs_offset;
*out = std::move(sparse_storage_fallback);
R_SUCCEED();
}
// Create the meta storage.
VirtualFile meta_storage;
@ -1093,6 +1124,56 @@ Result NcaFileSystemDriver::CreatePatchMetaStorage(
R_SUCCEED();
}
Result NcaFileSystemDriver::CreateSha3Storage(
VirtualFile* out, VirtualFile base_storage,
const NcaFsHeader::HashData::HierarchicalSha256Data& hash_data) {
ASSERT(out != nullptr);
ASSERT(base_storage != nullptr);
using VerificationStorage = HierarchicalSha3Storage;
R_UNLESS(Common::IsPowerOfTwo(hash_data.hash_block_size),
ResultInvalidHierarchicalSha256BlockSize);
R_UNLESS(hash_data.hash_layer_count == VerificationStorage::LayerCount - 1,
ResultInvalidHierarchicalSha256LayerCount);
const auto& hash_region = hash_data.hash_layer_region[0];
const auto& data_region = hash_data.hash_layer_region[1];
constexpr s32 CacheBlockCount = 2;
const auto hash_buffer_size = static_cast<size_t>(hash_region.size);
const auto cache_buffer_size = CacheBlockCount * hash_data.hash_block_size;
const auto total_buffer_size = hash_buffer_size + cache_buffer_size;
auto buffer_hold_storage = std::make_shared<MemoryResourceBufferHoldStorage>(
std::move(base_storage), total_buffer_size);
R_UNLESS(buffer_hold_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
R_UNLESS(buffer_hold_storage->IsValid(), ResultAllocationMemoryFailedInNcaFileSystemDriverI);
s64 base_size = buffer_hold_storage->GetSize();
R_UNLESS(hash_region.offset + hash_region.size <= base_size, ResultNcaBaseStorageOutOfRangeC);
R_UNLESS(data_region.offset + data_region.size <= base_size, ResultNcaBaseStorageOutOfRangeC);
auto master_hash_storage =
std::make_shared<ArrayVfsFile<sizeof(Hash)>>(hash_data.fs_data_master_hash.value);
auto verification_storage = std::make_shared<VerificationStorage>();
R_UNLESS(verification_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
std::array<VirtualFile, VerificationStorage::LayerCount> layer_storages{
std::make_shared<OffsetVfsFile>(master_hash_storage, sizeof(Hash), 0),
std::make_shared<OffsetVfsFile>(buffer_hold_storage, hash_region.size, hash_region.offset),
std::make_shared<OffsetVfsFile>(buffer_hold_storage, data_region.size, data_region.offset),
};
R_TRY(verification_storage->Initialize(layer_storages.data(), VerificationStorage::LayerCount,
hash_data.hash_block_size,
buffer_hold_storage->GetBuffer(), hash_buffer_size));
*out = std::move(verification_storage);
R_SUCCEED();
}
Result NcaFileSystemDriver::CreateSha256Storage(
VirtualFile* out, VirtualFile base_storage,
const NcaFsHeader::HashData::HierarchicalSha256Data& hash_data) {
@ -1160,6 +1241,7 @@ Result NcaFileSystemDriver::CreateSha256Storage(
Result NcaFileSystemDriver::CreateIntegrityVerificationStorage(
VirtualFile* out, VirtualFile base_storage,
const NcaFsHeader::HashData::IntegrityMetaInfo& meta_info) {
R_RETURN(this->CreateIntegrityVerificationStorageImpl(
out, base_storage, meta_info, 0, IntegrityDataCacheCount, IntegrityHashCacheCount,
HierarchicalIntegrityVerificationStorage::GetDefaultDataCacheBufferLevel(
@ -1209,11 +1291,12 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl(
VirtualFile* out, VirtualFile base_storage,
const NcaFsHeader::HashData::IntegrityMetaInfo& meta_info, s64 layer_info_offset,
int max_data_cache_entries, int max_hash_cache_entries, s8 buffer_level) {
// Validate preconditions.
// Preconditions
ASSERT(out != nullptr);
ASSERT(base_storage != nullptr);
ASSERT(layer_info_offset >= 0);
if (!Settings::values.disable_nca_verification.GetValue()) {
// Define storage types.
using VerificationStorage = HierarchicalIntegrityVerificationStorage;
using StorageInfo = VerificationStorage::HierarchicalStorageInformation;
@ -1266,6 +1349,38 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl(
// Set the output.
*out = std::move(integrity_storage);
R_SUCCEED();
} else {
// Read IVFC layout
HierarchicalIntegrityVerificationInformation lhi{};
std::memcpy(std::addressof(lhi), std::addressof(meta_info.level_hash_info), sizeof(lhi));
R_UNLESS(IntegrityMinLayerCount <= lhi.max_layers,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
R_UNLESS(lhi.max_layers <= IntegrityMaxLayerCount,
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
const auto& data_li = lhi.info[lhi.max_layers - 2];
const s64 base_size = base_storage->GetSize();
// Compute the data layer window
const s64 data_off = (layer_info_offset > 0) ? 0LL : data_li.offset.Get();
R_UNLESS(data_off + data_li.size <= base_size, ResultNcaBaseStorageOutOfRangeD);
if (layer_info_offset > 0) {
R_UNLESS(data_off + data_li.size <= layer_info_offset,
ResultRomNcaInvalidIntegrityLayerInfoOffset);
}
// TODO: Passthrough (temporary compatibility: integrity disabled)
auto data_view = std::make_shared<OffsetVfsFile>(base_storage, data_li.size, data_off);
R_UNLESS(data_view != nullptr, ResultAllocationMemoryFailedAllocateShared);
auto passthrough = std::make_shared<PassthroughStorage>(std::move(data_view));
R_UNLESS(passthrough != nullptr, ResultAllocationMemoryFailedAllocateShared);
*out = std::move(passthrough);
R_SUCCEED();
}
}
Result NcaFileSystemDriver::CreateRegionSwitchStorage(VirtualFile* out,

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -329,6 +332,10 @@ private:
const NcaPatchInfo& patch_info,
const NcaMetaDataHashDataInfo& meta_data_hash_data_info);
Result CreateSha3Storage(VirtualFile* out, VirtualFile base_storage,
const NcaFsHeader::HashData::HierarchicalSha256Data& hash_data);
Result CreateSha256Storage(VirtualFile* out, VirtualFile base_storage,
const NcaFsHeader::HashData::HierarchicalSha256Data& sha256_data);

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -10,11 +13,13 @@ u8 NcaHeader::GetProperKeyGeneration() const {
}
bool NcaPatchInfo::HasIndirectTable() const {
return this->indirect_size != 0;
static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'};
return std::memcmp(indirect_header.data(), BKTR, sizeof(BKTR)) == 0;
}
bool NcaPatchInfo::HasAesCtrExTable() const {
return this->aes_ctr_ex_size != 0;
static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'};
return std::memcmp(aes_ctr_ex_header.data(), BKTR, sizeof(BKTR)) == 0;
}
} // namespace FileSys

View file

@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/file_sys/fssystem/fs_i_storage.h"
#include "core/file_sys/vfs/vfs.h"
namespace FileSys {
//TODO: No integrity verification.
class PassthroughStorage final : public IReadOnlyStorage {
YUZU_NON_COPYABLE(PassthroughStorage);
YUZU_NON_MOVEABLE(PassthroughStorage);
public:
explicit PassthroughStorage(VirtualFile base) : base_(std::move(base)) {}
~PassthroughStorage() override = default;
size_t Read(u8* buffer, size_t size, size_t offset) const override {
if (!base_ || size == 0)
return 0;
return base_->Read(buffer, size, offset);
}
size_t GetSize() const override {
return base_ ? base_->GetSize() : 0;
}
private:
VirtualFile base_{};
};
} // namespace FileSys

View file

@ -1266,6 +1266,10 @@ void KProcess::InitializeInterfaces() {
#ifdef HAS_NCE
if (this->IsApplication() && Settings::IsNceEnabled()) {
// Register the scoped JIT handler before creating any NCE instances
// so that its signal handler will appear first in the signal chain.
Core::ScopedJitExecution::RegisterHandler();
for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
m_arm_interfaces[i] = std::make_unique<Core::ArmNce>(m_kernel.System(), true, i);
}

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -24,6 +27,7 @@ enum class ErrorModule : u32 {
HTCS = 4,
NCM = 5,
DD = 6,
OSDBG = 7,
LR = 8,
Loader = 9,
CMIF = 10,
@ -51,6 +55,7 @@ enum class ErrorModule : u32 {
Util = 33,
TIPC = 35,
ANIF = 37,
CRT = 39,
ETHC = 100,
I2C = 101,
GPIO = 102,
@ -106,6 +111,7 @@ enum class ErrorModule : u32 {
Audio = 153,
NPNS = 154,
NPNSHTTPSTREAM = 155,
IDLE = 156,
ARP = 157,
SWKBD = 158,
BOOT = 159,
@ -115,6 +121,7 @@ enum class ErrorModule : u32 {
Fatal = 163,
NIMShop = 164,
SPSM = 165,
AOC = 166,
BGTC = 167,
UserlandCrash = 168,
SASBUS = 169,
@ -176,13 +183,22 @@ enum class ErrorModule : u32 {
DP2HDMI = 244,
Cradle = 245,
SProfile = 246,
Icm42607p = 248,
NDRM = 250,
Fst2 = 251,
Nex = 306,
NPLN = 321,
TSPM = 499,
DevMenu = 500,
Nverpt = 520,
Am_StuckMonitor = 521,
Pia = 618,
Eagle = 623,
GeneralWebApplet = 800,
WifiWebAuthApplet = 809,
WhitelistedApplet = 810,
ShopN = 811,
Coral = 815
};
/// Encapsulates a Horizon OS error code, allowing it to be separated into its constituent fields.

View file

@ -1,5 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator
// Project// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/service/am/applet.h"
@ -12,7 +15,7 @@ Applet::Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_
process(std::move(process_)), hid_registration(system, *process),
gpu_error_detected_event(context), friend_invitation_storage_channel_event(context),
notification_storage_channel_event(context), health_warning_disappeared_system_event(context),
acquired_sleep_lock_event(context), pop_from_general_channel_event(context),
unknown_event(context), acquired_sleep_lock_event(context), pop_from_general_channel_event(context),
library_applet_launchable_event(context), accumulated_suspended_tick_changed_event(context),
sleep_lock_event(context), state_changed_event(context) {

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -120,6 +123,7 @@ struct Applet {
Event friend_invitation_storage_channel_event;
Event notification_storage_channel_event;
Event health_warning_disappeared_system_event;
Event unknown_event;
Event acquired_sleep_lock_event;
Event pop_from_general_channel_event;
Event library_applet_launchable_event;

View file

@ -18,6 +18,7 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys
// clang-format off
static const FunctionInfo functions[] = {
{100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
{110, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxyEx"},
{200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"},
{201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"},
{300, nullptr, "OpenOverlayAppletProxy"},
@ -25,6 +26,7 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys
{400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
{410, nullptr, "GetSystemAppletControllerForDebug"},
{450, D<&IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions>, "GetSystemProcessCommonFunctions"}, // 19.0.0+
{460, D<&IAllSystemAppletProxiesService::GetAppletAlternativeFunctions>, "GetAppletAlternativeFunctions"}, // 20.0.0+
{1000, nullptr, "GetDebugFunctions"},
};
// clang-format on
@ -99,6 +101,14 @@ Result IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions() {
R_SUCCEED();
}
Result IAllSystemAppletProxiesService::GetAppletAlternativeFunctions() {
LOG_DEBUG(Service_AM, "(STUBBED) called.");
// TODO (maufeat)
R_SUCCEED();
}
std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId(
ProcessId process_id) {
return m_window_system.GetByAppletResourceUserId(process_id.pid);

View file

@ -39,6 +39,7 @@ private:
InCopyHandle<Kernel::KProcess> process_handle,
InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute);
Result GetSystemProcessCommonFunctions();
Result GetAppletAlternativeFunctions();
private:
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);

View file

@ -35,6 +35,7 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
{310, nullptr, "IsSystemAppletHomeMenu"}, //19.0.0+
{320, nullptr, "SetGpuTimeSliceBoost"}, //19.0.0+
{321, nullptr, "SetGpuTimeSliceBoostDueToApplication"}, //19.0.0+
{350, D<&IAppletCommonFunctions::Unknown350>, "Unknown350"} //20.0.0+
};
// clang-format on
@ -70,4 +71,10 @@ Result IAppletCommonFunctions::GetCurrentApplicationId(Out<u64> out_application_
R_SUCCEED();
}
Result IAppletCommonFunctions::Unknown350(Out<u16> out_unknown) {
LOG_WARNING(Service_AM, "(STUBBED) called");
*out_unknown = 0;
R_SUCCEED();
}
} // namespace Service::AM

Some files were not shown because too many files have changed in this diff Show more