mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-10-06 08:12:52 +02:00
Compare commits
44 Commits
v0.0.3.git
...
v0.0.3
Author | SHA1 | Date | |
---|---|---|---|
|
6045627462 | ||
|
b4b361e5e9 | ||
|
0f625fc93c | ||
|
7a9e7e3bd1 | ||
|
421e5073d2 | ||
|
e3cb1cd134 | ||
|
837fffccf4 | ||
|
3d7bfcfb0a | ||
|
7b1f7c21bb | ||
|
0691e532c4 | ||
|
d83fee76ef | ||
|
51201a37e2 | ||
|
656ed8a864 | ||
|
ac30b209e5 | ||
|
f8f98da6b0 | ||
|
4ee1edc229 | ||
|
e3cbae4784 | ||
|
9a8d02358d | ||
|
5c90a3ab35 | ||
|
402704306f | ||
|
bf8fdbf1ec | ||
|
6ed373f9f2 | ||
|
5317775538 | ||
|
3247c53a55 | ||
|
5553f438d1 | ||
|
7f42d11176 | ||
|
31d3e97fa2 | ||
|
b598b7c325 | ||
|
39fd8400ef | ||
|
780d84e422 | ||
|
f390a6ca4c | ||
|
782e1cbc37 | ||
|
8a50d18924 | ||
|
1f2ab3fbc9 | ||
|
59f5c4fa29 | ||
|
62953003ee | ||
|
ad37d20fc1 | ||
|
d461f3af2b | ||
|
5ce16c4b05 | ||
|
489ec2dcb6 | ||
|
31b3e3e0ea | ||
|
f1083a2366 | ||
|
169bc44f0b | ||
|
64ce859a6a |
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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 \
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -52,3 +52,4 @@ Thumbs.db
|
||||
eden-windows-msvc
|
||||
artifacts
|
||||
*.AppImage*
|
||||
/install*
|
||||
|
22
.patch/unordered-dense/0001-cmake.patch
Normal file
22
.patch/unordered-dense/0001-cmake.patch
Normal 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
|
349
CMakeLists.txt
349
CMakeLists.txt
@@ -99,7 +99,6 @@ option(FORCE_DOWNLOAD_WIN_BUNDLES "Forcefully download bundled Windows dependenc
|
||||
|
||||
if (YUZU_USE_CPM AND ENABLE_SDL2)
|
||||
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}")
|
||||
CMAKE_DEPENDENT_OPTION(FORCE_DOWNLOAD_SDL2 "Forcefully download all bundled SDL2 builds (useful for CI)" OFF "YUZU_USE_BUNDLED_SDL2" OFF)
|
||||
endif()
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF)
|
||||
@@ -110,11 +109,7 @@ CMAKE_DEPENDENT_OPTION(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROI
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF)
|
||||
|
||||
if (PLATFORM_FREEBSD)
|
||||
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" OFF)
|
||||
else()
|
||||
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ON)
|
||||
endif()
|
||||
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ${EXT_DEFAULT})
|
||||
|
||||
option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF)
|
||||
|
||||
@@ -143,9 +138,8 @@ endif()
|
||||
|
||||
option(ENABLE_OPENSSL "Enable OpenSSL backend for ISslConnection" ${DEFAULT_ENABLE_OPENSSL})
|
||||
|
||||
if (YUZU_USE_CPM AND ENABLE_OPENSSL)
|
||||
if (ENABLE_OPENSSL)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_OPENSSL "Download bundled OpenSSL build" "${MSVC}" "NOT ANDROID" ON)
|
||||
CMAKE_DEPENDENT_OPTION(FORCE_DOWNLOAD_OPENSSL "Forcefully download all bundled OpenSSL builds (useful for CI)" OFF "YUZU_USE_BUNDLED_OPENSSL" OFF)
|
||||
endif()
|
||||
|
||||
if (ANDROID AND YUZU_DOWNLOAD_ANDROID_VVL)
|
||||
@@ -180,12 +174,12 @@ if (YUZU_USE_PRECOMPILED_HEADERS)
|
||||
set(YUZU_USE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (YUZU_USE_PRECOMPILED_HEADERS)
|
||||
message(STATUS "Using Precompiled Headers.")
|
||||
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
|
||||
endif()
|
||||
|
||||
|
||||
# Default to a Release build
|
||||
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
|
||||
@@ -246,20 +240,24 @@ 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)
|
||||
|
||||
if (EXISTS ${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||
configure_file("${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.json"
|
||||
"${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json"
|
||||
COPYONLY)
|
||||
endif()
|
||||
|
||||
if (ENABLE_COMPATIBILITY_LIST_DOWNLOAD AND NOT EXISTS ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||
message(STATUS "Downloading compatibility list for yuzu...")
|
||||
file(DOWNLOAD
|
||||
https://api.yuzu-emu.org/gamedb/
|
||||
"${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json" SHOW_PROGRESS)
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json "")
|
||||
endif()
|
||||
@@ -303,8 +301,15 @@ if (NOT DEFINED ARCHITECTURE)
|
||||
set(ARCHITECTURE_GENERIC 1)
|
||||
add_definitions(-DARCHITECTURE_GENERIC=1)
|
||||
endif()
|
||||
|
||||
message(STATUS "Target architecture: ${ARCHITECTURE}")
|
||||
|
||||
if (MSVC AND ARCHITECTURE_x86)
|
||||
message(FATAL_ERROR "Attempting to build with the x86 environment is not supported. \
|
||||
This can typically happen if you used the Developer Command Prompt from the start menu;\
|
||||
instead, run vcvars64.bat directly, located at C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat")
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
add_definitions(-DYUZU_UNIX=1)
|
||||
endif()
|
||||
@@ -367,6 +372,15 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
include(CPMUtil)
|
||||
|
||||
# openssl funniness
|
||||
if (ENABLE_OPENSSL)
|
||||
if (YUZU_USE_BUNDLED_OPENSSL)
|
||||
AddJsonPackage(openssl)
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
endif()
|
||||
|
||||
if (YUZU_USE_CPM)
|
||||
message(STATUS "Fetching needed dependencies with CPM")
|
||||
|
||||
@@ -375,36 +389,9 @@ if (YUZU_USE_CPM)
|
||||
|
||||
# TODO(crueter): renderdoc?
|
||||
|
||||
# openssl funniness
|
||||
if (ENABLE_OPENSSL)
|
||||
if (YUZU_USE_BUNDLED_OPENSSL)
|
||||
AddCIPackage(
|
||||
PACKAGE OpenSSL
|
||||
NAME openssl
|
||||
REPO crueter-ci/OpenSSL
|
||||
VERSION 3.5.2
|
||||
MIN_VERSION 1.1.1
|
||||
FORCE_DOWNLOAD ${FORCE_DOWNLOAD_OPENSSL}
|
||||
)
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
endif()
|
||||
|
||||
# boost
|
||||
set(BOOST_INCLUDE_LIBRARIES algorithm icl pool container heap asio headers process filesystem crc variant)
|
||||
AddPackage(
|
||||
NAME Boost
|
||||
REPO boostorg/boost
|
||||
TAG boost-1.88.0
|
||||
ARTIFACT boost-1.88.0-cmake.7z
|
||||
|
||||
HASH e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01
|
||||
|
||||
GIT_VERSION 1.88.0
|
||||
VERSION 1.57
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(boost)
|
||||
|
||||
# really annoying thing where boost::headers doesn't work with cpm
|
||||
# TODO(crueter) investigate
|
||||
@@ -419,6 +406,12 @@ if (YUZU_USE_CPM)
|
||||
|
||||
if (NOT MSVC)
|
||||
# boost sucks
|
||||
# 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)
|
||||
target_compile_options(boost_icl INTERFACE -Wno-shadow)
|
||||
target_compile_options(boost_asio INTERFACE -Wno-conversion -Wno-implicit-fallthrough)
|
||||
@@ -426,128 +419,98 @@ if (YUZU_USE_CPM)
|
||||
endif()
|
||||
|
||||
# fmt
|
||||
AddPackage(
|
||||
NAME fmt
|
||||
REPO fmtlib/fmt
|
||||
SHA 40626af88b
|
||||
HASH d59f06c24339f223de4ec2afeba1c67b5835a0f350a1ffa86242a72fc3e616a6b8b21798355428d4200c75287308b66634619ffa0b52ba5bd74cc01772ea1a8a
|
||||
VERSION 8
|
||||
OPTIONS
|
||||
"FMT_INSTALL OFF"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(fmt)
|
||||
|
||||
# lz4
|
||||
AddPackage(
|
||||
NAME lz4
|
||||
REPO lz4/lz4
|
||||
SHA ebb370ca83
|
||||
HASH 43600e87b35256005c0f2498fa56a77de6783937ba4cfce38c099f27c03188d097863e8a50c5779ca0a7c63c29c4f7ed0ae526ec798c1fd2e3736861b62e0a37
|
||||
SOURCE_SUBDIR build/cmake
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(lz4)
|
||||
|
||||
if (lz4_ADDED)
|
||||
add_library(lz4::lz4 ALIAS lz4_static)
|
||||
endif()
|
||||
|
||||
# nlohmann
|
||||
AddPackage(
|
||||
NAME nlohmann_json
|
||||
REPO nlohmann/json
|
||||
SHA 55f93686c0
|
||||
HASH b739749b066800e21154506ea150d2c5cbce8a45344177f46f884547a1399d26753166fd0df8135269ce28cf223552b1b65cd625b88c844d54753f2434900486
|
||||
VERSION 3.8
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(nlohmann)
|
||||
|
||||
# zlib
|
||||
AddPackage(
|
||||
NAME ZLIB
|
||||
REPO madler/zlib
|
||||
SHA 51b7f2abda
|
||||
HASH 16eaf1f3752489d12fd9ce30f7b5f7cbd5cb8ff53d617005a9847ae72d937f65e01e68be747f62d7ac19fd0c9aeba9956e60f16d6b465c5fdc2f3d08b4db2e6c
|
||||
VERSION 1.2
|
||||
OPTIONS
|
||||
"ZLIB_BUILD_SHARED OFF"
|
||||
"ZLIB_INSTALL OFF"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(zlib)
|
||||
|
||||
if (ZLIB_ADDED)
|
||||
add_library(ZLIB::ZLIB ALIAS zlibstatic)
|
||||
endif()
|
||||
|
||||
# zstd
|
||||
AddPackage(
|
||||
NAME zstd
|
||||
REPO facebook/zstd
|
||||
SHA f8745da6ff
|
||||
HASH 3037007f990040fe32573b46f9bef8762fd5dbeeb07ffffcbfeba51ec98167edae39bb9c87f9299efcd61c4e467c5e84f7c19f0df7799bc1fc04864a278792ee
|
||||
VERSION 1.5
|
||||
SOURCE_SUBDIR build/cmake
|
||||
OPTIONS
|
||||
"ZSTD_BUILD_SHARED OFF"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(zstd)
|
||||
|
||||
if (zstd_ADDED)
|
||||
add_library(zstd::zstd ALIAS libzstd_static)
|
||||
endif()
|
||||
|
||||
# Catch2
|
||||
if (YUZU_TESTS OR DYNARMIC_TESTS)
|
||||
AddPackage(
|
||||
NAME Catch2
|
||||
REPO catchorg/Catch2
|
||||
SHA 644821ce28
|
||||
HASH f8795f98acf2c02c0db8e734cc866d5caebab4b4a306e93598b97cb3c0c728dafe8283dce27ffe8d42460e5ae7302f3f32e7e274a7f991b73511ac88eef21b1f
|
||||
VERSION 3.0.1
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(catch2)
|
||||
endif()
|
||||
|
||||
# ENet
|
||||
AddPackage(
|
||||
NAME enet
|
||||
REPO lsalzman/enet
|
||||
SHA 2662c0de09
|
||||
VERSION 1.3
|
||||
HASH 3de1beb4fa3d6b1e03eda8dd1e7580694f854af3ed3975dcdabfdcdf76b97f322b9734d35ea7f185855bb490d957842b938b26da4dd2dfded509390f8d2794dd
|
||||
FIND_PACKAGE_ARGUMENTS "MODULE"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(enet)
|
||||
|
||||
if (enet_ADDED)
|
||||
target_include_directories(enet INTERFACE ${enet_SOURCE_DIR}/include)
|
||||
endif()
|
||||
|
||||
# Opus
|
||||
AddPackage(
|
||||
NAME Opus
|
||||
VERSION 1.3
|
||||
REPO "xiph/opus"
|
||||
SHA 5ded705cf4
|
||||
HASH 0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203
|
||||
FIND_PACKAGE_ARGUMENTS "MODULE"
|
||||
OPTIONS
|
||||
"OPUS_BUILD_TESTING OFF"
|
||||
"OPUS_BUILD_PROGRAMS OFF"
|
||||
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF"
|
||||
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(opus)
|
||||
else()
|
||||
# Enforce the search mode of non-required packages for better and shorter failure messages
|
||||
find_package(fmt 8 REQUIRED)
|
||||
find_package(LLVM MODULE COMPONENTS Demangle)
|
||||
find_package(nlohmann_json 3.8 REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
find_package(RenderDoc MODULE)
|
||||
find_package(stb MODULE)
|
||||
find_package(enet 1.3 MODULE REQUIRED)
|
||||
find_package(Opus 1.3 MODULE REQUIRED)
|
||||
find_package(ZLIB 1.2 REQUIRED)
|
||||
find_package(zstd 1.5 REQUIRED MODULE)
|
||||
|
||||
if (YUZU_TESTS)
|
||||
find_package(Catch2 3.0.1 REQUIRED)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
|
||||
find_package(gamemode 1.7 MODULE)
|
||||
endif()
|
||||
|
||||
if (ENABLE_OPENSSL)
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TARGET Boost::headers)
|
||||
AddJsonPackage(boost_headers)
|
||||
endif()
|
||||
|
||||
if (ENABLE_LIBUSB)
|
||||
if (PLATFORM_FREEBSD)
|
||||
find_package(libusb MODULE)
|
||||
else()
|
||||
find_package(libusb 1.0.24 MODULE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# DiscordRPC
|
||||
if (USE_DISCORD_PRESENCE)
|
||||
AddJsonPackage(discord-rpc)
|
||||
|
||||
target_include_directories(discord-rpc INTERFACE ${discord-rpc_SOURCE_DIR}/include)
|
||||
add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
|
||||
endif()
|
||||
|
||||
# SimpleIni
|
||||
AddJsonPackage(simpleini)
|
||||
|
||||
# Most linux distros don't package cubeb, so enable regardless of cpm settings
|
||||
if(ENABLE_CUBEB)
|
||||
AddPackage(
|
||||
NAME cubeb
|
||||
REPO "mozilla/cubeb"
|
||||
SHA fa02160712
|
||||
HASH 82d808356752e4064de48c8fecbe7856715ade1e76b53937116bf07129fc1cc5b3de5e4b408de3cd000187ba8dc32ca4109661cb7e0355a52e54bd81b9be1c61
|
||||
FIND_PACKAGE_ARGUMENTS "CONFIG" # not sure this works outside of gentoo
|
||||
OPTIONS
|
||||
"USE_SANITIZERS OFF"
|
||||
"BUILD_TESTS OFF"
|
||||
"BUILD_TOOLS OFF"
|
||||
"BUNDLE_SPEEX ON"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
AddJsonPackage(cubeb)
|
||||
|
||||
if (cubeb_ADDED)
|
||||
if (NOT MSVC)
|
||||
@@ -571,96 +534,10 @@ if (YUZU_USE_CPM)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# Enforce the search mode of non-required packages for better and shorter failure messages
|
||||
find_package(fmt 8 REQUIRED)
|
||||
find_package(LLVM MODULE COMPONENTS Demangle)
|
||||
find_package(nlohmann_json 3.8 REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
find_package(RenderDoc MODULE)
|
||||
find_package(stb MODULE)
|
||||
find_package(enet 1.3 MODULE)
|
||||
find_package(Opus 1.3 MODULE)
|
||||
find_package(ZLIB 1.2 REQUIRED)
|
||||
find_package(zstd 1.5 REQUIRED)
|
||||
|
||||
if (ENABLE_CUBEB)
|
||||
find_package(cubeb CONFIG)
|
||||
endif()
|
||||
|
||||
if (YUZU_TESTS)
|
||||
find_package(Catch2 3.0.1 REQUIRED)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
|
||||
find_package(gamemode 1.7 MODULE)
|
||||
endif()
|
||||
|
||||
if (ENABLE_OPENSSL)
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TARGET Boost::headers)
|
||||
AddPackage(
|
||||
NAME boost_headers
|
||||
REPO "boostorg/headers"
|
||||
SHA 0456900fad
|
||||
HASH 50cd75dcdfc5f082225cdace058f47b4fb114a47585f7aee1d22236a910a80b667186254c214fa2fcebac67ae6d37ba4b6e695e1faea8affd6fd42a03cf996e3
|
||||
BUNDLED_PACKAGE ON
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
endif()
|
||||
|
||||
if (ENABLE_LIBUSB)
|
||||
if (PLATFORM_FREEBSD)
|
||||
find_package(libusb MODULE)
|
||||
else()
|
||||
find_package(libusb 1.0.24 MODULE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# DiscordRPC
|
||||
if (USE_DISCORD_PRESENCE)
|
||||
AddPackage(
|
||||
NAME discord-rpc
|
||||
REPO "discord/discord-rpc"
|
||||
SHA 963aa9f3e5
|
||||
HASH 386e1344e9a666d730f2d335ee3aef1fd05b1039febefd51aa751b705009cc764411397f3ca08dffd46205c72f75b235c870c737b2091a4ed0c3b061f5919bde
|
||||
OPTIONS
|
||||
"BUILD_EXAMPLES OFF"
|
||||
PATCHES
|
||||
${CMAKE_SOURCE_DIR}/.patch/discord-rpc/0001-cmake-version.patch
|
||||
${CMAKE_SOURCE_DIR}/.patch/discord-rpc/0002-no-clang-format.patch
|
||||
${CMAKE_SOURCE_DIR}/.patch/discord-rpc/0003-fix-cpp17.patch
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
|
||||
target_include_directories(discord-rpc INTERFACE ${discord-rpc_SOURCE_DIR}/include)
|
||||
add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
|
||||
endif()
|
||||
|
||||
# SimpleIni
|
||||
AddPackage(
|
||||
NAME SimpleIni
|
||||
REPO brofield/simpleini
|
||||
SHA 09c21bda1d
|
||||
HASH 99779ca9b6e040d36558cadf484f9ffdab5b47bcc8fc72e4d33639d1d60c0ceb4410d335ba445d72a4324e455167fd6769d99b459943aa135bec085dff2d4b7c
|
||||
FIND_PACKAGE_ARGUMENTS "MODULE"
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
|
||||
# TODO(crueter): Work around this
|
||||
if (NOT YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SPIRV-Tools REQUIRED SPIRV-Tools)
|
||||
endif()
|
||||
|
||||
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package
|
||||
if (ENABLE_SDL2)
|
||||
# this was hard to get right, but ultimately I decided to make it so that FORCE_DOWNLOAD_SDL2 also downloads the
|
||||
# external one. Really silly behavior imo but in the interest of getting something out there I'm leaving it for now
|
||||
if (YUZU_USE_EXTERNAL_SDL2 OR FORCE_DOWNLOAD_SDL2)
|
||||
if (YUZU_USE_EXTERNAL_SDL2)
|
||||
message(STATUS "Using SDL2 from externals.")
|
||||
if (NOT WIN32)
|
||||
# Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers
|
||||
@@ -683,37 +560,14 @@ if (ENABLE_SDL2)
|
||||
endif()
|
||||
|
||||
if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck")
|
||||
set(SDL_HASH cc016b0046)
|
||||
set(SDL_PIPEWIRE OFF) # build errors out with this on
|
||||
set(SDL_SHA512SUM 34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b)
|
||||
AddJsonPackage("sdl2_steamdeck")
|
||||
else()
|
||||
set(SDL_HASH 54772f345a)
|
||||
set(SDL_SHA512SUM 2a68a0e01c390043aa9d9df63d8a20a52076c88bb460ac4e0f33194ca7d9bc8fadbbcc04e7506872ac4b6354a73fbc267c036f82200da59465789b87c7d9e3a4)
|
||||
AddJsonPackage("sdl2_generic")
|
||||
endif()
|
||||
|
||||
AddPackage(
|
||||
NAME SDL2
|
||||
REPO "libsdl-org/SDL"
|
||||
SHA ${SDL_HASH}
|
||||
HASH ${SDL_SHA512SUM}
|
||||
KEY ${YUZU_SYSTEM_PROFILE}
|
||||
BUNDLED_PACKAGE ON
|
||||
EXCLUDE_FROM_ALL ON
|
||||
)
|
||||
endif()
|
||||
|
||||
if (YUZU_USE_BUNDLED_SDL2)
|
||||
elseif (YUZU_USE_BUNDLED_SDL2)
|
||||
message(STATUS "Using bundled SDL2")
|
||||
AddCIPackage(
|
||||
PACKAGE SDL2
|
||||
NAME SDL2
|
||||
REPO crueter-ci/SDL2
|
||||
VERSION 2.32.8
|
||||
MIN_VERSION 2.26.4
|
||||
CMAKE_FILENAME sdl2
|
||||
FORCE_DOWNLOAD ${FORCE_DOWNLOAD_SDL2}
|
||||
TARGET "SDL2::SDL2"
|
||||
)
|
||||
AddJsonPackage(sdl2)
|
||||
endif()
|
||||
|
||||
find_package(SDL2 2.26.4 REQUIRED)
|
||||
@@ -750,6 +604,7 @@ add_subdirectory(externals)
|
||||
find_package(VulkanHeaders)
|
||||
find_package(VulkanUtilityLibraries)
|
||||
find_package(VulkanMemoryAllocator)
|
||||
find_package(SPIRV-Tools)
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
find_package(httplib)
|
||||
@@ -1003,14 +858,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()
|
||||
|
@@ -1,28 +1,220 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# Created-By: crueter
|
||||
# Docs will come at a later date, mostly this is to just reduce boilerplate
|
||||
# and some cmake magic to allow for runtime viewing of dependency versions
|
||||
|
||||
include(CMakeDependentOption)
|
||||
# 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?
|
||||
|
||||
if (MSVC OR ANDROID)
|
||||
set(SYSTEM_DEFAULT OFF)
|
||||
set(BUNDLED_DEFAULT OFF)
|
||||
else()
|
||||
set(SYSTEM_DEFAULT ON)
|
||||
set(BUNDLED_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(CPMUTIL_DEFAULT_SYSTEM
|
||||
"Allow usage of system packages for CPM dependencies" ${SYSTEM_DEFAULT}
|
||||
"NOT ANDROID" OFF)
|
||||
option(CPMUTIL_FORCE_BUNDLED
|
||||
"Force bundled packages for all CPM depdendencies" ${BUNDLED_DEFAULT})
|
||||
|
||||
option(CPMUTIL_FORCE_SYSTEM
|
||||
"Force system packages for all CPM dependencies (NOT RECOMMENDED)" OFF)
|
||||
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
include(CPM)
|
||||
|
||||
# TODO(crueter): Better solution for separate cpmfiles e.g. per-directory
|
||||
set(CPMUTIL_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json" CACHE STRING "Location of cpmfile.json")
|
||||
|
||||
if (EXISTS ${CPMUTIL_JSON_FILE})
|
||||
file(READ ${CPMUTIL_JSON_FILE} CPMFILE_CONTENT)
|
||||
else()
|
||||
message(WARNING "[CPMUtil] cpmfile ${CPMUTIL_JSON_FILE} does not exist, AddJsonPackage will be a no-op")
|
||||
endif()
|
||||
|
||||
# utility
|
||||
function(cpm_utils_message level name message)
|
||||
message(${level} "[CPMUtil] ${name}: ${message}")
|
||||
endfunction()
|
||||
|
||||
# utility
|
||||
function(array_to_list array length out)
|
||||
math(EXPR range "${length} - 1")
|
||||
|
||||
foreach(IDX RANGE ${range})
|
||||
string(JSON _element GET "${array}" "${IDX}")
|
||||
|
||||
list(APPEND NEW_LIST ${_element})
|
||||
endforeach()
|
||||
|
||||
set("${out}" "${NEW_LIST}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# utility
|
||||
function(get_json_element object out member default)
|
||||
string(JSON out_type ERROR_VARIABLE err TYPE "${object}" ${member})
|
||||
|
||||
if (err)
|
||||
set("${out}" "${default}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(JSON outvar GET "${object}" ${member})
|
||||
|
||||
if (out_type STREQUAL "ARRAY")
|
||||
string(JSON _len LENGTH "${object}" ${member})
|
||||
# array_to_list("${outvar}" ${_len} outvar)
|
||||
set("${out}_LENGTH" "${_len}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
set("${out}" "${outvar}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Kinda cancerous but whatever
|
||||
function(AddJsonPackage)
|
||||
set(oneValueArgs
|
||||
NAME
|
||||
|
||||
# these are overrides that can be generated at runtime, so can be defined separately from the json
|
||||
DOWNLOAD_ONLY
|
||||
SYSTEM_PACKAGE
|
||||
BUNDLED_PACKAGE
|
||||
)
|
||||
|
||||
set(multiValueArgs OPTIONS)
|
||||
|
||||
cmake_parse_arguments(JSON "" "${oneValueArgs}" "${multiValueArgs}"
|
||||
"${ARGN}")
|
||||
|
||||
list(LENGTH ARGN argnLength)
|
||||
# single name argument
|
||||
if(argnLength EQUAL 1)
|
||||
set(JSON_NAME "${ARGV0}")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED CPMFILE_CONTENT)
|
||||
cpm_utils_message(WARNING ${name} "No cpmfile, AddJsonPackage is a no-op")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED JSON_NAME)
|
||||
cpm_utils_message(FATAL_ERROR "json package" "No name specified")
|
||||
endif()
|
||||
|
||||
string(JSON object ERROR_VARIABLE err GET "${CPMFILE_CONTENT}" "${JSON_NAME}")
|
||||
|
||||
if (err)
|
||||
cpm_utils_message(FATAL_ERROR ${JSON_NAME} "Not found in cpmfile")
|
||||
endif()
|
||||
|
||||
get_json_element("${object}" package package ${JSON_NAME})
|
||||
get_json_element("${object}" repo repo "")
|
||||
get_json_element("${object}" ci ci OFF)
|
||||
get_json_element("${object}" version version "")
|
||||
|
||||
if (ci)
|
||||
get_json_element("${object}" name name "${JSON_NAME}")
|
||||
get_json_element("${object}" extension extension "tar.zst")
|
||||
get_json_element("${object}" min_version min_version "")
|
||||
get_json_element("${object}" cmake_filename cmake_filename "")
|
||||
get_json_element("${object}" raw_disabled disabled_platforms "")
|
||||
|
||||
if (raw_disabled)
|
||||
array_to_list("${raw_disabled}" ${raw_disabled_LENGTH} disabled_platforms)
|
||||
else()
|
||||
set(disabled_platforms "")
|
||||
endif()
|
||||
|
||||
AddCIPackage(
|
||||
VERSION ${version}
|
||||
NAME ${name}
|
||||
REPO ${repo}
|
||||
PACKAGE ${package}
|
||||
EXTENSION ${extension}
|
||||
MIN_VERSION ${min_version}
|
||||
DISABLED_PLATFORMS ${disabled_platforms}
|
||||
CMAKE_FILENAME ${cmake_filename}
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_json_element("${object}" hash hash "")
|
||||
get_json_element("${object}" sha sha "")
|
||||
get_json_element("${object}" url url "")
|
||||
get_json_element("${object}" key key "")
|
||||
get_json_element("${object}" tag tag "")
|
||||
get_json_element("${object}" artifact artifact "")
|
||||
get_json_element("${object}" git_version git_version "")
|
||||
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 "")
|
||||
|
||||
# format patchdir
|
||||
if (raw_patches)
|
||||
math(EXPR range "${raw_patches_LENGTH} - 1")
|
||||
|
||||
foreach(IDX RANGE ${range})
|
||||
string(JSON _patch GET "${raw_patches}" "${IDX}")
|
||||
|
||||
set(full_patch "${CMAKE_SOURCE_DIR}/.patch/${JSON_NAME}/${_patch}")
|
||||
if (NOT EXISTS ${full_patch})
|
||||
cpm_utils_message(FATAL_ERROR ${JSON_NAME} "specifies patch ${full_patch} which does not exist")
|
||||
endif()
|
||||
|
||||
list(APPEND patches "${full_patch}")
|
||||
endforeach()
|
||||
endif()
|
||||
# end format patchdir
|
||||
|
||||
# options
|
||||
get_json_element("${object}" raw_options options "")
|
||||
|
||||
if (raw_options)
|
||||
array_to_list("${raw_options}" ${raw_options_LENGTH} options)
|
||||
endif()
|
||||
|
||||
set(options ${options} ${JSON_OPTIONS})
|
||||
|
||||
# end options
|
||||
|
||||
# system/bundled
|
||||
if (bundled STREQUAL "unset" AND DEFINED JSON_BUNDLED_PACKAGE)
|
||||
set(bundled ${JSON_BUNDLED_PACKAGE})
|
||||
endif()
|
||||
|
||||
AddPackage(
|
||||
NAME "${package}"
|
||||
VERSION "${version}"
|
||||
URL "${url}"
|
||||
HASH "${hash}"
|
||||
SHA "${sha}"
|
||||
REPO "${repo}"
|
||||
KEY "${key}"
|
||||
PATCHES "${patches}"
|
||||
OPTIONS "${options}"
|
||||
FIND_PACKAGE_ARGUMENTS "${find_args}"
|
||||
BUNDLED_PACKAGE "${bundled}"
|
||||
SOURCE_SUBDIR "${source_subdir}"
|
||||
|
||||
GIT_VERSION ${git_version}
|
||||
ARTIFACT ${artifact}
|
||||
TAG ${tag}
|
||||
)
|
||||
|
||||
# pass stuff to parent scope
|
||||
set(${package}_ADDED "${${package}_ADDED}"
|
||||
PARENT_SCOPE)
|
||||
set(${package}_SOURCE_DIR "${${package}_SOURCE_DIR}"
|
||||
PARENT_SCOPE)
|
||||
set(${package}_BINARY_DIR "${${package}_BINARY_DIR}"
|
||||
PARENT_SCOPE)
|
||||
|
||||
endfunction()
|
||||
|
||||
function(AddPackage)
|
||||
cpm_set_policies()
|
||||
|
||||
@@ -64,10 +256,8 @@ function(AddPackage)
|
||||
GIT_URL
|
||||
|
||||
KEY
|
||||
DOWNLOAD_ONLY
|
||||
FIND_PACKAGE_ARGUMENTS
|
||||
SYSTEM_PACKAGE
|
||||
BUNDLED_PACKAGE
|
||||
FIND_PACKAGE_ARGUMENTS
|
||||
)
|
||||
|
||||
set(multiValueArgs OPTIONS PATCHES)
|
||||
@@ -79,6 +269,9 @@ function(AddPackage)
|
||||
cpm_utils_message(FATAL_ERROR "package" "No package name defined")
|
||||
endif()
|
||||
|
||||
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 (DEFINED PKG_ARGS_URL)
|
||||
set(pkg_url ${PKG_ARGS_URL})
|
||||
|
||||
@@ -124,9 +317,9 @@ 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_VERSION})
|
||||
elseif(DEFINED PKG_ARGS_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)
|
||||
@@ -178,25 +371,55 @@ function(AddPackage)
|
||||
if (DEFINED hash_url)
|
||||
set(outfile ${CMAKE_CURRENT_BINARY_DIR}/${PKG_ARGS_NAME}.hash)
|
||||
|
||||
# TODO(crueter): This is kind of a bad solution
|
||||
# because "technically" the hash is invalidated each week
|
||||
# but it works for now kjsdnfkjdnfjksdn
|
||||
string(TOLOWER ${PKG_ARGS_NAME} lowername)
|
||||
if (NOT EXISTS ${outfile} AND NOT EXISTS ${CPM_SOURCE_CACHE}/${lowername}/${pkg_key})
|
||||
file(DOWNLOAD ${hash_url} ${outfile})
|
||||
file(READ ${outfile} pkg_hash_tmp)
|
||||
file(REMOVE ${outfile})
|
||||
endif()
|
||||
|
||||
if (EXISTS ${outfile})
|
||||
file(READ ${outfile} pkg_hash_tmp)
|
||||
endif()
|
||||
|
||||
if (DEFINED ${pkg_hash_tmp})
|
||||
set(pkg_hash "${hash_algo}=${pkg_hash_tmp}")
|
||||
endif()
|
||||
|
||||
if (NOT CPMUTIL_DEFAULT_SYSTEM)
|
||||
set(CPM_USE_LOCAL_PACKAGES OFF)
|
||||
elseif (DEFINED PKG_ARGS_SYSTEM_PACKAGE)
|
||||
set(CPM_USE_LOCAL_PACKAGES ${PKG_ARGS_SYSTEM_PACKAGE})
|
||||
elseif (DEFINED PKG_ARGS_BUNDLED_PACKAGE)
|
||||
if (PKG_ARGS_BUNDLED_PACKAGE)
|
||||
set(CPM_USE_LOCAL_PACKAGES OFF)
|
||||
else()
|
||||
set(CPM_USE_LOCAL_PACKAGES ON)
|
||||
endif()
|
||||
|
||||
macro(set_precedence local force)
|
||||
set(CPM_USE_LOCAL_PACKAGES ${local})
|
||||
set(CPM_LOCAL_PACKAGES_ONLY ${force})
|
||||
endmacro()
|
||||
|
||||
#[[
|
||||
Precedence:
|
||||
- package_FORCE_SYSTEM
|
||||
- package_FORCE_BUNDLED
|
||||
- CPMUTIL_FORCE_SYSTEM
|
||||
- CPMUTIL_FORCE_BUNDLED
|
||||
- BUNDLED_PACKAGE
|
||||
- default to allow local
|
||||
]]#
|
||||
if (${PKG_ARGS_NAME}_FORCE_SYSTEM)
|
||||
set_precedence(ON ON)
|
||||
elseif (${PKG_ARGS_NAME}_FORCE_BUNDLED)
|
||||
set_precedence(OFF OFF)
|
||||
elseif (CPMUTIL_FORCE_SYSTEM)
|
||||
set_precedence(ON ON)
|
||||
elseif(CPMUTIL_FORCE_BUNDLED)
|
||||
set_precedence(OFF OFF)
|
||||
elseif (DEFINED PKG_ARGS_BUNDLED_PACKAGE AND NOT PKG_ARGS_BUNDLED_PACKAGE STREQUAL "unset")
|
||||
if (PKG_ARGS_BUNDLED_PACKAGE)
|
||||
set(local OFF)
|
||||
else()
|
||||
set(CPM_USE_LOCAL_PACKAGES ON)
|
||||
set(local ON)
|
||||
endif()
|
||||
|
||||
set_precedence(${local} OFF)
|
||||
else()
|
||||
set_precedence(ON OFF)
|
||||
endif()
|
||||
|
||||
CPMAddPackage(
|
||||
@@ -210,6 +433,7 @@ function(AddPackage)
|
||||
|
||||
OPTIONS ${PKG_ARGS_OPTIONS}
|
||||
PATCHES ${PKG_ARGS_PATCHES}
|
||||
EXCLUDE_FROM_ALL ON
|
||||
|
||||
${PKG_ARGS_UNPARSED_ARGUMENTS}
|
||||
)
|
||||
@@ -257,7 +481,7 @@ function(add_ci_package key)
|
||||
set(ARTIFACT ${ARTIFACT_NAME}-${key}-${ARTIFACT_VERSION}.${ARTIFACT_EXT})
|
||||
|
||||
AddPackage(
|
||||
NAME ${ARTIFACT_PACKAGE}-${key}
|
||||
NAME ${ARTIFACT_PACKAGE}
|
||||
REPO ${ARTIFACT_REPO}
|
||||
TAG v${ARTIFACT_VERSION}
|
||||
VERSION ${ARTIFACT_VERSION}
|
||||
@@ -266,15 +490,12 @@ function(add_ci_package key)
|
||||
KEY ${key}
|
||||
HASH_SUFFIX sha512sum
|
||||
BUNDLED_PACKAGE ON
|
||||
DOWNLOAD_ONLY ON
|
||||
)
|
||||
|
||||
if (NOT ARTIFACT_FORCE_DOWNLOAD OR ARTIFACT_OVERRIDE)
|
||||
set(ARTIFACT_DIR ${${ARTIFACT_PACKAGE}-${key}_SOURCE_DIR} PARENT_SCOPE)
|
||||
endif()
|
||||
set(ARTIFACT_DIR ${${ARTIFACT_PACKAGE}_SOURCE_DIR} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# TODO(crueter): doc
|
||||
# name is the artifact name, package is for find_package override
|
||||
function(AddCIPackage)
|
||||
set(oneValueArgs
|
||||
VERSION
|
||||
@@ -282,11 +503,9 @@ function(AddCIPackage)
|
||||
REPO
|
||||
PACKAGE
|
||||
EXTENSION
|
||||
FORCE_DOWNLOAD
|
||||
MIN_VERSION
|
||||
DISABLED_PLATFORMS
|
||||
CMAKE_FILENAME
|
||||
TARGET
|
||||
)
|
||||
|
||||
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "" ${ARGN})
|
||||
@@ -316,12 +535,6 @@ function(AddCIPackage)
|
||||
set(ARTIFACT_EXT ${PKG_ARGS_EXTENSION})
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED PKG_ARGS_FORCE_DOWNLOAD)
|
||||
set(ARTIFACT_FORCE_DOWNLOAD OFF)
|
||||
else()
|
||||
set(ARTIFACT_FORCE_DOWNLOAD ${PKG_ARGS_FORCE_DOWNLOAD})
|
||||
endif()
|
||||
|
||||
if (DEFINED PKG_ARGS_MIN_VERSION)
|
||||
set(ARTIFACT_MIN_VERSION ${PKG_ARGS_MIN_VERSION})
|
||||
endif()
|
||||
@@ -336,86 +549,42 @@ function(AddCIPackage)
|
||||
set(ARTIFACT_REPO ${PKG_ARGS_REPO})
|
||||
set(ARTIFACT_PACKAGE ${PKG_ARGS_PACKAGE})
|
||||
|
||||
if ((MSVC AND ARCHITECTURE_x86_64) OR ARTIFACT_FORCE_DOWNLOAD AND NOT "windows-amd64" IN_LIST DISABLED_PLATFORMS)
|
||||
# kinda hacky
|
||||
if(MSVC AND ARCHITECTURE_x86_64)
|
||||
set(ARTIFACT_OVERRIDE ON)
|
||||
endif()
|
||||
|
||||
if ((MSVC AND ARCHITECTURE_x86_64) AND NOT "windows-amd64" IN_LIST DISABLED_PLATFORMS)
|
||||
add_ci_package(windows-amd64)
|
||||
set(ARTIFACT_OVERRIDE OFF)
|
||||
endif()
|
||||
|
||||
if ((MSVC AND ARCHITECTURE_arm64) OR ARTIFACT_FORCE_DOWNLOAD AND NOT "windows-arm64" IN_LIST DISABLED_PLATFORMS)
|
||||
if(MSVC AND ARCHITECTURE_arm64)
|
||||
set(ARTIFACT_OVERRIDE ON)
|
||||
endif()
|
||||
|
||||
if ((MSVC AND ARCHITECTURE_arm64) AND NOT "windows-arm64" IN_LIST DISABLED_PLATFORMS)
|
||||
add_ci_package(windows-arm64)
|
||||
set(ARTIFACT_OVERRIDE OFF)
|
||||
endif()
|
||||
|
||||
if (ANDROID OR ARTIFACT_FORCE_DOWNLOAD AND NOT "android" IN_LIST DISABLED_PLATFORMS)
|
||||
if(ANDROID)
|
||||
set(ARTIFACT_OVERRIDE ON)
|
||||
endif()
|
||||
|
||||
if (ANDROID AND NOT "android" IN_LIST DISABLED_PLATFORMS)
|
||||
add_ci_package(android)
|
||||
set(ARTIFACT_OVERRIDE OFF)
|
||||
endif()
|
||||
|
||||
if(PLATFORM_SUN OR ARTIFACT_FORCE_DOWNLOAD AND NOT "solaris" IN_LIST DISABLED_PLATFORMS)
|
||||
if(PLATFORM_SUN)
|
||||
set(ARTIFACT_OVERRIDE ON)
|
||||
endif()
|
||||
|
||||
if(PLATFORM_SUN AND NOT "solaris" IN_LIST DISABLED_PLATFORMS)
|
||||
add_ci_package(solaris)
|
||||
set(ARTIFACT_OVERRIDE OFF)
|
||||
endif()
|
||||
|
||||
if(PLATFORM_FREEBSD OR ARTIFACT_FORCE_DOWNLOAD AND NOT "freebsd" IN_LIST DISABLED_PLATFORMS)
|
||||
if(PLATFORM_FREEBSD)
|
||||
set(ARTIFACT_OVERRIDE ON)
|
||||
endif()
|
||||
|
||||
if(PLATFORM_FREEBSD AND NOT "freebsd" IN_LIST DISABLED_PLATFORMS)
|
||||
add_ci_package(freebsd)
|
||||
set(ARTIFACT_OVERRIDE OFF)
|
||||
endif()
|
||||
|
||||
if((PLATFORM_LINUX AND ARCHITECTURE_x86_64) OR ARTIFACT_FORCE_DOWNLOAD AND NOT "linux" IN_LIST DISABLED_PLATFORMS)
|
||||
if(PLATFORM_LINUX AND ARCHITECTURE_x86_64)
|
||||
set(ARTIFACT_OVERRIDE ON)
|
||||
endif()
|
||||
|
||||
if((PLATFORM_LINUX AND ARCHITECTURE_x86_64) AND NOT "linux" IN_LIST DISABLED_PLATFORMS)
|
||||
add_ci_package(linux)
|
||||
set(ARTIFACT_OVERRIDE OFF)
|
||||
endif()
|
||||
|
||||
if((PLATFORM_LINUX AND ARCHITECTURE_arm64) OR ARTIFACT_FORCE_DOWNLOAD AND NOT "linux-aarch64" IN_LIST DISABLED_PLATFORMS)
|
||||
if(PLATFORM_LINUX AND ARCHITECTURE_arm64)
|
||||
set(ARTIFACT_OVERRIDE ON)
|
||||
endif()
|
||||
|
||||
if((PLATFORM_LINUX AND ARCHITECTURE_arm64) AND NOT "linux-aarch64" IN_LIST DISABLED_PLATFORMS)
|
||||
add_ci_package(linux-aarch64)
|
||||
set(ARTIFACT_OVERRIDE OFF)
|
||||
endif()
|
||||
|
||||
if (DEFINED ARTIFACT_DIR)
|
||||
if (NOT DEFINED PKG_ARGS_TARGET OR NOT TARGET "${PKG_ARGS_TARGET}")
|
||||
include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake)
|
||||
|
||||
# Overrides find package
|
||||
CPMAddPackage(
|
||||
NAME ${ARTIFACT_PACKAGE}
|
||||
SOURCE_DIR ${ARTIFACT_DIR}
|
||||
)
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_NAMES ${ARTIFACT_NAME})
|
||||
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_URLS "https://github.com/${ARTIFACT_REPO}") # TODO(crueter) other hosts?
|
||||
set_property(GLOBAL APPEND PROPERTY CPM_PACKAGE_SHAS ${ARTIFACT_VERSION})
|
||||
|
||||
set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
else()
|
||||
find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED)
|
||||
endif()
|
||||
|
@@ -29,6 +29,7 @@ function(download_bundled_external remote_path lib_name cpm_key prefix_var versi
|
||||
set(package_url "${package_base_url}${package_repo}")
|
||||
set(full_url ${package_url}${remote_path}${lib_name}${package_extension})
|
||||
|
||||
# TODO(crueter): DELETE THIS ENTIRELY, GLORY BE TO THE CI!
|
||||
AddPackage(
|
||||
NAME ${cpm_key}
|
||||
VERSION ${version}
|
||||
|
19
CMakeModules/FindSPIRV-Tools.cmake
Normal file
19
CMakeModules/FindSPIRV-Tools.cmake
Normal file
@@ -0,0 +1,19 @@
|
||||
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(SPIRV-Tools QUIET IMPORTED_TARGET SPIRV-Tools)
|
||||
find_package_handle_standard_args(SPIRV-Tools
|
||||
REQUIRED_VARS SPIRV-Tools_LINK_LIBRARIES
|
||||
VERSION_VAR SPIRV-Tools_VERSION
|
||||
)
|
||||
|
||||
if (SPIRV-Tools_FOUND AND NOT TARGET SPIRV-Tools::SPIRV-Tools)
|
||||
if (TARGET SPIRV-Tools)
|
||||
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools)
|
||||
else()
|
||||
add_library(SPIRV-Tools::SPIRV-Tools ALIAS PkgConfig::SPIRV-Tools)
|
||||
endif()
|
||||
endif()
|
@@ -3,17 +3,12 @@
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(zstd QUIET CONFIG)
|
||||
if (zstd_CONSIDERED_CONFIGS)
|
||||
find_package_handle_standard_args(zstd CONFIG_MODE)
|
||||
else()
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(ZSTD QUIET IMPORTED_TARGET libzstd)
|
||||
find_package_handle_standard_args(zstd
|
||||
REQUIRED_VARS ZSTD_LINK_LIBRARIES
|
||||
VERSION_VAR ZSTD_VERSION
|
||||
)
|
||||
endif()
|
||||
|
||||
if (zstd_FOUND AND NOT TARGET zstd::zstd)
|
||||
if (TARGET zstd::libzstd_shared)
|
||||
|
147
cpmfile.json
Normal file
147
cpmfile.json
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"openssl": {
|
||||
"ci": true,
|
||||
"package": "OpenSSL",
|
||||
"name": "openssl",
|
||||
"repo": "crueter-ci/OpenSSL",
|
||||
"version": "3.5.2",
|
||||
"min_version": "1.1.1"
|
||||
},
|
||||
"boost": {
|
||||
"package": "Boost",
|
||||
"repo": "boostorg/boost",
|
||||
"tag": "boost-1.88.0",
|
||||
"artifact": "boost-1.88.0-cmake.7z",
|
||||
"hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01",
|
||||
"git_version": "1.88.0",
|
||||
"version": "1.57"
|
||||
},
|
||||
"fmt": {
|
||||
"repo": "fmtlib/fmt",
|
||||
"sha": "40626af88b",
|
||||
"hash": "d59f06c24339f223de4ec2afeba1c67b5835a0f350a1ffa86242a72fc3e616a6b8b21798355428d4200c75287308b66634619ffa0b52ba5bd74cc01772ea1a8a",
|
||||
"version": "8",
|
||||
"options": [
|
||||
"FMT_INSTALL OFF"
|
||||
]
|
||||
},
|
||||
"lz4": {
|
||||
"name": "lz4",
|
||||
"repo": "lz4/lz4",
|
||||
"sha": "ebb370ca83",
|
||||
"hash": "43600e87b35256005c0f2498fa56a77de6783937ba4cfce38c099f27c03188d097863e8a50c5779ca0a7c63c29c4f7ed0ae526ec798c1fd2e3736861b62e0a37",
|
||||
"source_subdir": "build/cmake"
|
||||
},
|
||||
"nlohmann": {
|
||||
"package": "nlohmann_json",
|
||||
"repo": "nlohmann/json",
|
||||
"sha": "55f93686c0",
|
||||
"hash": "b739749b066800e21154506ea150d2c5cbce8a45344177f46f884547a1399d26753166fd0df8135269ce28cf223552b1b65cd625b88c844d54753f2434900486",
|
||||
"version": "3.8"
|
||||
},
|
||||
"zlib": {
|
||||
"package": "ZLIB",
|
||||
"repo": "madler/zlib",
|
||||
"sha": "51b7f2abda",
|
||||
"hash": "16eaf1f3752489d12fd9ce30f7b5f7cbd5cb8ff53d617005a9847ae72d937f65e01e68be747f62d7ac19fd0c9aeba9956e60f16d6b465c5fdc2f3d08b4db2e6c",
|
||||
"version": "1.2",
|
||||
"options": [
|
||||
"ZLIB_BUILD_SHARED OFF",
|
||||
"ZLIB_INSTALL OFF"
|
||||
]
|
||||
},
|
||||
"zstd": {
|
||||
"repo": "facebook/zstd",
|
||||
"sha": "f8745da6ff",
|
||||
"hash": "3037007f990040fe32573b46f9bef8762fd5dbeeb07ffffcbfeba51ec98167edae39bb9c87f9299efcd61c4e467c5e84f7c19f0df7799bc1fc04864a278792ee",
|
||||
"version": "1.5",
|
||||
"source_subdir": "build/cmake",
|
||||
"find_args": "MODULE",
|
||||
"options": [
|
||||
"ZSTD_BUILD_SHARED OFF"
|
||||
]
|
||||
},
|
||||
"catch2": {
|
||||
"package": "Catch2",
|
||||
"repo": "catchorg/Catch2",
|
||||
"sha": "644821ce28",
|
||||
"hash": "f8795f98acf2c02c0db8e734cc866d5caebab4b4a306e93598b97cb3c0c728dafe8283dce27ffe8d42460e5ae7302f3f32e7e274a7f991b73511ac88eef21b1f",
|
||||
"version": "3.0.1"
|
||||
},
|
||||
"enet": {
|
||||
"repo": "lsalzman/enet",
|
||||
"sha": "2662c0de09",
|
||||
"hash": "3de1beb4fa3d6b1e03eda8dd1e7580694f854af3ed3975dcdabfdcdf76b97f322b9734d35ea7f185855bb490d957842b938b26da4dd2dfded509390f8d2794dd",
|
||||
"version": "1.3",
|
||||
"find_args": "MODULE"
|
||||
},
|
||||
"opus": {
|
||||
"package": "Opus",
|
||||
"repo": "xiph/opus",
|
||||
"sha": "5ded705cf4",
|
||||
"hash": "0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203",
|
||||
"version": "1.3",
|
||||
"find_args": "MODULE",
|
||||
"options": [
|
||||
"OPUS_BUILD_TESTING OFF",
|
||||
"OPUS_BUILD_PROGRAMS OFF",
|
||||
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF",
|
||||
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
|
||||
]
|
||||
},
|
||||
"cubeb": {
|
||||
"repo": "mozilla/cubeb",
|
||||
"sha": "fa02160712",
|
||||
"hash": "82d808356752e4064de48c8fecbe7856715ade1e76b53937116bf07129fc1cc5b3de5e4b408de3cd000187ba8dc32ca4109661cb7e0355a52e54bd81b9be1c61",
|
||||
"find_args": "CONFIG",
|
||||
"options": [
|
||||
"USE_SANITIZERS OFF",
|
||||
"BUILD_TESTS OFF",
|
||||
"BUILD_TOOLS OFF",
|
||||
"BUNDLE_SPEEX ON"
|
||||
]
|
||||
},
|
||||
"boost_headers": {
|
||||
"repo": "boostorg/headers",
|
||||
"sha": "0456900fad",
|
||||
"hash": "50cd75dcdfc5f082225cdace058f47b4fb114a47585f7aee1d22236a910a80b667186254c214fa2fcebac67ae6d37ba4b6e695e1faea8affd6fd42a03cf996e3",
|
||||
"bundled": true
|
||||
},
|
||||
"discord-rpc": {
|
||||
"repo": "eden-emulator/discord-rpc",
|
||||
"sha": "1cf7772bb6",
|
||||
"hash": "e9b35e6f2c075823257bcd59f06fe7bb2ccce1976f44818d2e28810435ef79c712a3c4f20f40da41f691342a4058cf86b078eb7f9d9e4dae83c0547c21ec4f97"
|
||||
},
|
||||
"simpleini": {
|
||||
"package": "SimpleIni",
|
||||
"repo": "brofield/simpleini",
|
||||
"sha": "09c21bda1d",
|
||||
"hash": "99779ca9b6e040d36558cadf484f9ffdab5b47bcc8fc72e4d33639d1d60c0ceb4410d335ba445d72a4324e455167fd6769d99b459943aa135bec085dff2d4b7c",
|
||||
"find_args": "MODULE"
|
||||
},
|
||||
"sdl2_generic": {
|
||||
"package": "SDL2",
|
||||
"repo": "libsdl-org/SDL",
|
||||
"sha": "54772f345a",
|
||||
"hash": "2a68a0e01c390043aa9d9df63d8a20a52076c88bb460ac4e0f33194ca7d9bc8fadbbcc04e7506872ac4b6354a73fbc267c036f82200da59465789b87c7d9e3a4",
|
||||
"key": "generic",
|
||||
"bundled": true
|
||||
},
|
||||
"sdl2_steamdeck": {
|
||||
"package": "SDL2",
|
||||
"repo": "libsdl-org/SDL",
|
||||
"sha": "cc016b0046",
|
||||
"hash": "34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b",
|
||||
"key": "steamdeck",
|
||||
"bundled": true
|
||||
},
|
||||
"sdl2": {
|
||||
"ci": true,
|
||||
"package": "SDL2",
|
||||
"name": "SDL2",
|
||||
"repo": "crueter-ci/SDL2",
|
||||
"version": "2.32.8",
|
||||
"min_version": "2.26.4",
|
||||
"cmake_filename": "sdl2"
|
||||
}
|
||||
}
|
@@ -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;
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
54
dist/qt_themes/default/style.qss
vendored
54
dist/qt_themes/default/style.qss
vendored
@@ -95,6 +95,60 @@ QPushButton#button_reset_defaults {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
/* QGroupBox --------------------------------------------------------------
|
||||
|
||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
|
||||
|
||||
--------------------------------------------------------------------------- */
|
||||
QGroupBox {
|
||||
border: 1px solid #32414B;
|
||||
border-radius: 4px;
|
||||
margin-top: 20px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top left;
|
||||
padding-left: 3px;
|
||||
padding-right: 5px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
QGroupBox::indicator {
|
||||
margin-left: 2px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
QGroupBox::indicator:unchecked {
|
||||
border: none;
|
||||
image: url(":/qss_icons/rc/checkbox_unchecked.png");
|
||||
}
|
||||
|
||||
QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed {
|
||||
border: none;
|
||||
image: url(":/qss_icons/rc/checkbox_unchecked_focus.png");
|
||||
}
|
||||
|
||||
QGroupBox::indicator:unchecked:disabled {
|
||||
image: url(":/qss_icons/rc/checkbox_unchecked_disabled.png");
|
||||
}
|
||||
|
||||
QGroupBox::indicator:checked {
|
||||
border: none;
|
||||
image: url(":/qss_icons/rc/checkbox_checked.png");
|
||||
}
|
||||
|
||||
QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed {
|
||||
border: none;
|
||||
image: url(":/qss_icons/rc/checkbox_checked_focus.png");
|
||||
}
|
||||
|
||||
QGroupBox::indicator:checked:disabled {
|
||||
image: url(":/qss_icons/rc/checkbox_checked_disabled.png");
|
||||
}
|
||||
|
||||
QWidget#bottomPerGameInput,
|
||||
QWidget#topControllerApplet,
|
||||
QWidget#bottomControllerApplet,
|
||||
|
26
dist/qt_themes/default_dark/style.qss
vendored
26
dist/qt_themes/default_dark/style.qss
vendored
@@ -697,3 +697,29 @@ QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
|
||||
QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
|
||||
image: url(:/overlay/osk_button_Y_disabled.png);
|
||||
}
|
||||
|
||||
/* QGroupBox --------------------------------------------------------------
|
||||
|
||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
|
||||
|
||||
--------------------------------------------------------------------------- */
|
||||
QGroupBox {
|
||||
border: 1px solid #32414B;
|
||||
border-radius: 4px;
|
||||
margin-top: 22px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top left;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
QGroupBox::indicator {
|
||||
margin-left: 2px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
2
dist/qt_themes/qdarkstyle/style.qss
vendored
2
dist/qt_themes/qdarkstyle/style.qss
vendored
@@ -307,7 +307,7 @@ QAbstractItemView QLineEdit {
|
||||
QGroupBox {
|
||||
border: 1px solid #54575B;
|
||||
border-radius: 2px;
|
||||
margin-top: 12px;
|
||||
margin-top: 20px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
|
@@ -235,10 +235,9 @@ https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox
|
||||
|
||||
--------------------------------------------------------------------------- */
|
||||
QGroupBox {
|
||||
font-weight: bold;
|
||||
border: 1px solid #32414B;
|
||||
border-radius: 4px;
|
||||
margin-top: 12px;
|
||||
margin-top: 20px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
|
252
docs/CPM.md
Normal file
252
docs/CPM.md
Normal file
@@ -0,0 +1,252 @@
|
||||
# CPM
|
||||
|
||||
CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden.
|
||||
|
||||
Global Options:
|
||||
|
||||
- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing
|
||||
* If this is `OFF`, required system dependencies will be searched via `find_package`, although certain externals use CPM regardless.
|
||||
- `CPMUTIL_FORCE_SYSTEM` (default `OFF`): Require all CPM dependencies to use system packages. NOT RECOMMENDED!
|
||||
* Many packages, e.g. mcl, sirit, xbyak, discord-rpc, are not generally available as a system package.
|
||||
* You may optionally override these (see CPMUtil section)
|
||||
- `CPMUTIL_FORCE_BUNDLED` (default `ON` on MSVC and Android, `OFF` elsewhere): Require all CPM dependencies to use bundled packages.
|
||||
|
||||
## CPMUtil
|
||||
|
||||
CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful utility functions to make dependency management a piece of cake.
|
||||
|
||||
### AddPackage
|
||||
|
||||
`AddPackage` is the core of the CPMUtil wrapper, and is generally the lowest level you will need to go when dealing with dependencies.
|
||||
|
||||
**Identification/Fetching**
|
||||
|
||||
- `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
|
||||
- `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
|
||||
- `TAG`: The tag to fetch, if applicable.
|
||||
- `ARTIFACT`: The name of the artifact, if applicable.
|
||||
- `SHA`: Commit sha to fetch, if applicable.
|
||||
- `BRANCH`: Branch to fetch, if applicable.
|
||||
|
||||
The following configurations are supported, in descending order of precedence:
|
||||
|
||||
- `URL`: Bare URL download, useful for custom artifacts
|
||||
* If this is set, `GIT_URL` or `REPO` should be set to allow the dependency viewer to link to the project's Git repository.
|
||||
* If this is NOT set, `REPO` must be defined.
|
||||
- `REPO + TAG + ARTIFACT`: GitHub release artifact
|
||||
* The final download URL will be `https://github.com/${REPO}/releases/download/${TAG}/${ARTIFACT}`
|
||||
* Useful for prebuilt libraries and prefetched archives
|
||||
- `REPO + TAG`: GitHub tag archive
|
||||
* The final download URL will be `https://github.com/${REPO}/archive/refs/tags/${TAG}.tar.gz`
|
||||
* Useful for pinning to a specific tag, better for build identification
|
||||
- `REPO + SHA`: GitHub commit archive
|
||||
* The final download URL will be `https://github.com/${REPO}/archive/${SHA}.zip`
|
||||
* Useful for pinning to a specific commit
|
||||
- `REPO + BRANCH`: GitHub branch archive
|
||||
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/${BRANCH}.zip`
|
||||
* Generally not recommended unless the branch is frozen
|
||||
- `REPO`: GitHub master archive
|
||||
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/master.zip`
|
||||
* Generally not recommended unless the project is dead
|
||||
|
||||
**Hashing**
|
||||
|
||||
Hashing is used for verifying downloads. It's highly recommended to use these.
|
||||
|
||||
- `HASH_ALGO` (default `SHA512`): Hash algorithm to use
|
||||
|
||||
Hashing strategies, descending order of precedence:
|
||||
|
||||
- `HASH`: Bare hash verification, useful for static downloads e.g. commit archives
|
||||
- `HASH_SUFFIX`: Download the hash as `${DOWNLOAD_URL}.${HASH_SUFFIX}`
|
||||
* The downloaded hash *must* match the hash algorithm and contain nothing but the hash; no filenames or extra content.
|
||||
- `HASH_URL`: Download the hash from a separate URL
|
||||
|
||||
**Additional Options**
|
||||
|
||||
- `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
|
||||
- Tag
|
||||
- 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
|
||||
- `SOURCE_SUBDIR`: Subdirectory of the project containing a CMakeLists.txt file
|
||||
- `FIND_PACKAGE_ARGUMENTS`: Arguments to pass to the `find_package` call
|
||||
- `BUNDLED_PACKAGE`: Set to `ON` to force the usage of a bundled package
|
||||
- `OPTIONS`: Options to pass to the configuration of the package
|
||||
- `PATCHES`: Patches to apply to the package, stored in `.patch/${packagename_lower}/0001-patch-name.patch` and so on
|
||||
- Other arguments can be passed to CPM as well
|
||||
|
||||
**Extra Variables**
|
||||
|
||||
For each added package, users may additionally force usage of the system/bundled package.
|
||||
|
||||
- `${package}_FORCE_SYSTEM`: Require the package to be installed on the system
|
||||
- `${package}_FORCE_BUNDLED`: Force the package to be fetched and use the bundled version
|
||||
|
||||
**Bundled/System Switching**
|
||||
|
||||
Descending order of precedence:
|
||||
- If `${package}_FORCE_SYSTEM` is true, requires the package to be on the system
|
||||
- If `${package}_FORCE_BUNDLED` is true, forcefully uses the bundled package
|
||||
- If `CPMUTIL_FORCE_SYSTEM` is true, requires the package to be on the system
|
||||
- If `CPMUTIL_FORCE_BUNDLED` is true, forcefully uses the bundled package
|
||||
- If the `BUNDLED_PACKAGE` argument is true, forcefully uses the bundled package
|
||||
- Otherwise, CPM will search for the package first, and if not found, will use the bundled package
|
||||
|
||||
**Identification**
|
||||
|
||||
All dependencies must be identifiable in some way for usage in the dependency viewer. Lists are provided in descending order of precedence.
|
||||
|
||||
URLs:
|
||||
|
||||
- `GIT_URL`
|
||||
- `REPO` as a GitHub repository
|
||||
- `URL`
|
||||
|
||||
Versions (bundled):
|
||||
|
||||
- `SHA`
|
||||
- `GIT_VERSION`
|
||||
- `VERSION`
|
||||
- `TAG`
|
||||
- "unknown"
|
||||
|
||||
If the package is a system package, AddPackage will attempt to determine the package version and append ` (system)` to the identifier. Otherwise, it will be marked as `unknown (system)`
|
||||
|
||||
### AddCIPackage
|
||||
|
||||
Adds a package that follows crueter's CI repository spec.
|
||||
|
||||
- `VERSION` (required): The version to get (the tag will be `v${VERSION}`)
|
||||
- `NAME` (required): Name used within the artifacts
|
||||
- `REPO` (required): CI repository, e.g. `crueter-ci/OpenSSL`
|
||||
- `PACKAGE` (required): `find_package` package name
|
||||
- `EXTENSION`: Artifact extension (default `tar.zst`)
|
||||
- `MIN_VERSION`: Minimum version for `find_package`. Only used if platform does not support this package as a bundled artifact
|
||||
- `DISABLED_PLATFORMS`: List of platforms that lack artifacts for this package. One of:
|
||||
* `windows-amd64`
|
||||
* `windows-arm64`
|
||||
* `android`
|
||||
* `solaris`
|
||||
* `freebsd`
|
||||
* `linux`
|
||||
* `linux-aarch64`
|
||||
- `CMAKE_FILENAME`: Custom CMake filename, relative to the package root (default `${PACKAGE_ROOT}/${NAME}.cmake`)
|
||||
|
||||
### AddJsonPackage
|
||||
|
||||
This is the recommended method of usage for CPMUtil. In each directory that utilizes `CPMUtil`, there must be a `cpmfile.json` that defines dependencies in a similar manner to the individual calls.
|
||||
|
||||
The cpmfile is an object of objects, with each sub-object being named according to the package's identifier, e.g. `openssl`, which can then be fetched with `AddJsonPackage(<identifier>)`. Options are designed to map closely to the argument names, and are always strings unless otherwise specified.
|
||||
|
||||
- `package` -> `NAME` (`PACKAGE` for CI), defaults to the object key
|
||||
- `repo` -> `REPO`
|
||||
- `version` -> `VERSION`
|
||||
- `ci` (bool)
|
||||
|
||||
If `ci` is `false`:
|
||||
|
||||
- `hash` -> `HASH`
|
||||
- `sha` -> `SHA`
|
||||
- `tag` -> `TAG`
|
||||
- `artifact` -> `ARTIFACT`
|
||||
- `git_version` -> `GIT_VERSION`
|
||||
- `source_subdir` -> `SOURCE_SUBDIR`
|
||||
- `bundled` -> `BUNDLED_PACKAGE`
|
||||
- `find_args` -> `FIND_PACKAGE_ARGUMENTS`
|
||||
- `patches` -> `PATCHES` (array)
|
||||
- `options` -> `OPTIONS` (array)
|
||||
|
||||
Other arguments aren't currently supported. If you wish to add them, see the `AddJsonPackage` function in `CMakeModules/CPMUtil.cmake`.
|
||||
|
||||
If `ci` is `true`:
|
||||
|
||||
- `name` -> `NAME`, defaults to the object key
|
||||
- `extension` -> `EXTENSION`, defaults to `tar.zst`
|
||||
- `min_version` -> `MIN_VERSION`
|
||||
- `cmake_filename` -> `CMAKE_FILENAME`
|
||||
- `extension` -> `EXTENSION`
|
||||
|
||||
### Examples
|
||||
|
||||
In order: OpenSSL CI, Boost (tag + artifact), discord-rpc (sha + options + patches), Opus (options + find_args)
|
||||
|
||||
```json
|
||||
{
|
||||
"openssl": {
|
||||
"ci": true,
|
||||
"package": "OpenSSL",
|
||||
"name": "openssl",
|
||||
"repo": "crueter-ci/OpenSSL",
|
||||
"version": "3.5.2",
|
||||
"min_version": "1.1.1"
|
||||
},
|
||||
"boost": {
|
||||
"package": "Boost",
|
||||
"repo": "boostorg/boost",
|
||||
"tag": "boost-1.88.0",
|
||||
"artifact": "boost-1.88.0-cmake.7z",
|
||||
"hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01",
|
||||
"git_version": "1.88.0",
|
||||
"version": "1.57"
|
||||
},
|
||||
"opus": {
|
||||
"package": "Opus",
|
||||
"repo": "xiph/opus",
|
||||
"sha": "5ded705cf4",
|
||||
"hash": "0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203",
|
||||
"version": "1.3",
|
||||
"find_args": "MODULE",
|
||||
"options": [
|
||||
"OPUS_BUILD_TESTING OFF",
|
||||
"OPUS_BUILD_PROGRAMS OFF",
|
||||
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF",
|
||||
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
|
||||
]
|
||||
},
|
||||
"discord-rpc": {
|
||||
"repo": "discord/discord-rpc",
|
||||
"sha": "963aa9f3e5",
|
||||
"hash": "386e1344e9a666d730f2d335ee3aef1fd05b1039febefd51aa751b705009cc764411397f3ca08dffd46205c72f75b235c870c737b2091a4ed0c3b061f5919bde",
|
||||
"options": [
|
||||
"BUILD_EXAMPLES OFF"
|
||||
],
|
||||
"patches": [
|
||||
"0001-cmake-version.patch",
|
||||
"0002-no-clang-format.patch",
|
||||
"0003-fix-cpp17.patch"
|
||||
]
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Inclusion
|
||||
|
||||
To include CPMUtil:
|
||||
|
||||
```cmake
|
||||
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
|
||||
include(CPMUtil)
|
||||
```
|
||||
|
||||
You may omit the first line if you are not utilizing cpmfile.
|
||||
|
||||
## Prefetching
|
||||
|
||||
- To prefetch a CPM dependency (requires cpmfile):
|
||||
* `tools/cpm-fetch.sh <packages>`
|
||||
- To prefetch all CPM dependencies:
|
||||
* `tools/cpm-fetch-all.sh`
|
||||
|
||||
Currently, `cpm-fetch.sh` defines the following directories for cpmfiles:
|
||||
|
||||
`externals src/yuzu/externals externals/ffmpeg src/dynarmic/externals externals/nx_tzdb`
|
||||
|
||||
Whenever you add a new cpmfile, update the script accordingly
|
2
docs/build/Linux.md
vendored
2
docs/build/Linux.md
vendored
@@ -37,7 +37,7 @@ Dependencies are listed here as commands that can be copied/pasted. Of course, t
|
||||
- GCC 11 or later is required.
|
||||
|
||||
- Ubuntu / Linux Mint / Debian:
|
||||
- `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev`
|
||||
- `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev`
|
||||
- Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required.
|
||||
- Users need to manually specify building with QT Web Engine enabled. This is done using the parameter `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake.
|
||||
- Users need to manually disable building SDL2 from externals if they intend to use the version provided by their system by adding the parameters `-DYUZU_USE_EXTERNAL_SDL2=OFF`
|
||||
|
154
externals/CMakeLists.txt
vendored
154
externals/CMakeLists.txt
vendored
@@ -7,7 +7,8 @@
|
||||
# TODO(crueter): A lot of this should be moved to the root.
|
||||
# otherwise we have to do weird shenanigans with library linking and stuff
|
||||
|
||||
# cpm
|
||||
# Explicitly include CPMUtil here since we have a separate cpmfile for externals
|
||||
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
|
||||
include(CPMUtil)
|
||||
|
||||
# Explicitly declare this option here to propagate to the oaknut CPM call
|
||||
@@ -33,32 +34,15 @@ endif()
|
||||
# Xbyak (also used by Dynarmic, so needs to be added first)
|
||||
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
|
||||
if (PLATFORM_SUN)
|
||||
# Fix regset.h collisions
|
||||
set(XBYAK_HASH 51f507b0b3)
|
||||
set(XBYAK_SHA512SUM 4a29a3c2f97f7d5adf667a21a008be03c951fb6696b0d7ba27e7e4afa037bc76eb5e059bb84860e01baf741d4d3ac851b840cd54c99d038812fbe0f1fa6d38a4)
|
||||
AddJsonPackage(xbyak_sun)
|
||||
else()
|
||||
set(XBYAK_HASH 4e44f4614d)
|
||||
set(XBYAK_SHA512SUM 5824e92159e07fa36a774aedd3b3ef3541d0241371d522cffa4ab3e1f215fa5097b1b77865b47b2481376c704fa079875557ea463ca63d0a7fd6a8a20a589e70)
|
||||
AddJsonPackage(xbyak)
|
||||
endif()
|
||||
|
||||
AddPackage(
|
||||
NAME xbyak
|
||||
REPO "Lizzie841/xbyak"
|
||||
SHA ${XBYAK_HASH}
|
||||
HASH ${XBYAK_SHA512SUM}
|
||||
BUNDLED_PACKAGE ON
|
||||
)
|
||||
endif()
|
||||
|
||||
# Oaknut (also used by Dynarmic, so needs to be added first)
|
||||
if (ARCHITECTURE_arm64 OR DYNARMIC_TESTS)
|
||||
AddPackage(
|
||||
NAME oaknut
|
||||
VERSION 2.0.1
|
||||
REPO "merryhime/oaknut"
|
||||
SHA 94c726ce03
|
||||
HASH d8d082242fa1881abce3c82f8dafa002c4e561e66a69e7fc038af67faa5eff2630f082d3d19579c88c4c9f9488e54552accc8cb90e7ce743efe043b6230c08ac
|
||||
)
|
||||
AddJsonPackage(oaknut)
|
||||
endif()
|
||||
|
||||
# getopt
|
||||
@@ -70,14 +54,7 @@ endif()
|
||||
add_subdirectory(glad)
|
||||
|
||||
# mbedtls
|
||||
AddPackage(
|
||||
NAME mbedtls
|
||||
REPO "Mbed-TLS/mbedtls"
|
||||
SHA "8c88150ca1"
|
||||
HASH 769ad1e94c570671071e1f2a5c0f1027e0bf6bcdd1a80ea8ac970f2c86bc45ce4e31aa88d6d8110fc1bed1de81c48bc624df1b38a26f8b340a44e109d784a966
|
||||
PATCHES
|
||||
${CMAKE_SOURCE_DIR}/.patch/mbedtls/0001-cmake-version.patch
|
||||
)
|
||||
AddJsonPackage(mbedtls)
|
||||
|
||||
if (mbedtls_ADDED)
|
||||
target_include_directories(mbedtls PUBLIC ${mbedtls_SOURCE_DIR}/include)
|
||||
@@ -97,23 +74,11 @@ endif()
|
||||
# Sirit
|
||||
# TODO(crueter): spirv-tools doesn't work w/ system
|
||||
set(SPIRV_WERROR OFF)
|
||||
AddPackage(
|
||||
NAME SPIRV-Headers
|
||||
REPO "KhronosGroup/SPIRV-Headers"
|
||||
SHA 4e209d3d7e
|
||||
HASH f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4
|
||||
)
|
||||
AddJsonPackage(spirv-headers)
|
||||
|
||||
AddPackage(
|
||||
NAME sirit
|
||||
REPO "eden-emulator/sirit"
|
||||
SHA db1f1e8ab5
|
||||
HASH 73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05
|
||||
OPTIONS
|
||||
"SIRIT_USE_SYSTEM_SPIRV_HEADERS ON"
|
||||
)
|
||||
AddJsonPackage(sirit)
|
||||
|
||||
if(MSVC AND USE_CCACHE AND TARGET sirit)
|
||||
if(MSVC AND USE_CCACHE AND sirit_ADDED)
|
||||
get_target_property(_opts sirit COMPILE_OPTIONS)
|
||||
list(FILTER _opts EXCLUDE REGEX "/Zi")
|
||||
list(APPEND _opts "/Z7")
|
||||
@@ -122,45 +87,16 @@ endif()
|
||||
|
||||
# httplib
|
||||
if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER)
|
||||
AddPackage(
|
||||
NAME httplib
|
||||
REPO "yhirose/cpp-httplib"
|
||||
SHA a609330e4c
|
||||
HASH dd3fd0572f8367d8549e1319fd98368b3e75801a293b0c3ac9b4adb806473a4506a484b3d389dc5bee5acc460cb90af7a20e5df705a1696b56496b30b9ce7ed2
|
||||
OPTIONS
|
||||
"HTTPLIB_REQUIRE_OPENSSL ${ENABLE_OPENSSL}"
|
||||
)
|
||||
AddJsonPackage(httplib)
|
||||
endif()
|
||||
|
||||
# cpp-jwt
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
AddPackage(
|
||||
NAME cpp-jwt
|
||||
VERSION 1.4
|
||||
REPO "arun11299/cpp-jwt"
|
||||
SHA a54fa08a3b
|
||||
HASH a90f7e594ada0c7e49d5ff9211c71097534e7742a8e44bf0851b0362642a7271d53f5d83d04eeaae2bad17ef3f35e09e6818434d8eaefa038f3d1f7359d0969a
|
||||
FIND_PACKAGE_ARGUMENTS "CONFIG"
|
||||
OPTIONS
|
||||
"CPP_JWT_BUILD_EXAMPLES OFF"
|
||||
"CPP_JWT_BUILD_TESTS OFF"
|
||||
"CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF"
|
||||
PATCHES
|
||||
${CMAKE_SOURCE_DIR}/.patch/cpp-jwt/0001-no-install.patch
|
||||
${CMAKE_SOURCE_DIR}/.patch/cpp-jwt/0002-missing-decl.patch
|
||||
)
|
||||
AddJsonPackage(cpp-jwt)
|
||||
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)
|
||||
@@ -175,47 +111,37 @@ endif()
|
||||
|
||||
# TODO(crueter): Vk1.4 impl
|
||||
|
||||
AddPackage(
|
||||
NAME VulkanHeaders
|
||||
VERSION 1.3.274
|
||||
REPO "KhronosGroup/Vulkan-Headers"
|
||||
SHA 89268a6d17
|
||||
HASH 3ab349f74298ba72cafb8561015690c0674d428a09fb91ccd3cd3daca83650d190d46d33fd97b0a8fd4223fe6df2bcabae89136fbbf7c0bfeb8776f9448304c8
|
||||
AddJsonPackage(
|
||||
NAME vulkan-headers
|
||||
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_HEADERS}
|
||||
)
|
||||
|
||||
# Vulkan-Utility-Libraries
|
||||
AddPackage(
|
||||
NAME VulkanUtilityLibraries
|
||||
REPO "KhronosGroup/Vulkan-Utility-Libraries"
|
||||
SHA df2e358152
|
||||
HASH 3e468c3d9ff93f6d418d71e5527abe0a12c8c7ab5b0b52278bbbee4d02bb87e99073906729b727e0147242b7e3fd5dedf68b803f1878cb4c0e4f730bc2238d79
|
||||
AddJsonPackage(
|
||||
NAME vulkan-utility-libraries
|
||||
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES}
|
||||
)
|
||||
|
||||
# SPIRV-Tools
|
||||
if (YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS)
|
||||
AddPackage(
|
||||
NAME SPIRV-Tools
|
||||
REPO "KhronosGroup/SPIRV-Tools"
|
||||
SHA 40eb301f32
|
||||
HASH 58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa
|
||||
OPTIONS
|
||||
"SPIRV_SKIP_EXECUTABLES ON"
|
||||
# SPIRV Tools
|
||||
AddJsonPackage(
|
||||
NAME spirv-tools
|
||||
BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS}
|
||||
)
|
||||
|
||||
if (SPIRV-Tools_ADDED)
|
||||
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
|
||||
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
|
||||
endif()
|
||||
|
||||
# TZDB (Time Zone Database)
|
||||
add_subdirectory(nx_tzdb)
|
||||
|
||||
# VMA
|
||||
AddPackage(
|
||||
NAME VulkanMemoryAllocator
|
||||
REPO "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator"
|
||||
SHA 1076b348ab
|
||||
HASH a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772
|
||||
FIND_PACKAGE_ARGUMENTS "CONFIG"
|
||||
)
|
||||
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)
|
||||
@@ -245,17 +171,8 @@ if (NOT TARGET RenderDoc::API)
|
||||
add_library(RenderDoc::API ALIAS renderdoc)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
if (ARCHITECTURE_arm64)
|
||||
AddPackage(
|
||||
NAME libadrenotools
|
||||
REPO "bylaws/libadrenotools"
|
||||
SHA 8fae8ce254
|
||||
HASH c74fa855f0edebbf25c9bce40b00966daa2447bfc5e15f0cf1a95f86cbf70fc6b02590707edbde16328a0a2a4fb9a1fc419d2dfc22a4a4150971be91892d4edb
|
||||
PATCHES
|
||||
${CMAKE_SOURCE_DIR}/.patch/libadrenotools/0001-linkerns-cpm.patch
|
||||
)
|
||||
endif()
|
||||
if (ANDROID AND ARCHITECTURE_arm64)
|
||||
AddJsonPackage(libadrenotools)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE AND NOT TARGET gamemode::headers)
|
||||
@@ -278,6 +195,7 @@ if (YUZU_CRASH_DUMPS AND NOT TARGET libbreakpad_client)
|
||||
_CRT_NONSTDC_NO_DEPRECATE
|
||||
)
|
||||
|
||||
# TODO
|
||||
AddPackage(
|
||||
NAME breakpad
|
||||
URL "google/breakpad"
|
||||
@@ -378,13 +296,7 @@ endif()
|
||||
|
||||
# oboe
|
||||
if (ANDROID)
|
||||
AddPackage(
|
||||
NAME oboe
|
||||
REPO "google/oboe"
|
||||
SHA 2bc873e53c
|
||||
HASH 02329058a7f9cf7d5039afaae5ab170d9f42f60f4c01e21eaf4f46073886922b057a9ae30eeac040b3ac182f51b9c1bfe9fe1050a2c9f6ce567a1a9a0ec2c768
|
||||
BUNDLED_PACKAGE ON
|
||||
)
|
||||
AddJsonPackage(oboe)
|
||||
|
||||
add_library(oboe::oboe ALIAS oboe)
|
||||
endif()
|
||||
|
122
externals/cpmfile.json
vendored
Normal file
122
externals/cpmfile.json
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"mbedtls": {
|
||||
"repo": "Mbed-TLS/mbedtls",
|
||||
"sha": "8c88150ca1",
|
||||
"hash": "769ad1e94c570671071e1f2a5c0f1027e0bf6bcdd1a80ea8ac970f2c86bc45ce4e31aa88d6d8110fc1bed1de81c48bc624df1b38a26f8b340a44e109d784a966",
|
||||
"patches": [
|
||||
"0001-cmake-version.patch"
|
||||
]
|
||||
},
|
||||
"spirv-headers": {
|
||||
"package": "SPIRV-Headers",
|
||||
"repo": "KhronosGroup/SPIRV-Headers",
|
||||
"sha": "4e209d3d7e",
|
||||
"hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4"
|
||||
},
|
||||
"sirit": {
|
||||
"repo": "eden-emulator/sirit",
|
||||
"sha": "db1f1e8ab5",
|
||||
"hash": "73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05",
|
||||
"options": [
|
||||
"SIRIT_USE_SYSTEM_SPIRV_HEADERS ON"
|
||||
]
|
||||
},
|
||||
"httplib": {
|
||||
"repo": "yhirose/cpp-httplib",
|
||||
"sha": "a609330e4c",
|
||||
"hash": "dd3fd0572f8367d8549e1319fd98368b3e75801a293b0c3ac9b4adb806473a4506a484b3d389dc5bee5acc460cb90af7a20e5df705a1696b56496b30b9ce7ed2"
|
||||
},
|
||||
"cpp-jwt": {
|
||||
"version": "1.4",
|
||||
"repo": "arun11299/cpp-jwt",
|
||||
"sha": "a54fa08a3b",
|
||||
"hash": "a90f7e594ada0c7e49d5ff9211c71097534e7742a8e44bf0851b0362642a7271d53f5d83d04eeaae2bad17ef3f35e09e6818434d8eaefa038f3d1f7359d0969a",
|
||||
"find_args": "CONFIG",
|
||||
"options": [
|
||||
"CPP_JWT_BUILD_EXAMPLES OFF",
|
||||
"CPP_JWT_BUILD_TESTS OFF",
|
||||
"CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF"
|
||||
],
|
||||
"patches": [
|
||||
"0001-no-install.patch",
|
||||
"0002-missing-decl.patch"
|
||||
]
|
||||
},
|
||||
"vulkan-headers": {
|
||||
"package": "VulkanHeaders",
|
||||
"version": "1.3.274",
|
||||
"repo": "KhronosGroup/Vulkan-Headers",
|
||||
"sha": "89268a6d17",
|
||||
"hash": "3ab349f74298ba72cafb8561015690c0674d428a09fb91ccd3cd3daca83650d190d46d33fd97b0a8fd4223fe6df2bcabae89136fbbf7c0bfeb8776f9448304c8"
|
||||
},
|
||||
"vulkan-utility-libraries": {
|
||||
"package": "VulkanUtilityLibraries",
|
||||
"repo": "KhronosGroup/Vulkan-Utility-Libraries",
|
||||
"sha": "df2e358152",
|
||||
"hash": "3e468c3d9ff93f6d418d71e5527abe0a12c8c7ab5b0b52278bbbee4d02bb87e99073906729b727e0147242b7e3fd5dedf68b803f1878cb4c0e4f730bc2238d79"
|
||||
},
|
||||
"vulkan-memory-allocator": {
|
||||
"package": "VulkanMemoryAllocator",
|
||||
"repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator",
|
||||
"sha": "1076b348ab",
|
||||
"hash": "a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772",
|
||||
"find_args": "CONFIG"
|
||||
},
|
||||
"spirv-tools": {
|
||||
"package": "SPIRV-Tools",
|
||||
"repo": "KhronosGroup/SPIRV-Tools",
|
||||
"sha": "40eb301f32",
|
||||
"hash": "58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa",
|
||||
"find_args": "MODULE",
|
||||
"options": [
|
||||
"SPIRV_SKIP_EXECUTABLES ON"
|
||||
]
|
||||
},
|
||||
"xbyak_sun": {
|
||||
"package": "xbyak",
|
||||
"repo": "herumi/xbyak",
|
||||
"sha": "9bb219333a",
|
||||
"hash": "303165d45c8c19387ec49d9fda7d7a4e0d86d4c0153898c23f25ce2d58ece567f44c0bbbfe348239b933edb6e1a1e34f4bc1c0ab3a285bee5da0e548879387b0",
|
||||
"bundled": true
|
||||
},
|
||||
"xbyak": {
|
||||
"package": "xbyak",
|
||||
"repo": "herumi/xbyak",
|
||||
"sha": "4e44f4614d",
|
||||
"hash": "5824e92159e07fa36a774aedd3b3ef3541d0241371d522cffa4ab3e1f215fa5097b1b77865b47b2481376c704fa079875557ea463ca63d0a7fd6a8a20a589e70",
|
||||
"bundled": true
|
||||
},
|
||||
"oaknut": {
|
||||
"version": "2.0.1",
|
||||
"repo": "merryhime/oaknut",
|
||||
"sha": "94c726ce03",
|
||||
"hash": "d8d082242fa1881abce3c82f8dafa002c4e561e66a69e7fc038af67faa5eff2630f082d3d19579c88c4c9f9488e54552accc8cb90e7ce743efe043b6230c08ac"
|
||||
},
|
||||
"libadrenotools": {
|
||||
"repo": "bylaws/libadrenotools",
|
||||
"sha": "8fae8ce254",
|
||||
"hash": "c74fa855f0edebbf25c9bce40b00966daa2447bfc5e15f0cf1a95f86cbf70fc6b02590707edbde16328a0a2a4fb9a1fc419d2dfc22a4a4150971be91892d4edb",
|
||||
"patches": [
|
||||
"0001-linkerns-cpm.patch"
|
||||
]
|
||||
},
|
||||
"oboe": {
|
||||
"repo": "google/oboe",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
}
|
49
externals/ffmpeg/CMakeLists.txt
vendored
49
externals/ffmpeg/CMakeLists.txt
vendored
@@ -1,6 +1,10 @@
|
||||
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Explicitly include CPMUtil here since we have a separate cpmfile for ffmpeg
|
||||
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
|
||||
include(CPMUtil)
|
||||
|
||||
if (NOT WIN32 AND NOT ANDROID)
|
||||
# Build FFmpeg from externals
|
||||
message(STATUS "Using FFmpeg from externals")
|
||||
@@ -19,13 +23,7 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
message(FATAL_ERROR "Required program `autoconf` not found.")
|
||||
endif()
|
||||
|
||||
AddPackage(
|
||||
NAME ffmpeg
|
||||
REPO "FFmpeg/FFmpeg"
|
||||
SHA c2184b65d2
|
||||
HASH 2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97
|
||||
SYSTEM_PACKAGE OFF
|
||||
)
|
||||
AddJsonPackage(ffmpeg)
|
||||
|
||||
set(FFmpeg_PREFIX ${ffmpeg_SOURCE_DIR})
|
||||
set(FFmpeg_BUILD_DIR ${ffmpeg_BINARY_DIR})
|
||||
@@ -65,32 +63,46 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
set(FFmpeg_HWACCEL_INCLUDE_DIRS)
|
||||
set(FFmpeg_HWACCEL_LDFLAGS)
|
||||
|
||||
if(LIBVA_FOUND)
|
||||
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
|
||||
X11
|
||||
"/usr/lib/xorg/amd64/libdrm.so")
|
||||
else()
|
||||
pkg_check_modules(LIBDRM libdrm REQUIRED)
|
||||
list(APPEND FFmpeg_HWACCEL_LIBRARIES
|
||||
${LIBDRM_LIBRARIES})
|
||||
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
|
||||
${LIBDRM_INCLUDE_DIRS})
|
||||
endif()
|
||||
list(APPEND FFmpeg_HWACCEL_FLAGS
|
||||
--enable-libdrm)
|
||||
endif()
|
||||
|
||||
if(LIBVA_FOUND)
|
||||
find_package(X11 REQUIRED)
|
||||
pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
|
||||
pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
|
||||
list(APPEND FFmpeg_HWACCEL_LIBRARIES
|
||||
${LIBDRM_LIBRARIES}
|
||||
${X11_LIBRARIES}
|
||||
${LIBVA-DRM_LIBRARIES}
|
||||
${LIBVA-X11_LIBRARIES}
|
||||
${LIBVA_LIBRARIES})
|
||||
set(FFmpeg_HWACCEL_FLAGS
|
||||
list(APPEND FFmpeg_HWACCEL_FLAGS
|
||||
--enable-hwaccel=h264_vaapi
|
||||
--enable-hwaccel=vp8_vaapi
|
||||
--enable-hwaccel=vp9_vaapi
|
||||
--enable-libdrm)
|
||||
--enable-hwaccel=vp9_vaapi)
|
||||
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
|
||||
${LIBDRM_INCLUDE_DIRS}
|
||||
${X11_INCLUDE_DIRS}
|
||||
${LIBVA-DRM_INCLUDE_DIRS}
|
||||
${LIBVA-X11_INCLUDE_DIRS}
|
||||
${LIBVA_INCLUDE_DIRS}
|
||||
)
|
||||
message(STATUS "VA-API found")
|
||||
message(STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found")
|
||||
else()
|
||||
set(FFmpeg_HWACCEL_FLAGS --disable-vaapi)
|
||||
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
|
||||
message(WARNING "ffmpeg: libva-dev not found, disabling Video Aceleraion API (VA-API)...")
|
||||
endif()
|
||||
|
||||
if (FFNVCODEC_FOUND)
|
||||
@@ -105,7 +117,7 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${FFNVCODEC_LIBRARIES})
|
||||
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${FFNVCODEC_INCLUDE_DIRS})
|
||||
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${FFNVCODEC_LDFLAGS})
|
||||
message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
|
||||
message(STATUS "ffmpeg: ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
|
||||
# ffnvenc could load CUDA libraries at the runtime using dlopen/dlsym or LoadLibrary/GetProcAddress
|
||||
# here we handle the hard-linking senario where CUDA is linked during compilation
|
||||
if (CUDA_FOUND)
|
||||
@@ -114,7 +126,7 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${CUDA_LIBRARIES})
|
||||
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS})
|
||||
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${CUDA_LDFLAGS})
|
||||
message(STATUS "CUDA libraries found, hard-linking will be performed")
|
||||
message(STATUS "ffmpeg: CUDA libraries found, hard-linking will be performed")
|
||||
endif(CUDA_FOUND)
|
||||
endif()
|
||||
|
||||
@@ -127,9 +139,10 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES})
|
||||
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS})
|
||||
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS})
|
||||
message(STATUS "vdpau libraries version ${VDPAU_VERSION} found")
|
||||
message(STATUS "ffmpeg: vdpau libraries version ${VDPAU_VERSION} found")
|
||||
else()
|
||||
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
|
||||
message(WARNING "ffmpeg: libvdpau-dev not found, disabling Video Decode and Presentation API for Unix (VDPAU)...")
|
||||
endif()
|
||||
|
||||
find_program(BASH_PROGRAM bash REQUIRED)
|
||||
|
8
externals/ffmpeg/cpmfile.json
vendored
Normal file
8
externals/ffmpeg/cpmfile.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"ffmpeg": {
|
||||
"repo": "FFmpeg/FFmpeg",
|
||||
"sha": "c2184b65d2",
|
||||
"hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
96
externals/nx_tzdb/CMakeLists.txt
vendored
96
externals/nx_tzdb/CMakeLists.txt
vendored
@@ -1,6 +1,13 @@
|
||||
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Explicitly include CPMUtil here since we have a separate cpmfile for nx_tzdb
|
||||
set(CPMUTIL_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json)
|
||||
include(CPMUtil)
|
||||
|
||||
set(NX_TZDB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
|
||||
|
||||
add_library(nx_tzdb INTERFACE)
|
||||
@@ -11,33 +18,38 @@ find_program(DATE_PROG date)
|
||||
|
||||
set(CAN_BUILD_NX_TZDB true)
|
||||
|
||||
if (NOT GIT)
|
||||
set(CAN_BUILD_NX_TZDB false)
|
||||
endif()
|
||||
if (NOT GNU_MAKE)
|
||||
set(CAN_BUILD_NX_TZDB false)
|
||||
endif()
|
||||
if (NOT DATE_PROG)
|
||||
set(CAN_BUILD_NX_TZDB false)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID)
|
||||
if (NOT (GIT AND GNU_MAKE AND DATE_PROG) OR CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID)
|
||||
# tzdb_to_nx currently requires a posix-compliant host
|
||||
# MinGW and Android are handled here due to the executable format being different from the host system
|
||||
# TODO (lat9nq): cross-compiling support
|
||||
|
||||
set(CAN_BUILD_NX_TZDB false)
|
||||
endif()
|
||||
|
||||
if (CAN_BUILD_NX_TZDB AND NOT YUZU_DOWNLOAD_TIME_ZONE_DATA)
|
||||
message(FATAL_ERROR "Building tzdb is currently unsupported. Check back later.")
|
||||
add_subdirectory(tzdb_to_nx)
|
||||
add_dependencies(nx_tzdb x80e)
|
||||
|
||||
set(NX_TZDB_BASE_DIR "${NX_TZDB_DIR}")
|
||||
set(NX_TZDB_TZ_DIR "${NX_TZDB_BASE_DIR}/zoneinfo")
|
||||
endif()
|
||||
|
||||
# TODO(crueter): This is a terrible solution, but MSVC fails to link without it
|
||||
# Need to investigate further but I still can't reproduce...
|
||||
if (MSVC)
|
||||
set(NX_TZDB_VERSION "250725")
|
||||
set(NX_TZDB_ARCHIVE "${CPM_SOURCE_CACHE}/nx_tzdb/${NX_TZDB_VERSION}.zip")
|
||||
|
||||
set(NX_TZDB_ROMFS_DIR "${CPM_SOURCE_CACHE}/nx_tzdb/tz")
|
||||
set(NX_TZDB_BASE_DIR "${CPM_SOURCE_CACHE}/nx_tzdb/tz")
|
||||
set(NX_TZDB_TZ_DIR "${NX_TZDB_BASE_DIR}/zoneinfo")
|
||||
|
||||
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ROMFS_DIR})
|
||||
set(NX_TZDB_DOWNLOAD_URL "https://github.com/crueter/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip")
|
||||
|
||||
message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...")
|
||||
file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE}
|
||||
STATUS NX_TZDB_DOWNLOAD_STATUS)
|
||||
|
||||
list(GET NX_TZDB_DOWNLOAD_STATUS 0 NX_TZDB_DOWNLOAD_STATUS_CODE)
|
||||
if (NOT NX_TZDB_DOWNLOAD_STATUS_CODE EQUAL 0)
|
||||
message(FATAL_ERROR "Time zone data download failed (status code ${NX_TZDB_DOWNLOAD_STATUS_CODE})")
|
||||
@@ -47,13 +59,17 @@ if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_
|
||||
INPUT
|
||||
${NX_TZDB_ARCHIVE}
|
||||
DESTINATION
|
||||
${NX_TZDB_ROMFS_DIR})
|
||||
elseif (CAN_BUILD_NX_TZDB AND NOT YUZU_DOWNLOAD_TIME_ZONE_DATA)
|
||||
# TODO(crueter): this sucked to do with cpm, see if i can get it to work again
|
||||
add_subdirectory(tzdb_to_nx)
|
||||
add_dependencies(nx_tzdb x80e)
|
||||
${NX_TZDB_BASE_DIR})
|
||||
else()
|
||||
message(STATUS "Downloading time zone data...")
|
||||
AddJsonPackage(tzdb)
|
||||
|
||||
set(NX_TZDB_ROMFS_DIR "${NX_TZDB_DIR}")
|
||||
target_include_directories(nx_tzdb
|
||||
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
INTERFACE ${NX_TZDB_INCLUDE_DIR})
|
||||
|
||||
set(NX_TZDB_BASE_DIR "${CPM_SOURCE_CACHE}/nx_tzdb")
|
||||
set(NX_TZDB_TZ_DIR "${nx_tzdb_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
target_include_directories(nx_tzdb
|
||||
@@ -78,25 +94,25 @@ function(CreateHeader ZONE_PATH HEADER_NAME)
|
||||
target_sources(nx_tzdb PRIVATE ${HEADER_PATH})
|
||||
endfunction()
|
||||
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR} base)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo zoneinfo)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Africa africa)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America america)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Argentina america_argentina)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Indiana america_indiana)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Kentucky america_kentucky)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/North_Dakota america_north_dakota)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Antarctica antarctica)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Arctic arctic)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Asia asia)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Atlantic atlantic)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Australia australia)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Brazil brazil)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Canada canada)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Chile chile)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Etc etc)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Europe europe)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Indian indian)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Mexico mexico)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Pacific pacific)
|
||||
CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/US us)
|
||||
CreateHeader(${NX_TZDB_BASE_DIR} base)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR} zoneinfo)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Africa africa)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/America america)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/America/Argentina america_argentina)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/America/Indiana america_indiana)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/America/Kentucky america_kentucky)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/America/North_Dakota america_north_dakota)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Antarctica antarctica)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Arctic arctic)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Asia asia)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Atlantic atlantic)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Australia australia)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Brazil brazil)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Canada canada)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Chile chile)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Etc etc)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Europe europe)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Indian indian)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Mexico mexico)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/Pacific pacific)
|
||||
CreateHeader(${NX_TZDB_TZ_DIR}/US us)
|
||||
|
8
externals/nx_tzdb/cpmfile.json
vendored
Normal file
8
externals/nx_tzdb/cpmfile.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"tzdb": {
|
||||
"package": "nx_tzdb",
|
||||
"url": "https://github.com/crueter/tzdb_to_nx/releases/download/250725/250725.zip",
|
||||
"hash": "8f60b4b29f285e39c0443f3d5572a73780f3dbfcfd5b35004451fadad77f3a215b2e2aa8d0fffe7e348e2a7b0660882b35228b6178dda8804a14ce44509fd2ca",
|
||||
"version": "250725"
|
||||
}
|
||||
}
|
@@ -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,9 +173,13 @@ 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"
|
||||
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
|
||||
"-DBUILD_TESTING=OFF",
|
||||
"-DYUZU_TESTS=OFF",
|
||||
"-DDYNARMIC_TESTS=OFF"
|
||||
)
|
||||
|
||||
abiFilters("arm64-v8a")
|
||||
|
@@ -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()
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
USE_FAST_CPU_TIME("use_fast_cpu_time"),
|
||||
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
|
||||
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
|
||||
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
|
||||
USE_DOCKED_MODE("use_docked_mode"),
|
||||
USE_AUTO_STUB("use_auto_stub"),
|
||||
RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache"),
|
||||
@@ -34,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"),
|
||||
@@ -65,7 +67,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
SHOW_POWER_INFO("show_power_info"),
|
||||
SHOW_SHADERS_BUILDING("show_shaders_building"),
|
||||
|
||||
DEBUG_FLUSH_BY_LINE("flush_lines"),
|
||||
DEBUG_FLUSH_BY_LINE("flush_line"),
|
||||
USE_LRU_CACHE("use_lru_cache");
|
||||
|
||||
external fun isRaiiEnabled(): Boolean
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
@@ -673,6 +679,13 @@ abstract class SettingsItem(
|
||||
descriptionId = R.string.skip_cpu_inner_invalidation_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.CPUOPT_UNSAFE_HOST_MMU,
|
||||
titleId = R.string.cpuopt_unsafe_host_mmu,
|
||||
descriptionId = R.string.cpuopt_unsafe_host_mmu_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.RENDERER_REACTIVE_FLUSHING,
|
||||
|
@@ -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)
|
||||
@@ -466,6 +467,7 @@ class SettingsFragmentPresenter(
|
||||
add(BooleanSetting.USE_CUSTOM_CPU_TICKS.key)
|
||||
add(IntSetting.CPU_TICKS.key)
|
||||
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
||||
add(BooleanSetting.CPUOPT_UNSAFE_HOST_MMU.key)
|
||||
add(BooleanSetting.USE_LRU_CACHE.key)
|
||||
add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
|
||||
add(BooleanSetting.SYNC_MEMORY_OPERATIONS.key)
|
||||
|
@@ -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"
|
||||
)
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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("\"", "\"")
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -117,6 +117,8 @@
|
||||
<string name="cpu_ticks">دورات</string>
|
||||
<string name="skip_cpu_inner_invalidation">تخطي إبطال ذاكرة التخزين المؤقت الداخلية للوحدة المركزية</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقت أثناء تحديثات الذاكرة، مما يقلل استخدام المعالج ويحسن أدائه. قد يسبب هذا أعطالاً أو تعطلًا في بعض الألعاب.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">تمكين محاكاة MMU المضيف</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">يعمل هذا التحسين على تسريع وصول الذاكرة بواسطة البرنامج الضيف. يؤدي تمكينه إلى إجراء عمليات قراءة/كتابة ذاكرة الضيف مباشرة في الذاكرة والاستفادة من MMU المضيف. يؤدي تعطيل هذا إلى إجبار جميع عمليات الوصول إلى الذاكرة على استخدام محاكاة MMU البرمجية.</string>
|
||||
<string name="dma_accuracy">مستوى DMA</string>
|
||||
<string name="dma_accuracy_description">يتحكم في دقة تحديد مستوى DMA. الدقة الأعلى يمكنها إصلاح بعض المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اتركه على الوضع الافتراضي.</string>
|
||||
|
||||
@@ -496,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>
|
||||
@@ -731,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">تیک</string>
|
||||
<string name="skip_cpu_inner_invalidation">بازنەکردنی ناوەکی CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">هەندێک لە بازنەکردنەکانی هەڵگر لە کاتی نوێکردنەوەی بیرگە دەنێرێت، کەمکردنەوەی بەکارهێنانی CPU و باشترکردنی کارایی. لەوانەیە لە هەندێک یاری کێشە درووست بکات.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">چالاککردنی میمیکردنی MMU میواندە</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">ئەم باشکردنە خێرایی دەستکەوتنی بیرگە لەلایەن پرۆگرامی میوانەکە زیاد دەکات. چالاککردنی وای لێدەکات کە خوێندنەوە/نووسینەکانی بیرگەی میوانەکە ڕاستەوخۆ لە بیرگە ئەنجام بدرێت و میمیکردنی MMU میواندە بەکاربهێنێت. ناچالاککردنی ئەمە هەموو دەستکەوتنەکانی بیرگە ڕەت دەکاتەوە لە بەکارهێنانی میمیکردنی MMU نەرمەکاڵا.</string>
|
||||
<string name="dma_accuracy">ئاستی DMA</string>
|
||||
<string name="dma_accuracy_description">کۆنتڕۆڵی وردی ڕێکخستنی DMA دەکات. وردی زیاتر دەتوانێ هەندێک کێشە لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، بە ڕێکخستنی بنەڕەتی بێڵە.</string>
|
||||
|
||||
@@ -480,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>
|
||||
@@ -708,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>
|
||||
|
@@ -125,6 +125,8 @@
|
||||
<string name="cpu_ticks">Takty</string>
|
||||
<string name="skip_cpu_inner_invalidation">Přeskočit vnitřní invalidaci CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Přeskočí některé invalidace mezipaměti na straně CPU během aktualizací paměti, čímž sníží zatížení CPU a zlepší jeho výkon. Může způsobit chyby nebo pády v některých hrách.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Povolit emulaci hostitelské MMU</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Tato optimalizace zrychluje přístup do paměti hostovaného programu. Její povolení způsobí, že čtení a zápisy do paměti hosta se provádějí přímo v paměti a využívají hostitelskou MMU. Zakázání této funkce vynutí použití softwarové emulace MMU pro všechny přístupy do paměti.</string>
|
||||
<string name="dma_accuracy">Úroveň DMA</string>
|
||||
<string name="dma_accuracy_description">Ovládá přesnost DMA. Vyšší přesnost může opravit problémy v některých hrách, ale může také ovlivnit výkon. Pokud si nejste jisti, ponechejte výchozí nastavení.</string>
|
||||
|
||||
@@ -456,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>
|
||||
@@ -689,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Ticks</string>
|
||||
<string name="skip_cpu_inner_invalidation">CPU-interne Invalidierung überspringen</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Überspringt bestimmte Cache-Invalidierungen auf CPU-Seite während Speicherupdates, reduziert die CPU-Auslastung und verbessert die Leistung. Kann in einigen Spielen zu Fehlern oder Abstürzen führen.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Host-MMU-Emulation aktivieren</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Diese Optimierung beschleunigt Speicherzugriffe durch das Gastprogramm. Wenn aktiviert, erfolgen Speicherlese- und -schreibvorgänge des Gastes direkt im Speicher und nutzen die MMU des Hosts. Das Deaktivieren erzwingt die Verwendung der Software-MMU-Emulation für alle Speicherzugriffe.</string>
|
||||
<string name="dma_accuracy">DMA-Level</string>
|
||||
<string name="dma_accuracy_description">Steuert die DMA-Präzisionsgenauigkeit. Eine höhere Präzision kann Probleme in einigen Spielen beheben, kann aber in einigen Fällen auch die Leistung beeinträchtigen. Im Zweifel auf „Standard“ belassen.</string>
|
||||
|
||||
@@ -484,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>
|
||||
@@ -760,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Ticks</string>
|
||||
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché durante actualizaciones de memoria, reduciendo el uso de CPU y mejorando su rendimiento. Puede causar fallos en algunos juegos.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Habilitar emulación de MMU del host</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Esta optimización acelera los accesos a la memoria por parte del programa invitado. Al habilitarla, las lecturas/escrituras de memoria del invitado se realizan directamente en la memoria y utilizan la MMU del host. Deshabilitar esto obliga a que todos los accesos a la memoria utilicen la emulación de MMU por software.</string>
|
||||
<string name="dma_accuracy">Nivel de DMA</string>
|
||||
<string name="dma_accuracy_description">Controla la precisión del DMA. Una mayor precisión puede solucionar problemas en algunos juegos, pero también puede afectar el rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
|
||||
|
||||
@@ -504,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>
|
||||
@@ -804,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">تیکها</string>
|
||||
<string name="skip_cpu_inner_invalidation">رد کردن ابطال داخلی CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">بعضی ابطالهای حافظه نهان در هنگام بهروزرسانیهای حافظه را رد میکند، استفاده از CPU را کاهش داده و عملکرد آن را بهبود میبخشد. ممکن است در برخی بازیها باعث مشکلات یا خرابی شود.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">فعالسازی شبیهسازی MMU میزبان</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">این بهینهسازی دسترسیهای حافظه توسط برنامه میهمان را تسریع میکند. فعالسازی آن باعث میشود خواندن/نوشتن حافظه میهمان مستقیماً در حافظه انجام شود و از MMU میزبان استفاده کند. غیرفعال کردن این قابلیت، همه دسترسیهای حافظه را مجبور به استفاده از شبیهسازی نرمافزاری MMU میکند.</string>
|
||||
<string name="dma_accuracy">سطح DMA</string>
|
||||
<string name="dma_accuracy_description">دقت صحت DMA را کنترل می کند. دقت بالاتر می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز می تواند بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، آن را روی پیش فرض بگذارید.</string>
|
||||
|
||||
@@ -502,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>
|
||||
@@ -803,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Ticks</string>
|
||||
<string name="skip_cpu_inner_invalidation">Ignorer l\'invalidation interne du CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Activer l\'émulation de la MMU hôte</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Cette optimisation accélère les accès mémoire par le programme invité. L\'activer entraîne que les lectures/écritures mémoire de l\'invité sont effectuées directement en mémoire et utilisent la MMU de l\'hôte. Désactiver cela force tous les accès mémoire à utiliser l\'émulation logicielle de la MMU.</string>
|
||||
<string name="dma_accuracy">Niveau DMA</string>
|
||||
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision plus élevée peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez-la sur Défaut.</string>
|
||||
|
||||
@@ -504,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>
|
||||
@@ -852,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>
|
||||
|
@@ -127,6 +127,8 @@
|
||||
<string name="cpu_ticks">טיקים</string>
|
||||
<string name="skip_cpu_inner_invalidation">דלג על איפוס מטמון פנימי של המעבד</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">מדלג על איפוסי מטמון מסוימים במהלך עדכוני זיכרון, מפחית שימוש במעבד ומשפר ביצועים. עלול לגרום לתקלות או קריסות בחלק מהמשחקים.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">הפעל אמולציית MMU מארח</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">אופטימיזציה זו מאיצה את גישת הזיכרון על ידי התוכנית האורחת. הפעלתה גורמת לכך שפעולות קריאה/כתיבה לזיכרון האורח מתבצעות ישירות לזיכרון ומשתמשות ב-MMU של המארח. השבתת זאת מאלצת את כל גישות הזיכרון להשתמש באמולציית MMU תוכנתית.</string>
|
||||
<string name="dma_accuracy">רמת DMA</string>
|
||||
<string name="dma_accuracy_description">שולטת בדיוק הדיוק של DMA. דיוק גבוה יותר יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר ברירת מחדל.</string>
|
||||
|
||||
@@ -503,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>
|
||||
@@ -737,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Tick-ek</string>
|
||||
<string name="skip_cpu_inner_invalidation">CPU belső érvénytelenítés kihagyása</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Kihagy néhány CPU-oldali gyorsítótár-érvénytelenítést memóriafrissítések közben, csökkentve a CPU használatát és javítva a teljesítményt. Néhány játékban hibákat vagy összeomlást okozhat.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Gazda MMU emuláció engedélyezése</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Ez az optimalizáció gyorsítja a vendégprogram memória-hozzáférését. Engedélyezése esetén a vendég memóriaolvasási/írási műveletei közvetlenül a memóriában történnek, és kihasználják a gazda MMU-ját. Letiltás esetén minden memória-hozzáférés a szoftveres MMU emulációt használja.</string>
|
||||
<string name="dma_accuracy">DMA szint</string>
|
||||
<string name="dma_accuracy_description">Szabályozza a DMA pontosságát. A magasabb pontosság megoldhat néhány játék problémáit, de bizonyos esetekben befolyásolhatja a teljesítményt. Ha bizonytalan, hagyja Alapértelmezett beállításnál.</string>
|
||||
|
||||
@@ -499,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>
|
||||
@@ -841,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Ticks</string>
|
||||
<string name="skip_cpu_inner_invalidation">Lewati Pembatalan Internal CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Melewati beberapa pembatalan cache sisi CPU selama pembaruan memori, mengurangi penggunaan CPU dan meningkatkan kinerjanya. Mungkin menyebabkan gangguan atau crash pada beberapa game.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Aktifkan Emulasi MMU Host</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Optimasi ini mempercepat akses memori oleh program tamu. Mengaktifkannya menyebabkan pembacaan/penulisan memori tamu dilakukan langsung ke memori dan memanfaatkan MMU Host. Menonaktifkan ini memaksa semua akses memori menggunakan Emulasi MMU Perangkat Lunak.</string>
|
||||
<string name="dma_accuracy">Level DMA</string>
|
||||
<string name="dma_accuracy_description">Mengontrol akurasi presisi DMA. Presisi yang lebih tinggi dapat memperbaiki masalah di beberapa game, tetapi juga dapat memengaruhi performa dalam beberapa kasus. Jika tidak yakin, biarkan di Bawaan.</string>
|
||||
|
||||
@@ -500,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>
|
||||
@@ -796,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Tick</string>
|
||||
<string name="skip_cpu_inner_invalidation">Salta invalidamento interno CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Salta alcuni invalidamenti della cache lato CPU durante gli aggiornamenti di memoria, riducendo l\'uso della CPU e migliorandone le prestazioni. Potrebbe causare glitch o crash in alcuni giochi.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Abilita emulazione MMU host</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Questa ottimizzazione accelera gli accessi alla memoria da parte del programma guest. Abilitandola, le letture/scritture della memoria guest vengono eseguite direttamente in memoria e sfruttano la MMU host. Disabilitandola, tutti gli accessi alla memoria sono costretti a utilizzare l\'emulazione software della MMU.</string>
|
||||
<string name="dma_accuracy">Livello DMA</string>
|
||||
<string name="dma_accuracy_description">Controlla la precisione del DMA. Una precisione più alta può risolvere problemi in alcuni giochi, ma in alcuni casi può influire sulle prestazioni. Se non sei sicuro, lascia su Predefinito.</string>
|
||||
|
||||
@@ -503,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>
|
||||
@@ -768,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">ティック</string>
|
||||
<string name="skip_cpu_inner_invalidation">CPU内部無効化をスキップ</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">メモリ更新時のCPU側キャッシュ無効化をスキップし、CPU使用率を減らして性能を向上させます。一部のゲームで不具合やクラッシュが発生する可能性があります。</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">ホストMMUエミュレーションを有効化</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">この最適化により、ゲストプログラムによるメモリアクセスが高速化されます。有効にすると、ゲストのメモリ読み書きが直接メモリ内で実行され、ホストのMMUを利用します。無効にすると、すべてのメモリアクセスでソフトウェアMMUエミュレーションが使用されます。</string>
|
||||
<string name="dma_accuracy">DMAレベル</string>
|
||||
<string name="dma_accuracy_description">DMAの精度を制御します。精度を高くすると一部のゲームの問題が修正される場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、デフォルトのままにしてください。</string>
|
||||
|
||||
@@ -489,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>
|
||||
@@ -727,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">틱</string>
|
||||
<string name="skip_cpu_inner_invalidation">CPU 내부 무효화 건너뛰기</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">메모리 업데이트 시 일부 CPU 측 캐시 무효화를 건너뛰어 CPU 사용량을 줄이고 성능을 향상시킵니다. 일부 게임에서 오류 또는 충돌을 일으킬 수 있습니다.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">호스트 MMU 에뮬레이션 사용</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">이 최적화는 게스트 프로그램의 메모리 접근 속도를 높입니다. 활성화하면 게스트의 메모리 읽기/쓰기가 메모리에서 직접 수행되고 호스트의 MMU를 활용합니다. 비활성화하면 모든 메모리 접근에 소프트웨어 MMU 에뮬레이션을 사용하게 됩니다.</string>
|
||||
<string name="dma_accuracy">DMA 수준</string>
|
||||
<string name="dma_accuracy_description">DMA 정밀도를 제어합니다. 높은 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않다면 기본값으로 두세요.</string>
|
||||
|
||||
@@ -499,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>
|
||||
@@ -796,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Takter</string>
|
||||
<string name="skip_cpu_inner_invalidation">Hopp over CPU intern invalidering</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Hopper over enkelte CPU-side cache-invalideringer under minneoppdateringer, reduserer CPU-bruk og forbedrer ytelsen. Kan forårsake feil eller krasj i noen spill.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Aktiver verts-MMU-emulering</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Denne optimaliseringen fremskynder minnetilgang av gjesteprogrammet. Hvis aktivert, utføres gjestens minnelesing/skriving direkte i minnet og bruker vertens MMU. Deaktivering tvinger alle minnetilganger til å bruke programvarebasert MMU-emulering.</string>
|
||||
<string name="dma_accuracy">DMA-nivå</string>
|
||||
<string name="dma_accuracy_description">Styrer DMA-presisjonsnøyaktigheten. Høyere presisjon kan fikse problemer i noen spill, men kan også påvirke ytelsen i noen tilfeller. Hvis du er usikker, la den stå på Standard.</string>
|
||||
|
||||
@@ -480,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>
|
||||
@@ -718,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Takty</string>
|
||||
<string name="skip_cpu_inner_invalidation">Pomiń wewnętrzne unieważnienie CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Pomija niektóre unieważnienia pamięci podręcznej po stronie CPU podczas aktualizacji pamięci, zmniejszając użycie CPU i poprawiając jego wydajność. Może powodować błędy lub awarie w niektórych grach.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Włącz emulację MMU hosta</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Ta optymalizacja przyspiesza dostęp do pamięci przez program gościa. Włączenie powoduje, że odczyty/zapisy pamięci gościa są wykonywane bezpośrednio w pamięci i wykorzystują MMU hosta. Wyłączenie wymusza użycie programowej emulacji MMU dla wszystkich dostępów do pamięci.</string>
|
||||
<string name="dma_accuracy">Poziom DMA</string>
|
||||
<string name="dma_accuracy_description">Kontroluje dokładność precyzji DMA. Wyższy poziom może naprawić problemy w niektórych grach, ale może również wpłynąć na wydajność. Jeśli nie jesteś pewien, pozostaw wartość «Domyślny».</string>
|
||||
|
||||
@@ -480,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>
|
||||
@@ -716,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Ticks</string>
|
||||
<string name="skip_cpu_inner_invalidation">Pular invalidação interna da CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Ignora algumas invalidações de cache do lado da CPU durante atualizações de memória, reduzindo o uso da CPU e melhorando seu desempenho. Pode causar falhas ou travamentos em alguns jogos.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Ativar Emulação de MMU do Host</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Esta otimização acelera os acessos à memória pelo programa convidado. Ativar isso faz com que as leituras/gravações de memória do convidado sejam feitas diretamente na memória e utilizem a MMU do Host. Desativar isso força todos os acessos à memória a usarem a Emulação de MMU por Software.</string>
|
||||
<string name="dma_accuracy">Nível DMA</string>
|
||||
<string name="dma_accuracy_description">Controla a precisão do DMA. Maior precisão pode corrigir problemas em alguns jogos, mas também pode impactar o desempenho em alguns casos. Se não tiver certeza, deixe em Padrão.</string>
|
||||
|
||||
@@ -504,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>
|
||||
@@ -853,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Ticks</string>
|
||||
<string name="skip_cpu_inner_invalidation">Ignorar invalidação interna da CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Ignora algumas invalidações de cache do lado da CPU durante atualizações de memória, reduzindo a utilização da CPU e melhorando o desempenho. Pode causar falhas ou crashes em alguns jogos.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Ativar Emulação de MMU do Anfitrião</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Esta otimização acelera os acessos à memória pelo programa convidado. Ativar faz com que as leituras/escritas de memória do convidado sejam efetuadas diretamente na memória e utilizem a MMU do Anfitrião. Desativar força todos os acessos à memória a usar a Emulação de MMU por Software.</string>
|
||||
<string name="dma_accuracy">Nível DMA</string>
|
||||
<string name="dma_accuracy_description">Controla a precisão do DMA. Maior precisão pode corrigir problemas em alguns jogos, mas também pode afetar o desempenho nalguns casos. Se não tiver a certeza, deixe em Predefinido.</string>
|
||||
|
||||
@@ -504,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>
|
||||
@@ -853,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Такты</string>
|
||||
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Включить эмуляцию MMU хоста</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Эта оптимизация ускоряет доступ к памяти гостевой программой. При включении операции чтения/записи памяти гостя выполняются напрямую в памяти с использованием MMU хоста. Отключение заставляет все обращения к памяти использовать программную эмуляцию MMU.</string>
|
||||
<string name="dma_accuracy">Уровень DMA</string>
|
||||
<string name="dma_accuracy_description">Управляет точностью DMA. Более высокий уровень может исправить проблемы в некоторых играх, но также может повлиять на производительность. Если не уверены, оставьте значение «По умолчанию».</string>
|
||||
|
||||
@@ -506,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>
|
||||
@@ -854,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>
|
||||
|
@@ -119,6 +119,8 @@
|
||||
<string name="cpu_ticks">Тактови</string>
|
||||
<string name="skip_cpu_inner_invalidation">Preskoči unutrašnje poništavanje CPU-a</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Preskače određena poništavanja keša na strani CPU-a tokom ažuriranja memorije, smanjujući opterećenje procesora i poboljšavajući performanse. Može izazvati greške u nekim igrama.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Омогући емулацију MMU домаћина</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Ова оптимизација убрзава приступ меморији од стране гостујућег програма. Укључивање изазива да се читања/уписа меморије госта обављају директно у меморији и користе MMU домаћина. Искључивање присиљава све приступе меморији да користе софтверску емулацију MMU.</string>
|
||||
<string name="dma_accuracy">DMA ниво</string>
|
||||
<string name="dma_accuracy_description">Контролише тачност DMA прецизности. Виши ниво може да поправи проблеме у неким играма, али може и да утиче на перформансе. Ако нисте сигурни, оставите на «Подразумевано».</string>
|
||||
|
||||
@@ -455,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>
|
||||
@@ -810,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Такти</string>
|
||||
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Увімкнути емуляцію MMU хоста</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Ця оптимізація пришвидшує доступ до пам\'яті гостьовою програмою. Увімкнення призводить до того, що читання/запис пам\'яті гостя виконуються безпосередньо в пам\'яті та використовують MMU хоста. Вимкнення змушує всі звернення до пам\'яті використовувати програмну емуляцію MMU.</string>
|
||||
<string name="dma_accuracy">Рівень DMA</string>
|
||||
<string name="dma_accuracy_description">Керує точністю DMA. Вищий рівень може виправити проблеми в деяких іграх, але також може вплинути на продуктивність. Якщо не впевнені, залиште значення «Типово».</string>
|
||||
|
||||
@@ -493,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>
|
||||
@@ -747,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>
|
||||
|
@@ -126,6 +126,8 @@
|
||||
<string name="cpu_ticks">Tích</string>
|
||||
<string name="skip_cpu_inner_invalidation">Bỏ qua vô hiệu hóa bên trong CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Bỏ qua một số lần vô hiệu hóa bộ nhớ đệm phía CPU trong khi cập nhật bộ nhớ, giảm mức sử dụng CPU và cải thiện hiệu suất. Có thể gây ra lỗi hoặc treo máy trong một số trò chơi.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Bật giả lập MMU Máy chủ</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">Tối ưu hóa này tăng tốc độ truy cập bộ nhớ của chương trình khách. Bật nó lên khiến các thao tác đọc/ghi bộ nhớ khách được thực hiện trực tiếp vào bộ nhớ và sử dụng MMU của Máy chủ. Tắt tính năng này buộc tất cả quyền truy cập bộ nhớ phải sử dụng Giả lập MMU Phần mềm.</string>
|
||||
<string name="dma_accuracy">Cấp độ DMA</string>
|
||||
<string name="dma_accuracy_description">Điều khiển độ chính xác của DMA. Độ chính xác cao hơn có thể sửa lỗi trong một số trò chơi, nhưng cũng có thể ảnh hưởng đến hiệu suất trong một số trường hợp. Nếu không chắc chắn, hãy để ở Mặc định.</string>
|
||||
|
||||
@@ -480,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>
|
||||
@@ -721,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>
|
||||
|
@@ -125,6 +125,8 @@
|
||||
<string name="cpu_ticks">时钟</string>
|
||||
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">启用主机 MMU 模拟</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">此优化可加速来宾程序的内存访问。启用后,来宾内存读取/写入将直接在内存中执行并利用主机的 MMU。禁用此功能将强制所有内存访问使用软件 MMU 模拟。</string>
|
||||
<string name="dma_accuracy">DMA 级别</string>
|
||||
<string name="dma_accuracy_description">控制 DMA 精度。更高的精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。</string>
|
||||
|
||||
@@ -498,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>
|
||||
@@ -846,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>
|
||||
|
@@ -118,6 +118,8 @@
|
||||
<string name="cpu_ticks">時脈</string>
|
||||
<string name="skip_cpu_inner_invalidation">跳過CPU內部無效化</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">在記憶體更新期間跳過某些CPU端快取無效化,減少CPU使用率並提高其性能。可能會導致某些遊戲出現故障或崩潰。</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">啟用主機 MMU 模擬</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">此最佳化可加速來賓程式的記憶體存取。啟用後,來賓記憶體讀取/寫入將直接在記憶體中執行並利用主機的 MMU。停用此功能將強制所有記憶體存取使用軟體 MMU 模擬。</string>
|
||||
<string name="dma_accuracy">DMA 級別</string>
|
||||
<string name="dma_accuracy_description">控制 DMA 精確度。更高的精確度可以修復某些遊戲中的問題,但在某些情況下也可能影響效能。如果不確定,請保留為「預設」。</string>
|
||||
|
||||
@@ -503,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>
|
||||
@@ -851,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>
|
||||
|
@@ -109,6 +109,8 @@
|
||||
<string name="cpu_ticks">Ticks</string>
|
||||
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
|
||||
<string name="cpuopt_unsafe_host_mmu">Enable Host MMU Emulation</string>
|
||||
<string name="cpuopt_unsafe_host_mmu_description">This optimization speeds up memory accesses by the guest program. Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host\'s MMU. Disabling this forces all memory accesses to use Software MMU Emulation.</string>
|
||||
<string name="fast_cpu_time">CPU Clock</string>
|
||||
<string name="fast_cpu_time_description">Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock.</string>
|
||||
<string name="memory_layout">Memory Layout</string>
|
||||
@@ -472,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>
|
||||
|
||||
@@ -780,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>
|
||||
@@ -833,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>
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#include "common/polyfill_ranges.h"
|
||||
|
||||
namespace AudioCore {
|
||||
constexpr u32 CurrentRevision = 13;
|
||||
constexpr u32 CurrentRevision = 15;
|
||||
|
||||
enum class SupportTags {
|
||||
CommandProcessingTimeEstimatorVersion4,
|
||||
|
@@ -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
|
||||
|
||||
@@ -148,7 +151,7 @@ Result OpusDecoder::DecodeInterleavedForMultiStream(u32* out_data_size, u64* out
|
||||
auto* header_p{reinterpret_cast<const OpusPacketHeader*>(input_data.data())};
|
||||
OpusPacketHeader header{ReverseHeader(*header_p)};
|
||||
|
||||
LOG_TRACE(Service_Audio, "header size 0x{:X} input data size 0x{:X} in_data size 0x{:X}",
|
||||
LOG_TRACE(Service_Audio, "header size {:#X} input data size 0x{:X} in_data size 0x{:X}",
|
||||
header.size, input_data.size_bytes(), in_data.size_bytes());
|
||||
|
||||
R_UNLESS(in_data.size_bytes() >= header.size &&
|
||||
|
@@ -272,18 +272,7 @@ if (lz4_ADDED)
|
||||
endif()
|
||||
|
||||
target_link_libraries(common PUBLIC fmt::fmt stb::headers Threads::Threads)
|
||||
target_link_libraries(common PRIVATE lz4::lz4 LLVM::Demangle)
|
||||
|
||||
if (TARGET libzstd_static)
|
||||
target_link_libraries(common PRIVATE libzstd_static)
|
||||
else()
|
||||
target_link_libraries(common PRIVATE zstd)
|
||||
endif()
|
||||
|
||||
if (TARGET unordered_dense::unordered_dense)
|
||||
# weird quirk of system installs
|
||||
target_link_libraries(common PUBLIC unordered_dense::unordered_dense)
|
||||
endif()
|
||||
target_link_libraries(common PRIVATE lz4::lz4 LLVM::Demangle zstd::zstd)
|
||||
|
||||
if(ANDROID)
|
||||
# For ASharedMemory_create
|
||||
|
@@ -517,24 +517,4 @@ std::string_view GetPathWithoutTop(std::string_view path) {
|
||||
return path.substr(std::min(name_bck_index, name_fwd_index) + 1);
|
||||
}
|
||||
|
||||
std::string_view GetFilename(std::string_view path) {
|
||||
const auto name_index = path.find_last_of("\\/");
|
||||
|
||||
if (name_index == std::string_view::npos) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return path.substr(name_index + 1);
|
||||
}
|
||||
|
||||
std::string_view GetExtensionFromFilename(std::string_view name) {
|
||||
const std::size_t index = name.rfind('.');
|
||||
|
||||
if (index == std::string_view::npos) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return name.substr(index + 1);
|
||||
}
|
||||
|
||||
} // namespace Common::FS
|
||||
|
@@ -352,9 +352,17 @@ enum class DirectorySeparator {
|
||||
[[nodiscard]] std::string_view GetPathWithoutTop(std::string_view path);
|
||||
|
||||
// Gets the filename of the path
|
||||
[[nodiscard]] std::string_view GetFilename(std::string_view path);
|
||||
[[nodiscard]] inline std::string_view GetFilename(const std::string_view path) noexcept {
|
||||
if (auto const name_index = path.find_last_of("\\/"); name_index != std::string_view::npos)
|
||||
return path.substr(name_index + 1);
|
||||
return {};
|
||||
}
|
||||
|
||||
// Gets the extension of the filename
|
||||
[[nodiscard]] std::string_view GetExtensionFromFilename(std::string_view name);
|
||||
[[nodiscard]] inline std::string_view GetExtensionFromFilename(const std::string_view name) noexcept {
|
||||
if (auto const index = name.rfind('.'); index != std::string_view::npos)
|
||||
return name.substr(index + 1);
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Common::FS
|
||||
|
@@ -1,13 +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 <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "common/heap_tracker.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/assert.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
@@ -36,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);
|
||||
}
|
||||
@@ -111,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);
|
||||
@@ -164,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
|
||||
|
@@ -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{};
|
||||
|
@@ -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,11 +429,12 @@ static void* ChooseVirtualBase(size_t virtual_size) {
|
||||
#else
|
||||
|
||||
static void* ChooseVirtualBase(size_t virtual_size) {
|
||||
#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)
|
||||
return virtual_base;
|
||||
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
|
||||
#endif
|
||||
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -477,19 +490,9 @@ class HostMemory::Impl {
|
||||
public:
|
||||
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
||||
: backing_size{backing_size_}, virtual_size{virtual_size_} {
|
||||
bool good = false;
|
||||
SCOPE_EXIT {
|
||||
if (!good) {
|
||||
Release();
|
||||
}
|
||||
};
|
||||
|
||||
long page_size = sysconf(_SC_PAGESIZE);
|
||||
if (page_size != 0x1000) {
|
||||
LOG_CRITICAL(HW_Memory, "page size {:#x} is incompatible with 4K paging", page_size);
|
||||
throw std::bad_alloc{};
|
||||
}
|
||||
|
||||
ASSERT_MSG(page_size == 0x1000, "page size {:#x} is incompatible with 4K paging",
|
||||
page_size);
|
||||
// Backing memory initialization
|
||||
#if defined(__sun__) || defined(__HAIKU__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||
@@ -498,41 +501,33 @@ 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
|
||||
if (fd < 0) {
|
||||
LOG_CRITICAL(HW_Memory, "memfd_create failed: {}", strerror(errno));
|
||||
throw std::bad_alloc{};
|
||||
}
|
||||
ASSERT_MSG(fd >= 0, "memfd_create failed: {}", strerror(errno));
|
||||
|
||||
// Defined to extend the file with zeros
|
||||
int ret = ftruncate(fd, backing_size);
|
||||
if (ret != 0) {
|
||||
LOG_CRITICAL(HW_Memory, "ftruncate failed with {}, are you out-of-memory?",
|
||||
strerror(errno));
|
||||
throw std::bad_alloc{};
|
||||
}
|
||||
ASSERT_MSG(ret == 0, "ftruncate failed with {}, are you out-of-memory?", strerror(errno));
|
||||
|
||||
backing_base = static_cast<u8*>(
|
||||
mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
||||
if (backing_base == MAP_FAILED) {
|
||||
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
|
||||
throw std::bad_alloc{};
|
||||
}
|
||||
ASSERT_MSG(backing_base != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
||||
|
||||
// Virtual memory initialization
|
||||
virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
|
||||
if (virtual_base == MAP_FAILED) {
|
||||
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
|
||||
throw std::bad_alloc{};
|
||||
}
|
||||
ASSERT_MSG(virtual_base != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
||||
#if defined(__linux__)
|
||||
madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
|
||||
#endif
|
||||
|
||||
free_manager.SetAddressSpace(virtual_base, virtual_size);
|
||||
good = true;
|
||||
}
|
||||
|
||||
~Impl() {
|
||||
@@ -669,14 +664,13 @@ private:
|
||||
FreeRegionManager free_manager{};
|
||||
};
|
||||
|
||||
#else // ^^^ Linux ^^^ vvv Generic vvv
|
||||
#else // ^^^ POSIX ^^^ vvv Generic vvv
|
||||
|
||||
class HostMemory::Impl {
|
||||
public:
|
||||
explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) {
|
||||
explicit Impl([[maybe_unused]] size_t backing_size, [[maybe_unused]] size_t virtual_size) {
|
||||
// This is just a place holder.
|
||||
// Please implement fastmem in a proper way on your platform.
|
||||
throw std::bad_alloc{};
|
||||
ASSERT_MSG(false, "Please implement fastmem in a proper way on your platform.");
|
||||
}
|
||||
|
||||
void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm) {}
|
||||
|
@@ -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
|
||||
|
||||
@@ -121,7 +124,7 @@ public:
|
||||
bytes_written += file->WriteString(message);
|
||||
|
||||
// Option to log each line rather than 4k buffers
|
||||
if (Settings::values.log_flush_lines.GetValue()) {
|
||||
if (Settings::values.log_flush_line.GetValue()) {
|
||||
file->Flush();
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
// 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
|
||||
|
||||
@@ -13,6 +15,7 @@
|
||||
#include <span>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
namespace Common {
|
||||
|
||||
@@ -37,10 +40,10 @@ public:
|
||||
/// @param slot_count Number of slots to push
|
||||
/// @returns The number of slots actually pushed
|
||||
std::size_t Push(const void* new_slots, std::size_t slot_count) {
|
||||
const std::size_t write_index = m_write_index.load();
|
||||
const std::size_t slots_free = capacity + m_read_index.load() - write_index;
|
||||
const std::size_t push_count = std::min(slot_count, slots_free);
|
||||
std::lock_guard lock(rb_mutex);
|
||||
|
||||
const std::size_t slots_free = capacity + read_index - write_index;
|
||||
const std::size_t push_count = std::min(slot_count, slots_free);
|
||||
const std::size_t pos = write_index % capacity;
|
||||
const std::size_t first_copy = std::min(capacity - pos, push_count);
|
||||
const std::size_t second_copy = push_count - first_copy;
|
||||
@@ -50,8 +53,7 @@ public:
|
||||
in += first_copy * slot_size;
|
||||
std::memcpy(m_data.data(), in, second_copy * slot_size);
|
||||
|
||||
m_write_index.store(write_index + push_count);
|
||||
|
||||
write_index = write_index + push_count;
|
||||
return push_count;
|
||||
}
|
||||
|
||||
@@ -64,10 +66,10 @@ public:
|
||||
/// @param max_slots Maximum number of slots to pop
|
||||
/// @returns The number of slots actually popped
|
||||
std::size_t Pop(void* output, std::size_t max_slots = ~std::size_t(0)) {
|
||||
const std::size_t read_index = m_read_index.load();
|
||||
const std::size_t slots_filled = m_write_index.load() - read_index;
|
||||
const std::size_t pop_count = std::min(slots_filled, max_slots);
|
||||
std::lock_guard lock(rb_mutex);
|
||||
|
||||
const std::size_t slots_filled = write_index - read_index;
|
||||
const std::size_t pop_count = std::min(slots_filled, max_slots);
|
||||
const std::size_t pos = read_index % capacity;
|
||||
const std::size_t first_copy = std::min(capacity - pos, pop_count);
|
||||
const std::size_t second_copy = pop_count - first_copy;
|
||||
@@ -77,8 +79,7 @@ public:
|
||||
out += first_copy * slot_size;
|
||||
std::memcpy(out, m_data.data(), second_copy * slot_size);
|
||||
|
||||
m_read_index.store(read_index + pop_count);
|
||||
|
||||
read_index = read_index + pop_count;
|
||||
return pop_count;
|
||||
}
|
||||
|
||||
@@ -90,29 +91,21 @@ public:
|
||||
}
|
||||
|
||||
/// @returns Number of slots used
|
||||
[[nodiscard]] std::size_t Size() const {
|
||||
return m_write_index.load() - m_read_index.load();
|
||||
[[nodiscard]] inline std::size_t Size() const {
|
||||
return write_index - read_index;
|
||||
}
|
||||
|
||||
/// @returns Maximum size of ring buffer
|
||||
[[nodiscard]] constexpr std::size_t Capacity() const {
|
||||
[[nodiscard]] consteval std::size_t Capacity() const {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
private:
|
||||
// It is important to align the below variables for performance reasons:
|
||||
// Having them on the same cache-line would result in false-sharing between them.
|
||||
// TODO: Remove this ifdef whenever clang and GCC support
|
||||
// std::hardware_destructive_interference_size.
|
||||
#ifdef __cpp_lib_hardware_interference_size
|
||||
alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_read_index{0};
|
||||
alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_write_index{0};
|
||||
#else
|
||||
alignas(128) std::atomic_size_t m_read_index{0};
|
||||
alignas(128) std::atomic_size_t m_write_index{0};
|
||||
#endif
|
||||
|
||||
std::array<T, capacity> m_data;
|
||||
// This is wrong, a thread-safe ringbuffer is impossible.
|
||||
std::size_t read_index{0};
|
||||
std::size_t write_index{0};
|
||||
std::mutex rb_mutex;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
|
@@ -158,7 +158,14 @@ bool IsFastmemEnabled() {
|
||||
if (values.cpu_debug_mode) {
|
||||
return static_cast<bool>(values.cpuopt_fastmem);
|
||||
}
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) {
|
||||
return static_cast<bool>(values.cpuopt_unsafe_host_mmu);
|
||||
}
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool is_nce_enabled = false;
|
||||
|
@@ -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
|
||||
@@ -299,6 +300,15 @@ struct Values {
|
||||
Category::CpuDebug};
|
||||
Setting<bool> cpuopt_ignore_memory_aborts{linkage, true, "cpuopt_ignore_memory_aborts",
|
||||
Category::CpuDebug};
|
||||
|
||||
SwitchableSetting<bool> cpuopt_unsafe_host_mmu{linkage,
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)
|
||||
false,
|
||||
#else
|
||||
true,
|
||||
#endif
|
||||
"cpuopt_unsafe_host_mmu",
|
||||
Category::CpuUnsafe};
|
||||
SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{linkage, true, "cpuopt_unsafe_unfuse_fma",
|
||||
Category::CpuUnsafe};
|
||||
SwitchableSetting<bool> cpuopt_unsafe_reduce_fp_error{
|
||||
@@ -542,6 +552,8 @@ struct Values {
|
||||
3,
|
||||
#elif defined (ANDROID)
|
||||
0,
|
||||
#elif defined (__APPLE__)
|
||||
0,
|
||||
#else
|
||||
2,
|
||||
#endif
|
||||
@@ -574,8 +586,11 @@ struct Values {
|
||||
linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug};
|
||||
Setting<bool> enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey",
|
||||
Category::RendererDebug};
|
||||
Setting<bool> disable_buffer_reorder{linkage, false, "disable_buffer_reorder",
|
||||
Category::RendererDebug};
|
||||
SwitchableSetting<bool> disable_buffer_reorder{linkage, false, "disable_buffer_reorder",
|
||||
Category::RendererDebug,
|
||||
Specialization::Default,
|
||||
true,
|
||||
true};
|
||||
|
||||
// System
|
||||
SwitchableSetting<Language, true> language_index{linkage,
|
||||
@@ -611,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};
|
||||
|
||||
@@ -741,7 +760,7 @@ struct Values {
|
||||
|
||||
// Miscellaneous
|
||||
Setting<std::string> log_filter{linkage, "*:Info", "log_filter", Category::Miscellaneous};
|
||||
Setting<bool> log_flush_lines{linkage, true, "flush_lines", Category::Miscellaneous, Specialization::Default, true, true};
|
||||
Setting<bool> log_flush_line{linkage, false, "flush_line", Category::Miscellaneous, Specialization::Default, true, true};
|
||||
Setting<bool> censor_username{linkage, true, "censor_username", Category::Miscellaneous};
|
||||
Setting<bool> use_dev_keys{linkage, false, "use_dev_keys", Category::Miscellaneous};
|
||||
Setting<bool> first_launch{linkage, true, "first_launch", Category::Miscellaneous};
|
||||
|
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
|
||||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
@@ -7,6 +10,7 @@
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
#include "common/string_util.h"
|
||||
|
||||
@@ -21,51 +25,21 @@
|
||||
namespace Common {
|
||||
|
||||
/// Make a string lowercase
|
||||
std::string ToLower(std::string str) {
|
||||
std::string ToLower(const std::string_view sv) {
|
||||
std::string str{sv};
|
||||
std::transform(str.begin(), str.end(), str.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
[](auto const c) { return char(std::tolower(c)); });
|
||||
return str;
|
||||
}
|
||||
|
||||
/// Make a string uppercase
|
||||
std::string ToUpper(std::string str) {
|
||||
std::string ToUpper(const std::string_view sv) {
|
||||
std::string str{sv};
|
||||
std::transform(str.begin(), str.end(), str.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::toupper(c)); });
|
||||
[](auto const c) { return char(std::toupper(c)); });
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string StringFromBuffer(std::span<const u8> data) {
|
||||
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
|
||||
}
|
||||
|
||||
std::string StringFromBuffer(std::span<const char> data) {
|
||||
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
|
||||
}
|
||||
|
||||
// Turns " hej " into "hej". Also handles tabs.
|
||||
std::string StripSpaces(const std::string& str) {
|
||||
const std::size_t s = str.find_first_not_of(" \t\r\n");
|
||||
|
||||
if (str.npos != s)
|
||||
return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
// "\"hello\"" is turned to "hello"
|
||||
// This one assumes that the string has already been space stripped in both
|
||||
// ends, as done by StripSpaces above, for example.
|
||||
std::string StripQuotes(const std::string& s) {
|
||||
if (s.size() && '\"' == s[0] && '\"' == *s.rbegin())
|
||||
return s.substr(1, s.size() - 2);
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string StringFromBool(bool value) {
|
||||
return value ? "True" : "False";
|
||||
}
|
||||
|
||||
bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename,
|
||||
std::string* _pExtension) {
|
||||
if (full_path.empty())
|
||||
|
@@ -1,9 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
|
||||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
#include <string>
|
||||
@@ -13,18 +17,38 @@
|
||||
namespace Common {
|
||||
|
||||
/// Make a string lowercase
|
||||
[[nodiscard]] std::string ToLower(std::string str);
|
||||
[[nodiscard]] std::string ToLower(const std::string_view sv);
|
||||
|
||||
/// Make a string uppercase
|
||||
[[nodiscard]] std::string ToUpper(std::string str);
|
||||
[[nodiscard]] std::string ToUpper(const std::string_view sv);
|
||||
|
||||
[[nodiscard]] std::string StringFromBuffer(std::span<const u8> data);
|
||||
[[nodiscard]] std::string StringFromBuffer(std::span<const char> data);
|
||||
[[nodiscard]] inline std::string StringFromBuffer(std::span<const u8> data) noexcept {
|
||||
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
|
||||
}
|
||||
[[nodiscard]] inline std::string StringFromBuffer(std::span<const char> data) noexcept {
|
||||
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string StripSpaces(const std::string& s);
|
||||
[[nodiscard]] std::string StripQuotes(const std::string& s);
|
||||
/// Turns " hej " into "hej". Also handles tabs.
|
||||
[[nodiscard]] inline std::string StripSpaces(const std::string_view str) noexcept {
|
||||
const std::size_t s = str.find_first_not_of(" \t\r\n");
|
||||
if (str.npos != s)
|
||||
return std::string{str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1)};
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string StringFromBool(bool value);
|
||||
/// "\"hello\"" is turned to "hello"
|
||||
/// This one assumes that the string has already been space stripped in both
|
||||
/// ends, as done by StripSpaces above, for example.
|
||||
[[nodiscard]] inline std::string StripQuotes(const std::string_view s) noexcept {
|
||||
if (s.size() && '\"' == s[0] && '\"' == *s.rbegin())
|
||||
return std::string{s.substr(1, s.size() - 2)};
|
||||
return std::string{s};
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string StringFromBool(bool value) noexcept {
|
||||
return value ? "True" : "False";
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string TabsToSpaces(int tab_size, std::string in);
|
||||
|
||||
@@ -54,7 +78,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
|
||||
* `other` for equality.
|
||||
*/
|
||||
template <typename InIt>
|
||||
[[nodiscard]] bool ComparePartialString(InIt begin, InIt end, const char* other) {
|
||||
[[nodiscard]] inline bool ComparePartialString(InIt begin, InIt end, const char* other) noexcept {
|
||||
for (; begin != end && *other != '\0'; ++begin, ++other) {
|
||||
if (*begin != *other) {
|
||||
return false;
|
||||
@@ -64,18 +88,14 @@ template <typename InIt>
|
||||
return (begin == end) == (*other == '\0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't
|
||||
* NUL-terminated then the string ends at max_len characters.
|
||||
*/
|
||||
/// Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't
|
||||
/// NUL-terminated then the string ends at max_len characters.
|
||||
[[nodiscard]] std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer,
|
||||
std::size_t max_len);
|
||||
|
||||
/**
|
||||
* Creates a UTF-16 std::u16string from a fixed-size NUL-terminated char buffer. If the buffer isn't
|
||||
* null-terminated, then the string ends at the greatest multiple of two less then or equal to
|
||||
* max_len_bytes.
|
||||
*/
|
||||
/// Creates a UTF-16 std::u16string from a fixed-size NUL-terminated char buffer. If the buffer isn't
|
||||
/// null-terminated, then the string ends at the greatest multiple of two less then or equal to
|
||||
/// max_len_bytes.
|
||||
[[nodiscard]] std::u16string UTF16StringFromFixedZeroTerminatedBuffer(std::u16string_view buffer,
|
||||
std::size_t max_len);
|
||||
|
||||
|
@@ -88,6 +88,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 +104,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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -88,7 +88,7 @@ public:
|
||||
void InterpreterFallback(u32 pc, std::size_t num_instructions) override {
|
||||
m_parent.LogBacktrace(m_process);
|
||||
LOG_ERROR(Core_ARM,
|
||||
"Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
|
||||
"Unimplemented instruction @ {:#X} for {} instructions (instr = {:08X})", pc,
|
||||
num_instructions, m_memory.Read32(pc));
|
||||
}
|
||||
|
||||
@@ -175,7 +175,6 @@ public:
|
||||
Kernel::KProcess* m_process{};
|
||||
const bool m_debugger_enabled{};
|
||||
const bool m_check_memory_access{};
|
||||
static constexpr u64 MinimumRunCycles = 10000U;
|
||||
};
|
||||
|
||||
std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* page_table) const {
|
||||
@@ -272,6 +271,10 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa
|
||||
// Unsafe optimizations
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) {
|
||||
config.unsafe_optimizations = true;
|
||||
if (!Settings::values.cpuopt_unsafe_host_mmu) {
|
||||
config.fastmem_pointer = std::nullopt;
|
||||
config.fastmem_exclusive_access = false;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||
}
|
||||
@@ -292,13 +295,17 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa
|
||||
// Curated optimizations
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) {
|
||||
config.unsafe_optimizations = true;
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)
|
||||
config.fastmem_pointer = std::nullopt;
|
||||
config.fastmem_exclusive_access = false;
|
||||
#endif
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
|
||||
}
|
||||
|
||||
// Paranoia mode for debugging optimizations
|
||||
// Paranoid mode for debugging optimizations
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) {
|
||||
config.unsafe_optimizations = false;
|
||||
config.optimizations = Dynarmic::no_optimizations;
|
||||
@@ -336,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());
|
||||
}
|
||||
@@ -382,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;
|
||||
|
@@ -102,7 +102,7 @@ public:
|
||||
void InterpreterFallback(u64 pc, std::size_t num_instructions) override {
|
||||
m_parent.LogBacktrace(m_process);
|
||||
LOG_ERROR(Core_ARM,
|
||||
"Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
|
||||
"Unimplemented instruction @ {:#X} for {} instructions (instr = {:08X})", pc,
|
||||
num_instructions, m_memory.Read32(pc));
|
||||
ReturnException(pc, PrefetchAbort);
|
||||
}
|
||||
@@ -330,6 +330,10 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
|
||||
// Unsafe optimizations
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) {
|
||||
config.unsafe_optimizations = true;
|
||||
if (!Settings::values.cpuopt_unsafe_host_mmu) {
|
||||
config.fastmem_pointer = std::nullopt;
|
||||
config.fastmem_exclusive_access = false;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||
}
|
||||
@@ -350,6 +354,10 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
|
||||
// Curated optimizations
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) {
|
||||
config.unsafe_optimizations = true;
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)
|
||||
config.fastmem_pointer = std::nullopt;
|
||||
config.fastmem_exclusive_access = false;
|
||||
#endif
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||
config.fastmem_address_space_bits = 64;
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
|
||||
@@ -366,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());
|
||||
}
|
||||
@@ -410,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;
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
@@ -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
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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
|
||||
|
32
src/core/file_sys/fssystem/fssystem_passthrough_storage.h
Normal file
32
src/core/file_sys/fssystem/fssystem_passthrough_storage.h
Normal 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
|
@@ -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
|
||||
|
||||
@@ -180,7 +183,7 @@ void ProgramMetadata::Print() const {
|
||||
LOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data());
|
||||
LOG_DEBUG(Service_FS, "Main thread priority: 0x{:02X}", npdm_header.main_thread_priority);
|
||||
LOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu);
|
||||
LOG_DEBUG(Service_FS, "Main thread stack size: 0x{:X} bytes", npdm_header.main_stack_size);
|
||||
LOG_DEBUG(Service_FS, "Main thread stack size: {:#X} bytes", npdm_header.main_stack_size);
|
||||
LOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category);
|
||||
LOG_DEBUG(Service_FS, "Flags: 0x{:02X}", npdm_header.flags);
|
||||
LOG_DEBUG(Service_FS, " > 64-bit instructions: {}",
|
||||
|
@@ -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
|
||||
|
||||
@@ -56,8 +59,8 @@ NAX::NAX(VirtualFile file_)
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string two_dir = Common::ToUpper(match[1]);
|
||||
const std::string nca_id = Common::ToLower(match[2]);
|
||||
const std::string two_dir = Common::ToUpper(std::string{match[1]});
|
||||
const std::string nca_id = Common::ToLower(std::string{match[2]});
|
||||
status = Parse(fmt::format("/registered/{}/{}.nca", two_dir, nca_id));
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
||||
@@ -40,7 +43,7 @@ constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) {
|
||||
// Wait for an address (via Address Arbiter)
|
||||
Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_type, s32 value,
|
||||
s64 timeout_ns) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}",
|
||||
LOG_TRACE(Kernel_SVC, "called, address={:#X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}",
|
||||
address, arb_type, value, timeout_ns);
|
||||
|
||||
// Validate input.
|
||||
@@ -71,7 +74,7 @@ Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_typ
|
||||
// Signals to an address (via Address Arbiter)
|
||||
Result SignalToAddress(Core::System& system, u64 address, SignalType signal_type, s32 value,
|
||||
s32 count) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}",
|
||||
LOG_TRACE(Kernel_SVC, "called, address={:#X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}",
|
||||
address, signal_type, value, count);
|
||||
|
||||
// Validate input.
|
||||
|
@@ -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
|
||||
|
||||
@@ -30,7 +33,7 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm)
|
||||
} // namespace
|
||||
|
||||
Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t size) {
|
||||
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size);
|
||||
LOG_TRACE(Kernel_SVC, "called, address={:#X}, size=0x{:X}", address, size);
|
||||
|
||||
// Get kernel instance.
|
||||
auto& kernel = system.Kernel();
|
||||
@@ -70,8 +73,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
|
||||
MemoryPermission perm) {
|
||||
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, "
|
||||
"permission=0x{:X}",
|
||||
"called, code_memory_handle={:#X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, "
|
||||
"permission={:#X}",
|
||||
code_memory_handle, operation, address, size, perm);
|
||||
|
||||
// Validate the address / size.
|
||||
|
@@ -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
|
||||
|
||||
@@ -45,7 +48,7 @@ Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 cv_key, u
|
||||
|
||||
/// Signal process wide key
|
||||
void SignalProcessWideKey(Core::System& system, u64 cv_key, s32 count) {
|
||||
LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count);
|
||||
LOG_TRACE(Kernel_SVC, "called, cv_key={:#X}, count=0x{:08X}", cv_key, count);
|
||||
|
||||
// Signal the condition variable.
|
||||
return GetCurrentProcess(system.Kernel())
|
||||
|
@@ -15,7 +15,7 @@ namespace Kernel::Svc {
|
||||
/// Gets system/memory information for the current process
|
||||
Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle handle,
|
||||
u64 info_sub_id) {
|
||||
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}",
|
||||
LOG_TRACE(Kernel_SVC, "called info_id={:#X}, info_sub_id=0x{:X}, handle=0x{:08X}",
|
||||
info_id_type, info_sub_id, handle);
|
||||
|
||||
u32 info_id = static_cast<u32>(info_id_type);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user