diff --git a/.ci/android/build.sh b/.ci/android/build.sh index 1fb721b3b2..4b4c9c0834 100755 --- a/.ci/android/build.sh +++ b/.ci/android/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later export NDK_CCACHE=$(which ccache) diff --git a/.ci/android/package.sh b/.ci/android/package.sh index c2eb975a02..50b7bbc332 100755 --- a/.ci/android/package.sh +++ b/.ci/android/package.sh @@ -1,6 +1,6 @@ #!/bin/sh -# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later GITDATE="$(git show -s --date=short --format='%ad' | sed 's/-//g')" diff --git a/.ci/license-header.sh b/.ci/license-header.sh index fecffaa7d3..3d4929d1c1 100755 --- a/.ci/license-header.sh +++ b/.ci/license-header.sh @@ -5,10 +5,13 @@ HEADER_HASH="$(cat "$PWD/.ci/license/header-hash.txt")" echo "Getting branch changes" -BRANCH=`git rev-parse --abbrev-ref HEAD` -COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"` -RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}" -FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r` +# BRANCH=`git rev-parse --abbrev-ref HEAD` +# COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"` +# RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}" +# FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r` + +BASE=`git merge-base master HEAD` +FILES=`git diff --name-only $BASE` #FILES=$(git diff --name-only master) diff --git a/.ci/linux/build.sh b/.ci/linux/build.sh index 8e3a452809..41e0ca308b 100755 --- a/.ci/linux/build.sh +++ b/.ci/linux/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later case "$1" in diff --git a/.ci/linux/package.sh b/.ci/linux/package.sh index 837cfe07ef..838476097a 100755 --- a/.ci/linux/package.sh +++ b/.ci/linux/package.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later # This script assumes you're in the source directory diff --git a/.ci/update-icons.sh b/.ci/update-icons.sh index 4feb2abd24..c95ba0ad82 100755 --- a/.ci/update-icons.sh +++ b/.ci/update-icons.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later which png2icns || [ which yay && yay libicns ] || exit diff --git a/.ci/windows/build.sh b/.ci/windows/build.sh index a0ab69a440..d554e00e1b 100644 --- a/.ci/windows/build.sh +++ b/.ci/windows/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -ex -# SPDX-FileCopyrightText: 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later if [ "$COMPILER" == "clang" ] diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a9e15cfbd..6d8739fb00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,13 @@ if (PLATFORM_SUN) endif() endif() +# Needed for FFmpeg w/ VAAPI and DRM +if (PLATFORM_OPENBSD) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/X11R6/include") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/X11R6/include") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/X11R6/lib") +endif() + # Detect current compilation architecture and create standard definitions # ======================================================================= @@ -88,7 +95,7 @@ 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;\ + 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() @@ -122,7 +129,7 @@ include(CMakeDependentOption) include(CTest) # Disable Warnings as Errors for MSVC -if (CXX_CL) +if (MSVC AND NOT CXX_CLANG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-") endif() @@ -159,8 +166,6 @@ option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF) option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ${EXT_DEFAULT}) -option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan Utility Headers from externals" ${EXT_DEFAULT}) -option(YUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS "Use SPIRV-Tools from externals" ${EXT_DEFAULT}) option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF) @@ -172,8 +177,6 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) CMAKE_DEPENDENT_OPTION(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF "ENABLE_QT" OFF) -option(ENABLE_MICROPROFILE "Enables microprofile capabilities" OFF) - option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}") option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ${EXT_DEFAULT}) @@ -184,9 +187,7 @@ option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" option(FORCE_DOWNLOAD_WIN_BUNDLES "Forcefully download bundled Windows dependencies (useful for CI)" OFF) # TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system -if (YUZU_USE_CPM AND ENABLE_SDL2) - option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}") -endif() +CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "ENABLE_SDL2" OFF) CMAKE_DEPENDENT_OPTION(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF) @@ -206,6 +207,8 @@ CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead set(YUZU_TZDB_PATH "" CACHE STRING "Path to a pre-downloaded timezone database") +option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF) + set(DEFAULT_ENABLE_OPENSSL ON) if (ANDROID OR WIN32 OR APPLE OR PLATFORM_SUN) # - Windows defaults to the Schannel backend. @@ -455,10 +458,35 @@ if (YUZU_USE_CPM) ) endif() endif() + + # VulkanUtilityHeaders - pulls in headers and utility libs + AddJsonPackage(vulkan-utility-headers) + + # small hack + if (NOT VulkanUtilityLibraries_ADDED) + find_package(VulkanHeaders 1.3.274 REQUIRED) + endif() + + # SPIRV Headers + AddJsonPackage(spirv-headers) + + # SPIRV Tools + AddJsonPackage(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() + + # mbedtls + AddJsonPackage(mbedtls) 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) + if (NOT YUZU_DISABLE_LLVM) + find_package(LLVM MODULE COMPONENTS Demangle) + endif() + find_package(nlohmann_json 3.8 REQUIRED) find_package(lz4 REQUIRED) find_package(RenderDoc MODULE) @@ -467,7 +495,32 @@ else() find_package(Opus 1.3 MODULE REQUIRED) find_package(ZLIB 1.2 REQUIRED) find_package(zstd 1.5 REQUIRED MODULE) - find_package(Boost 1.79.0 REQUIRED headers context system fiber) + + # wow + if (PLATFORM_LINUX) + find_package(Boost 1.57.0 REQUIRED headers context system fiber) + else() + find_package(Boost 1.57.0 REQUIRED) + endif() + + # OpenBSD does not package mbedtls3 (only 2) + if (PLATFORM_OPENBSD) + AddJsonPackage(mbedtls) + else() + find_package(MbedTLS 3 REQUIRED) + endif() + + find_package(VulkanUtilityLibraries REQUIRED) + find_package(VulkanHeaders 1.3.274 REQUIRED) + + # FreeBSD does not package spirv-headers + if (PLATFORM_FREEBSD) + AddJsonPackage(spirv-headers) + else() + find_package(SPIRV-Headers 1.3.274 REQUIRED) + endif() + + find_package(SPIRV-Tools MODULE REQUIRED) if (YUZU_TESTS) find_package(Catch2 3.0.1 REQUIRED) @@ -594,10 +647,8 @@ endfunction() add_subdirectory(externals) # pass targets from externals -find_package(VulkanUtilityLibraries) find_package(libusb) find_package(VulkanMemoryAllocator) -find_package(SPIRV-Tools) if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) find_package(xbyak) diff --git a/CMakeModules/CPMUtil.cmake b/CMakeModules/CPMUtil.cmake index db9cce4c66..6a1384e730 100644 --- a/CMakeModules/CPMUtil.cmake +++ b/CMakeModules/CPMUtil.cmake @@ -1,17 +1,6 @@ -# 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 - -# Future crueter: Wow this was a lie and a half, at this point I might as well make my own CPN -# haha just kidding... unless? - -# TODO(crueter): Remember to get more than 6 hours of sleep whenever making giant cmake changes if (MSVC OR ANDROID) set(BUNDLED_DEFAULT ON) else() @@ -27,6 +16,7 @@ option(CPMUTIL_FORCE_SYSTEM cmake_minimum_required(VERSION 3.22) include(CPM) +# cpmfile parsing set(CPMUTIL_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json") if (EXISTS ${CPMUTIL_JSON_FILE}) @@ -35,12 +25,11 @@ else() message(WARNING "[CPMUtil] cpmfile ${CPMUTIL_JSON_FILE} does not exist, AddJsonPackage will be a no-op") endif() -# utility +# Utility stuff 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") @@ -53,7 +42,6 @@ function(array_to_list array length out) 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}) @@ -73,14 +61,13 @@ function(get_json_element object out member default) set("${out}" "${outvar}" PARENT_SCOPE) endfunction() -# Kinda cancerous but whatever +# The preferred usage 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 ) @@ -90,6 +77,7 @@ function(AddJsonPackage) "${ARGN}") list(LENGTH ARGN argnLength) + # single name argument if(argnLength EQUAL 1) set(JSON_NAME "${ARGV0}") @@ -199,7 +187,6 @@ function(AddJsonPackage) endif() set(options ${options} ${JSON_OPTIONS}) - # end options # system/bundled @@ -241,7 +228,7 @@ endfunction() function(AddPackage) cpm_set_policies() - # TODO(crueter): docs, git clone + # TODO(crueter): git clone? #[[ URL configurations, descending order of precedence: @@ -611,11 +598,6 @@ function(AddCIPackage) if (DEFINED ARTIFACT_DIR) include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake) - - 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) else() find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED) diff --git a/CMakeModules/Findmbedtls.cmake b/CMakeModules/Findmbedtls.cmake deleted file mode 100644 index f5ebf1abdc..0000000000 --- a/CMakeModules/Findmbedtls.cmake +++ /dev/null @@ -1,17 +0,0 @@ -# SPDX-FileCopyrightText: 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -include(FindPackageHandleStandardArgs) - -find_package(PkgConfig QUIET) -pkg_search_module(mbedtls QUIET IMPORTED_TARGET mbedtls) -find_package_handle_standard_args(mbedtls - REQUIRED_VARS mbedtls_LINK_LIBRARIES - VERSION_VAR mbedtls_VERSION -) - -pkg_search_module(mbedcrypto QUIET IMPORTED_TARGET mbedcrypto) -find_package_handle_standard_args(mbedcrypto - REQUIRED_VARS mbedcrypto_LINK_LIBRARIES - VERSION_VAR mbedcrypto_VERSION -) diff --git a/CMakeModules/Findsirit.cmake b/CMakeModules/Findsirit.cmake index 1611efaad8..83b81b09c5 100644 --- a/CMakeModules/Findsirit.cmake +++ b/CMakeModules/Findsirit.cmake @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later include(FindPackageHandleStandardArgs) diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake index bcb5dc466a..2d7081b7db 100644 --- a/CMakeModules/GenerateSCMRev.cmake +++ b/CMakeModules/GenerateSCMRev.cmake @@ -1,38 +1,35 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2019 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later -# Gets a UTC timestamp and sets the provided variable to it +# generate git/build information +include(GetSCMRev) + function(get_timestamp _var) string(TIMESTAMP timestamp UTC) set(${_var} "${timestamp}" PARENT_SCOPE) endfunction() -# generate git/build information -include(GetGitRevisionDescription) -if(NOT GIT_REF_SPEC) - get_git_head_revision(GIT_REF_SPEC GIT_REV) -endif() -if(NOT GIT_DESC) - git_describe(GIT_DESC --always --long --dirty) -endif() -if (NOT GIT_BRANCH) - git_branch_name(GIT_BRANCH) -endif() get_timestamp(BUILD_DATE) -git_get_exact_tag(GIT_TAG --tags) -if (GIT_TAG MATCHES "NOTFOUND") - set(BUILD_VERSION "${GIT_DESC}") - set(IS_DEV_BUILD true) -else() - set(BUILD_VERSION ${GIT_TAG}) +if (DEFINED GIT_RELEASE) + set(BUILD_VERSION "${GIT_TAG}") + set(GIT_REFSPEC "${GIT_RELEASE}") set(IS_DEV_BUILD false) +else() + string(SUBSTRING ${GIT_COMMIT} 0 10 BUILD_VERSION) + set(BUILD_VERSION "${BUILD_VERSION}-${GIT_REFSPEC}") + set(IS_DEV_BUILD true) endif() +set(GIT_DESC ${BUILD_VERSION}) + # Generate cpp with Git revision from template # Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well set(REPO_NAME "Eden") -set(BUILD_ID ${GIT_BRANCH}) +set(BUILD_ID ${GIT_REFSPEC}) set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ") set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") diff --git a/CMakeModules/GetSCMRev.cmake b/CMakeModules/GetSCMRev.cmake new file mode 100644 index 0000000000..ee5ce6a91c --- /dev/null +++ b/CMakeModules/GetSCMRev.cmake @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: 2025 crueter +# SPDX-License-Identifier: GPL-3.0-or-later + +include(GetGitRevisionDescription) + +function(trim var) + string(REGEX REPLACE "\n" "" new "${${var}}") + set(${var} ${new} PARENT_SCOPE) +endfunction() + +set(TAG_FILE ${CMAKE_SOURCE_DIR}/GIT-TAG) +set(REF_FILE ${CMAKE_SOURCE_DIR}/GIT-REFSPEC) +set(COMMIT_FILE ${CMAKE_SOURCE_DIR}/GIT-COMMIT) +set(RELEASE_FILE ${CMAKE_SOURCE_DIR}/GIT-RELEASE) + +if (EXISTS ${REF_FILE} AND EXISTS ${COMMIT_FILE}) + file(READ ${REF_FILE} GIT_REFSPEC) + file(READ ${COMMIT_FILE} GIT_COMMIT) +else() + get_git_head_revision(GIT_REFSPEC GIT_COMMIT) + git_branch_name(GIT_REFSPEC) + if (GIT_REFSPEC MATCHES "NOTFOUND") + set(GIT_REFSPEC 1.0.0) + set(GIT_COMMIT stable) + endif() +endif() + +if (EXISTS ${TAG_FILE}) + file(READ ${TAG_FILE} GIT_TAG) +else() + git_describe(GIT_TAG --tags --abbrev=0) + if (GIT_TAG MATCHES "NOTFOUND") + set(GIT_TAG "${GIT_REFSPEC}") + endif() +endif() + +if (EXISTS ${RELEASE_FILE}) + file(READ ${RELEASE_FILE} GIT_RELEASE) + trim(GIT_RELEASE) + message(STATUS "Git release: ${GIT_RELEASE}") +endif() + +trim(GIT_REFSPEC) +trim(GIT_COMMIT) +trim(GIT_TAG) + +message(STATUS "Git commit: ${GIT_COMMIT}") +message(STATUS "Git tag: ${GIT_TAG}") +message(STATUS "Git refspec: ${GIT_REFSPEC}") diff --git a/CMakeModules/WindowsCopyFiles.cmake b/CMakeModules/WindowsCopyFiles.cmake index 8d37bd5c2c..a4afeb77bf 100644 --- a/CMakeModules/WindowsCopyFiles.cmake +++ b/CMakeModules/WindowsCopyFiles.cmake @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2018 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later diff --git a/README.md b/README.md index e1f0b50b37..2378c206cd 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,11 @@ You can also follow us on [X (Twitter)](https://x.com/edenemuofficial) for updat If you would like to contribute, we are open to new developers and pull requests. Please ensure that your work is of a high standard and properly documented. You can also contact any of the developers on Discord or Revolt to learn more about the current state of the emulator. +See the [sign-up instructions](docs/SIGNUP.md) for information on registration. + ## Building -* **Windows**: [Windows Building Guide](./docs/build/Windows.md) -* **Linux**: [Linux Building Guide](./docs/build/Linux.md) -* **Android**: [Android Building Guide](./docs/build/Android.md) -* **Solaris**: [Solaris Building Guide](./docs/build/Solaris.md) -* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md) -* **macOS**: [macOS Building Guide](./docs/build/macOS.md) -* **OpenBSD**: [OpenBSD Building Guide](./docs/build/OpenBSD.md) +See the [General Build Guide](docs/Build.md) ## Download diff --git a/cpmfile.json b/cpmfile.json index e071e0a8b8..887e958533 100644 --- a/cpmfile.json +++ b/cpmfile.json @@ -91,6 +91,42 @@ "OPUS_PRESUME_NEON ON" ] }, + "vulkan-utility-headers": { + "package": "VulkanUtilityLibraries", + "repo": "scripts/VulkanUtilityHeaders", + "tag": "1.4.326", + "artifact": "VulkanUtilityHeaders.tar.zst", + "git_host": "git.crueter.xyz", + "hash": "5924629755cb1605c4aa4eee20ef7957a9dd8d61e4df548be656d98054f2730c4109693c1bd35811f401f4705d2ccff9fc849be32b0d8480bc3f73541a5e0964" + }, + "spirv-tools": { + "package": "SPIRV-Tools", + "repo": "KhronosGroup/SPIRV-Tools", + "sha": "40eb301f32", + "hash": "58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa", + "find_args": "MODULE", + "options": [ + "SPIRV_SKIP_EXECUTABLES ON" + ] + }, + "spirv-headers": { + "package": "SPIRV-Headers", + "repo": "KhronosGroup/SPIRV-Headers", + "sha": "4e209d3d7e", + "hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4", + "options": [ + "SPIRV_WERROR OFF" + ] + }, + "mbedtls": { + "package": "MbedTLS", + "repo": "Mbed-TLS/mbedtls", + "tag": "mbedtls-%VERSION%", + "hash": "6671fb8fcaa832e5b115dfdce8f78baa6a4aea71f5c89a640583634cdee27aefe3bf4be075744da91f7c3ae5ea4e0c765c8fc3937b5cfd9ea73d87ef496524da", + "version": "3", + "git_version": "3.6.4", + "artifact": "%TAG%.tar.bz2" + }, "cubeb": { "repo": "mozilla/cubeb", "sha": "fa02160712", diff --git a/docs/Build.md b/docs/Build.md new file mode 100644 index 0000000000..52a671ab1e --- /dev/null +++ b/docs/Build.md @@ -0,0 +1,160 @@ +# Building Eden + +> [!WARNING] +> This guide is intended for developers ONLY. If you are not a developer or packager, you are unlikely to receive support. + +This is a full-fledged guide to build Eden on all supported platforms. + +## Dependencies +First, you must [install some dependencies](Deps.md). + +## Clone +Next, you will want to clone Eden via the terminal: + +```sh +git clone https://git.eden-emu.dev/eden-emu/eden.git +cd eden +``` + +Or use Qt Creator (Create Project -> Import Project -> Git Clone). + +## Android + +Android has a completely different build process than other platforms. See its [dedicated page](build/Android.md). + +## Initial Configuration + +If the configure phase fails, see the `Troubleshooting` section below. Usually, as long as you followed the dependencies guide, the defaults *should* successfully configure and build. + +### Qt Creator + +This is the recommended GUI method for Linux, macOS, and Windows. + + +Click to Open + +> [!WARNING] +> On MSYS2, to use Qt Creator you are recommended to *also* install Qt from the online installer, ensuring to select the "MinGW" version. + +Open the CMakeLists.txt file in your cloned directory via File -> Open File or Project (Ctrl+O), if you didn't clone Eden via the project import tool. + +Select your desired "kit" (usually, the default is okay). RelWithDebInfo or Release is recommended: + + + +Hit "Configure Project", then wait for CMake to finish configuring (may take a while on Windows). + + + +### Command Line + +This is recommended for *BSD, Solaris, Linux, and MSYS2. MSVC is possible, but not recommended. + + +Click to Open + +Note that CMake must be in your PATH, and you must be in the cloned Eden directory. On Windows, you must also set up a Visual C++ development environment. This can be done by running `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat` in the same terminal. + +Recommended generators: + +- MSYS2: `MSYS Makefiles` +- MSVC: Install **[ninja](https://ninja-build.org/)** and use `Ninja`, OR use `Visual Studio 17 2022` +- macOS: `Ninja` (preferred) or `Xcode` +- Others: `Ninja` (preferred) or `UNIX Makefiles` + +BUILD_TYPE should usually be `Release` or `RelWithDebInfo` (debug symbols--compiled executable will be large). If you are using a debugger and annoyed with stuff getting optimized out, try `Debug`. + +Also see the [Options](Options.md) page for additional CMake options. + +```sh +cmake -S . -B build -G "GENERATOR" -DCMAKE_BUILD_TYPE= -DYUZU_TESTS=OFF +``` + +If you are on Windows and prefer to use Clang: + +```sh +cmake -S . -B build -G "GENERATOR" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl +``` + + + +### [CLion](https://www.jetbrains.com/clion/) + + +Click to Open + +* Clone the Repository: + + + + + +--- + +### Building & Setup + +* Once Cloned, You will be taken to a prompt like the image below: + + + +* Set the settings to the image below: +* Change `Build type: Release` +* Change `Name: Release` +* Change `Toolchain Visual Studio` +* Change `Generator: Let CMake decide` +* Change `Build directory: build` + + + +* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. +* Once this process has been completed (No loading bar bottom right), you can now build eden +* In the top right, click on the drop-down menu, select all configurations, then select eden + + + +* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. + + + + +## Troubleshooting + +If your initial configure failed: +- *Carefully* re-read the [dependencies guide](Deps.md) +- Clear the CPM cache (`.cache/cpm`) and CMake cache (`/CMakeCache.txt`) +- Evaluate the error and find any related settings +- See the [CPM docs](CPM.md) to see if you may need to forcefully bundle any packages + +Otherwise, feel free to ask for help in Revolt or Discord. + +## Caveats + +Many platforms have quirks, bugs, and other fun stuff that may cause issues when building OR running. See the [Caveats page](Caveats.md) before continuing. + +## Building & Running + +### Qt Creator + +Simply hit Ctrl+B, or the "hammer" icon in the bottom left. To run, hit the "play" icon, or Ctrl+R. + +### Command Line + +If you are not on Windows and are using the `UNIX Makefiles` generator, you must also add `-j$(nproc)` to this command. + +``` +cmake --build build +``` + +Your compiled executable will be in: +- `build/bin/eden.exe` for Windows, +- `build/bin/eden.app/Contents/MacOS/eden` for macOS, +- and `build/bin/eden` for others. + +## Scripts + +Some platforms have convenience scripts provided for building. + +- **[Linux](scripts/Linux.md)** +- **[Windows](scripts/Windows.md)** + +macOS scripts will come soon. \ No newline at end of file diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS new file mode 100644 index 0000000000..dcb97a5e83 --- /dev/null +++ b/docs/CODEOWNERS @@ -0,0 +1,27 @@ +# ui stuff +/src/android @AleksandrPopovich @nyxynx @Producdevity +/src/yuzu @crueter +/src/eden @crueter +/src/frontend_common @crueter +/src/qt_common @crueter + +# docs, meta +/docs @Lizzie @crueter +/.ci @crueter + +# cmake +*.cmake @crueter +*CMakeLists.txt @crueter +*.in @crueter + +# individual stuff +src/web_service @AleksandrPopovich +src/dynarmic @Lizzie +src/core @Lizzie @Maufeat @PavelBARABANOV @MrPurple666 @JPikachu +src/core/hle @Maufeat @PavelBARABANOV @SDK-Chan +src/core/arm @Lizzie @MrPurple666 +src/*_room @AleksandrPopovich +src/video_core @CamilleLaVey @MaranBr @Wildcard @weakboson + +# Global owners/triage +* @CamilleLaVey @Maufeat @crueter @MrPurple666 @MaranBr @Lizzie \ No newline at end of file diff --git a/docs/CPM.md b/docs/CPM.md index 2afcdaf164..03d8a039f9 100644 --- a/docs/CPM.md +++ b/docs/CPM.md @@ -177,7 +177,7 @@ If `ci` is `true`: ### Examples -In order: OpenSSL CI, Boost (tag + artifact), discord-rpc (sha + options + patches), Opus (options + find_args) +In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discord-rpc (sha + options + patches) ```json { @@ -245,6 +245,6 @@ include(CPMUtil) Currently, `cpm-fetch.sh` defines the following directories for cpmfiles (max depth of 2, so subdirs are caught as well): -`externals src/yuzu src/dynarmic .` +`externals src/qt_common src/dynarmic .` Whenever you add a new cpmfile, update the script accordingly \ No newline at end of file diff --git a/docs/Caveats.md b/docs/Caveats.md new file mode 100644 index 0000000000..7bc2428bab --- /dev/null +++ b/docs/Caveats.md @@ -0,0 +1,52 @@ +# Caveats + +## Arch Linux + +- httplib AUR package is broken. Set `httplib_FORCE_BUNDLED=ON` if you have it installed. +- Eden is also available as an [AUR package](https://aur.archlinux.org/packages/eden-git). If you are unable to build, either use that or compare your process to the PKGBUILD. + +## Gentoo Linux + +Do not use the system sirit or xbyak packages. + +## macOS + +macOS is largely untested. Expect crashes, significant Vulkan issues, and other fun stuff. + +## Solaris + +Qt Widgets appears to be broken. For now, add `-DENABLE_QT=OFF` to your configure command. In the meantime, a Qt Quick frontend is in the works--check back later! + +This is needed for some dependencies that call cc directly (tz): + +```sh +echo '#!/bin/sh' >cc +echo 'gcc $@' >>cc +chmod +x cc +export PATH="$PATH:$PWD" +``` + +Default MESA is a bit outdated, the following environment variables should be set for a smoother experience: +```sh +export MESA_GL_VERSION_OVERRIDE=4.6 +export MESA_GLSL_VERSION_OVERRIDE=460 +export MESA_EXTENSION_MAX_YEAR=2025 +export MESA_DEBUG=1 +export MESA_VK_VERSION_OVERRIDE=1.3 +# Only if nvidia/intel drm drivers cause crashes, will severely hinder performance +export LIBGL_ALWAYS_SOFTWARE=1 +``` + +- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). +- If using OpenIndiana, due to a bug in SDL2's CMake configuration, audio driver defaults to SunOS ``, which does not exist on OpenIndiana. Using external or bundled SDL2 may solve this. +- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_BUNDLED_OPENSSL=ON` to use a bundled static OpenSSL, or build a system dependency from source. + +## OpenBSD + +After configuration, you may need to modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`. + +## FreeBSD + +Eden is not currently available as a port on FreeBSD, though it is in the works. For now, the recommended method of usage is to compile it yourself. + +The available OpenSSL port (3.0.17) is out-of-date, and using a bundled static library instead is recommended; to do so, add `-DYUZU_USE_BUNDLED_OPENSSL=ON` to your CMake configure command. \ No newline at end of file diff --git a/docs/Deps.md b/docs/Deps.md new file mode 100644 index 0000000000..cfc6f0365b --- /dev/null +++ b/docs/Deps.md @@ -0,0 +1,214 @@ +# Dependencies + +To build Eden, you MUST have a C++ compiler. +* On Linux, this is usually [GCC](https://gcc.gnu.org/) 11+ or [Clang](https://clang.llvm.org/) v14+ + - GCC 12 also requires Clang 14+ +* On Windows, this is either: + - **[MSVC](https://visualstudio.microsoft.com/downloads/)**, + * *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* + - clang-cl - can be downloaded from the MSVC installer, + - or **[MSYS2](https://www.msys2.org)** +* On macOS, this is Apple Clang + - This can be installed with `xcode-select --install` + +The following additional tools are also required: + +* **[CMake](https://www.cmake.org/)** 3.22+ - already included with the Android SDK +* **[Git](https://git-scm.com/)** for version control + - **[Windows installer](https://gitforwindows.org)** +* On Windows, you must install the **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** as well + - *A convenience script to install the latest SDK is provided in `.ci/windows/install-vulkan-sdk.ps1`* + +If you are on desktop and plan to use the Qt frontend, you *must* install Qt 6, and optionally Qt Creator (the recommended IDE for building) +* On Linux, *BSD and macOS, this can be done by the package manager + - If you wish to use Qt Creator, append `qtcreator` or `qt-creator` to the commands seen below. +* MSVC/clang-cl users on Windows must install through the [official installer](https://www.qt.io/download-qt-installer-oss) +* Linux and macOS users may choose to use the installer as well. +* MSYS2 can also install Qt 6 via the package manager + +If you are on Windows and NOT building with MSYS2, you may go [back home](Build.md) and continue. + +## Externals +The following are handled by Eden's externals: + +* [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) +* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON` OR `-DYUZU_USE_BUNDLED_SDL2=ON` to reduce compile time) + +All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available (UNIX-like only): + +* [Boost](https://www.boost.org/users/download/) 1.57.0+ +* [Catch2](https://github.com/catchorg/Catch2) 3.0.1 if `YUZU_TESTS` or `DYNARMIC_TESTS` are on +* [fmt](https://fmt.dev/) 8.0.1+ +* [lz4](http://www.lz4.org) +* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+ +* [OpenSSL](https://www.openssl.org/source/) 1.1.1+ +* [ZLIB](https://www.zlib.net/) 1.2+ +* [zstd](https://facebook.github.io/zstd/) 1.5+ +* [enet](http://enet.bespin.org/) 1.3+ +* [Opus](https://opus-codec.org/) 1.3+ +* [MbedTLS](https://github.com/Mbed-TLS/mbedtls) 3+ + +Vulkan 1.3.274+ is also needed: +* [VulkanUtilityLibraries](https://github.com/KhronosGroup/Vulkan-Utility-Libraries) +* [VulkanHeaders](https://github.com/KhronosGroup/Vulkan-Headers) +* [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools) +* [SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) + +Certain other dependencies will be fetched by CPM regardless. System packages *can* be used for these libraries, but many are either not packaged by most distributions OR have issues when used by the system: + +* [SimpleIni](https://github.com/brofield/simpleini) +* [DiscordRPC](https://github.com/eden-emulator/discord-rpc) +* [cubeb](https://github.com/mozilla/cubeb) +* [libusb](https://github.com/libusb/libusb) +* [VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) +* [sirit](https://github.com/eden-emulator/sirit) +* [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_QT_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on +* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on +* [unordered-dense](https://github.com/martinus/unordered_dense) +* [mcl](https://github.com/azahar-emu/mcl) - subject to removal + +On amd64: +* [xbyak](https://github.com/herumi/xbyak) - 7.22 or earlier is recommended +* [zycore](https://github.com/zyantific/zycore-c) +* [zydis](https://github.com/zyantific/zydis) 4+ +* Note: zydis and zycore-c MUST match. Using one as a system dependency and the other as a bundled dependency WILL break things + +On aarch64 OR if `DYNARMIC_TESTS` is on: +* [oaknut](https://github.com/merryhime/oaknut) 2.0.1+ + +On riscv64: +* [biscuit](https://github.com/lioncash/biscuit) 0.9.1+ + +## Commands + +These are commands to install all necessary dependencies on various Linux and BSD distributions, as well as macOS. Always review what you're running before you hit Enter! + +Click on the arrows to expand. + + +Arch Linux + +```sh +sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip zydis zycore vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers +``` + +* Building with QT Web Engine requires `qt6-webengine` as well. +* Proper Wayland support requires `qt6-wayland` +* GCC 11 or later is required. + + + +Ubuntu, Debian, Mint Linux + +```sh +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 qt6-tools-dev libzydis-dev zydis-tools libzycore-dev +``` + +* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. +* To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. + + + +Fedora Linux + +```sh +sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel +``` + +* Force system libraries via CMake arguments: + * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` + * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` +* [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` +* Fedora 32 or later is required. +* Fedora 36+ users with GCC 12 need Clang and should configure CMake with: + + + +macOS + +Install dependencies from **[Homebrew](https://brew.sh/)** + +```sh +brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools +``` + +If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`. + +To run with MoltenVK, install additional dependencies: +```sh +brew install molten-vk vulkan-loader +``` + + + + +FreeBSD + +``` +devel/cmake +devel/sdl20 +devel/boost-libs +devel/catch2 +devel/libfmt +devel/nlohmann-json +devel/ninja +devel/nasm +devel/autoconf +devel/pkgconf +devel/qt6-base + +net/enet + +multimedia/ffnvcodec-headers +multimedia/ffmpeg + +audio/opus + +archivers/liblz4 + +lang/gcc12 + +graphics/glslang +graphics/vulkan-utility-libraries +``` + +If using FreeBSD 12 or prior, use `devel/pkg-config` instead. + + + +OpenBSD + +```sh +pkg_add -u +pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 libusb1.1.0.27 +``` + + + +Solaris / OpenIndiana + +Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability. + +Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`. + +- **gcc**: `sudo pkg install developer/gcc-14`. +- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. + +Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. + + + +MSYS2 + +* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) +* Download and install all dependencies using: + * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` +* Add MinGW binaries to the PATH: + * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` +* Add VulkanSDK to the PATH: + * `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` + + +## All Done + +You may now return to the **[root build guide](Build.md)**. \ No newline at end of file diff --git a/docs/Development.md b/docs/Development.md index e4816cd1ec..d170818d10 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -1,23 +1,3 @@ -# Development - -* **Windows**: [Windows Building Guide](./build/Windows.md) -* **Linux**: [Linux Building Guide](./build/Linux.md) -* **Android**: [Android Building Guide](./build/Android.md) -* **Solaris**: [Solaris Building Guide](./build/Solaris.md) -* **FreeBSD**: [FreeBSD Building Guide](./build/FreeBSD.md) -* **macOS**: [macOS Building Guide](./build/macOS.md) -* **OpenBSD**: [OpenBSD Building Guide](./build/OpenBSD.md) - -# CPM - -CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden. Documentation on adding dependencies/using CPMUtil is in the works. - -Notes: -- `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 -- `CPMUTIL_DEFAULT_SYSTEM` can be set to `OFF` to force the usage of bundled dependencies. This can marginally decrease the final package size. -- When adding new prebuilt dependencies a la OpenSSL, SDL2, or FFmpeg, there *must* be a CMake option made available to forcefully download this bundle. See the OpenSSL implementation in the root CMakeLists for an example. - * This is necessary to allow for creation of fully-qualified source packs that allow for offline builds after download (some package managers and distros enforce this) - # Guidelines ## License Headers @@ -37,6 +17,8 @@ FIX=true .ci/license-header.sh git commit --amend -a --no-edit ``` +If the work is licensed/vendored from other people or projects, you may omit the license headers. Additionally, if you wish to retain authorship over a piece of code, you may attribute it to yourself; however, the code may be changed at any given point and brought under the attribution of Eden. + ## Pull Requests Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed: ``` @@ -49,7 +31,7 @@ Pull requests are only to be merged by core developers when properly tested and - The level of namespacing is generally left to the committer's choice. - However, we never recommend going more than two levels *except* in `hle`, in which case you may go as many as four levels depending on the specificity of your changes. -- Ocassionally, up to two namespaces may be provided for more clarity. +- Ocassionally, up to two additional namespaces may be provided for more clarity. * Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`. - Maintainers are permitted to change namespaces at will. - Commits within PRs are not required to be namespaced, but it is highly recommended. diff --git a/docs/Options.md b/docs/Options.md new file mode 100644 index 0000000000..d19aab63f6 --- /dev/null +++ b/docs/Options.md @@ -0,0 +1,69 @@ +# CMake Options + +To change these options, add `-DOPTION_NAME=NEWVALUE` to the command line. + +- On Qt Creator, go to Project -> Current Configuration + +Notes: +- Defaults are marked per-platform. +- "Non-UNIX" just means Windows/MSVC and Android (yes, macOS is UNIX +- Android generally doesn't need to change anything; if you do, go to `src/android/app/build.gradle.kts` +- To set a boolean variable to on, use `ON` for the value; to turn it off, use `OFF` +- If a variable is mentioned as being e.g. "ON" for a specific platform(s), that means it is defaulted to OFF on others +- TYPE is always boolean unless otherwise specified +- Format: + * `OPTION_NAME` (TYPE DEFAULT) DESCRIPTION + +## Options + +- `YUZU_USE_CPM` (ON for non-UNIX) Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched. See the [CPM](CPM.md) and [Deps](Deps.md) docs for more info. +- `ENABLE_WEB_SERVICE` (ON) Enable multiplayer service +- `ENABLE_WIFI_SCAN` (OFF) Enable WiFi scanning (requires iw on Linux) - experimental +- `YUZU_USE_BUNDLED_FFMPEG` (ON for non-UNIX) Download (Windows, Android) or build (UNIX) bundled FFmpeg +- `ENABLE_CUBEB` (ON) Enables the cubeb audio backend +- `YUZU_TESTS` (ON) Compile tests - requires Catch2 +- `YUZU_USE_PRECOMPILED_HEADERS` (ON for non-UNIX) Use precompiled headers +- `YUZU_DOWNLOAD_ANDROID_VVL` (ON) Download validation layer binary for Android +- `YUZU_ENABLE_LTO` (OFF) Enable link-time optimization + * Not recommended on Windows + * UNIX may be better off appending `-flto=thin` to compiler args +- `YUZU_DOWNLOAD_TIME_ZONE_DATA` (ON) Always download time zone binaries + * Currently, build fails without this +- `YUZU_USE_FASTER_LD` (ON) Check if a faster linker is available + * Only available on UNIX +- `USE_SYSTEM_MOLTENVK` (OFF, macOS only) Use the system MoltenVK lib (instead of the bundled one) +- `YUZU_TZDB_PATH` (string) Path to a pre-downloaded timezone database (useful for nixOS) +- `ENABLE_OPENSSL` (ON for Linux and *BSD) Enable OpenSSL backend for the ssl service + * Always enabled if the web service is enabled +- `YUZU_USE_BUNDLED_OPENSSL` (ON for MSVC) Download bundled OpenSSL build + * Always on for Android + * Unavailable on OpenBSD + +The following options are desktop only: +- `ENABLE_SDL2` (ON) Enable the SDL2 desktop, audio, and input frontend (HIGHLY RECOMMENDED!) + * Unavailable on Android +- `YUZU_USE_EXTERNAL_SDL2` (ON for non-UNIX) Compiles SDL2 from source +- `YUZU_USE_BUNDLED_SDL2` (ON for MSVC) Download a prebuilt SDL2 + * Unavailable on OpenBSD + * Only enabled if YUZU_USE_CPM and ENABLE_SDL2 are both ON +- `ENABLE_LIBUSB` (ON) Enable the use of the libusb input frontend (HIGHLY RECOMMENDED) +- `ENABLE_OPENGL` (ON) Enable the OpenGL graphics frontend + * Unavailable on Windows/ARM64 and Android +- `ENABLE_QT` (ON) Enable the Qt frontend (recommended) +- `ENABLE_QT_TRANSLATION` (OFF) Enable translations for the Qt frontend +- `ENABLE_QT_UPDATE_CHECKER` (OFF) Enable update checker for the Qt frontend +- `YUZU_USE_BUNDLED_QT` (ON for MSVC) Download bundled Qt binaries + * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH`, e.g: + * `-DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` +- `YUZU_QT_MIRROR` (string) What mirror to use for downloading the bundled Qt libraries +- `YUZU_USE_QT_MULTIMEDIA` (OFF) Use QtMultimedia for camera support +- `YUZU_USE_QT_WEB_ENGINE` (OFF) Use QtWebEngine for web applet implementation (requires the huge QtWebEngine dependency; not recommended) +- `USE_DISCORD_PRESENCE` (OFF) Enables Discord Rich Presence (Qt frontend only) +- `YUZU_ROOM` (ON) Enable dedicated room functionality +- `YUZU_ROOM_STANDALONE` (ON) Enable standalone room executable (eden-room) + * Requires `YUZU_ROOM` +- `YUZU_CMD` (ON) Compile the SDL2 frontend (eden-cli) - requires SDL2 +- `YUZU_CRASH_DUMPS` Compile crash dump (Minidump) support" + * Currently only available on Windows and Linux + +See `src/dynarmic/CMakeLists.txt` for additional options--usually, these don't need changed \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..71e79e15ea --- /dev/null +++ b/docs/README.md @@ -0,0 +1,10 @@ +# Eden Build Documentation + +This contains documentation created by developers. This contains build instructions, guidelines, instructions/layouts for [cool stuff we made](CPM.md), and more. + +- **[General Build Instructions](Build.md)** +- **[Development Guidelines](Development.md)** +- **[Dependencies](Deps.md)** +- **[CPM - CMake Package Manager](CPM.md)** +- **[Platform-Specific Caveats](Caveats.md)** +- **[User Directory Handling](User.md)** \ No newline at end of file diff --git a/docs/SIGNUP.md b/docs/SIGNUP.md new file mode 100644 index 0000000000..f8cc315830 --- /dev/null +++ b/docs/SIGNUP.md @@ -0,0 +1,56 @@ +# Signup + +To prevent spam and reduce bandwidth usage, registration is closed, and will likely remain this way. + +## Valid Reasons + +First of all, you MUST have a valid reason to sign up for our Git. Valid reasons include (but are not limited to): + +- I want to add feature XYZ... +- I want to improve the macOS version... +- I want to improve the Vulkan backend... +- I want to fix bug XYZ... +- I have experience in XYZ... +- I can provide insight on XYZ... + +## Invalid Reasons + +The following are not valid reasons to sign up: + +- I want to contribute to Eden. + * Be at least somewhat specific! +- I want to support Eden. + * If you wish to support us through development, be more specific; otherwise, to support us, check out our [donations page](https://eden-emu.dev/donations). +- I want to report issues. + * Most of our issue tracking is handled on [GitHub](https://github.com/eden-emulator/Issue-Reports) for the time being. This is subject to change. +- I want to play/use Eden. + * To download and use Eden, see our [Releases page](https://github.com/eden-emulator/Releases/releases)! +- I want to see the source code. + * To see Eden's source code, go [here](https://git.eden-emu.dev/eden-emu/eden). +## Other Information + +Requests that appear suspicious, automated, OR blank will generally be automatically filtered. In cases of suspicion, or any of the invalid reasons listed above, you may receive an email back asking for clarification. + +You MUST use the following format: + +``` +Subject: [Eden Git] Registration Request +Username: +Email: +I wish to sign up because... +``` + +Email notifications are disabled for the time being, so you don't have to use a real email. If you wish to remain anonymous, either send a separate email asking for access to a shared anonymous account, *or* create a fake username and email. + +## Instructions + +If you have read everything above and affirm that you will not abuse your access, click the summary below to get the email to send your request to. + + +I affirm that I have read ALL of the information above, and will not abuse my access to Eden, nor will I send unnecessary spam requests or the following email. + +Email [crueter@crueter.xyz](mailto:crueter@crueter.xyz) with the format above. + +Once your request is processed, you should receive a confirmation email from crueter with your password alongside a link to a repository containing instructions on SSH, etc. Note that you are required to change your password. If your request is rejected, you will receive a notice as such, asking for clarification if needed. If you do not receive a response in 48 hours, you may send another email. + + \ No newline at end of file diff --git a/docs/build/Android.md b/docs/build/Android.md index 0538d351ea..c8ff3a3b1e 100644 --- a/docs/build/Android.md +++ b/docs/build/Android.md @@ -2,7 +2,7 @@ ## Dependencies * [Android Studio](https://developer.android.com/studio) -* [NDK 25.2.9519653 and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version) +* [NDK 27+ and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version) * [Git](https://git-scm.com/download) ### WINDOWS ONLY - Additional Dependencies @@ -16,8 +16,7 @@ git clone --recursive https://git.eden-emu.dev/eden-emu/eden.git ``` Eden by default will be cloned into - * `C:\Users\\eden` on Windows -* `~/eden` on Linux -* And wherever on macOS +* `~/eden` on Linux and macOS ## Building 1. Start Android Studio, on the startup dialog select `Open`. @@ -32,7 +31,7 @@ Eden by default will be cloned into - `export ANDROID_SDK_ROOT=path/to/sdk` `export ANDROID_NDK_ROOT=path/to/ndk`. 4. Navigate to `eden/src/android`. -5. Then Build with `./gradlew assemblerelWithDebInfo`. +5. Then Build with `./gradlew assembleRelWithDebInfo`. 6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`. ### Script diff --git a/docs/build/FreeBSD.md b/docs/build/FreeBSD.md deleted file mode 100644 index 97eef8f9d8..0000000000 --- a/docs/build/FreeBSD.md +++ /dev/null @@ -1,81 +0,0 @@ -Eden is not currently available as a port on FreeBSD, though it is in the works. For now, the recommended method of usage is to compile it yourself. Check back often, as the build process frequently changes. - -## Dependencies. -Eden needs the following dependencies: - -``` -devel/cmake -devel/sdl20 -devel/boost-libs -devel/catch2 -devel/libfmt -devel/nlohmann-json -devel/ninja -devel/nasm -devel/autoconf -devel/pkgconf -devel/qt6-base - -net/enet - -multimedia/ffnvcodec-headers -multimedia/ffmpeg - -audio/opus - -archivers/liblz4 - -lang/gcc12 - -graphics/glslang -graphics/vulkan-utility-libraries -``` - -If using FreeBSD 12 or prior, use `devel/pkg-config` instead. - ---- - -### Build preparations: -Run the following command to clone eden with git: -```sh -git clone --recursive https://git.eden-emu.dev/eden-emu/eden -``` -You usually want to add the `--recursive` parameter as it also takes care of the external dependencies for you. - -Now change into the eden directory and create a build directory there: -```sh -cd eden -mkdir build -``` - -Change into that build directory: -```sh -cd build -``` - -#### 1. Building in Release Mode (usually preferred and the most performant choice): -```sh -cmake .. -GNinja -DYUZU_TESTS=OFF -``` - -#### 2. Building in Release Mode with debugging symbols (useful if you want to debug errors for a eventual fix): -```sh -cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=ON -``` - -Build the emulator locally: -```sh -ninja -``` - -Optional: If you wish to install eden globally onto your system issue the following command: -```sh -sudo ninja install -``` -OR -```sh -doas -- ninja install -``` - -## OpenSSL -The available OpenSSL port (3.0.17) is out-of-date, and using a bundled static library instead is recommended; to do so, add `-DYUZU_USE_CPM=ON` to your CMake configure command. \ No newline at end of file diff --git a/docs/build/Linux.md b/docs/build/Linux.md deleted file mode 100644 index a6b7b2dda7..0000000000 --- a/docs/build/Linux.md +++ /dev/null @@ -1,138 +0,0 @@ -### Dependencies - -You'll need to download and install the following to build Eden: - - * [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc - * If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling - * [CMake](https://www.cmake.org/) 3.22+ - -The following are handled by Eden's externals: - - * [FFmpeg](https://ffmpeg.org/) - * [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ - * [opus](https://opus-codec.org/downloads/) 1.3+ - -All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available: - - * [Boost](https://www.boost.org/users/download/) 1.79.0+ - * [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 - * [fmt](https://fmt.dev/) 8.0.1+ - * [lz4](http://www.lz4.org) 1.8+ - * [nlohmann_json](https://github.com/nlohmann/json) 3.8+ - * [OpenSSL](https://www.openssl.org/source/) 1.1.1+ - * [ZLIB](https://www.zlib.net/) 1.2+ - * [zstd](https://facebook.github.io/zstd/) 1.5+ - * [enet](http://enet.bespin.org/) 1.3+ - * [cubeb](https://github.com/mozilla/cubeb) - * [SimpleIni](https://github.com/brofield/simpleini) - -Certain other dependencies (httplib, jwt, sirit, etc.) will be fetched by CPM regardless. System packages *can* be used for these libraries but this is generally not recommended. - -Dependencies are listed here as commands that can be copied/pasted. Of course, they should be inspected before being run. - -- Arch / Manjaro: - - `sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip` - - Building with QT Web Engine requires `qt6-webengine` as well. - - Proper wayland support requires `qt6-wayland` - - 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 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` - -```sh -git submodule update --init --recursive -cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 -``` - -- Fedora: - - `sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel` - - Fedora 32 or later is required. - - Due to GCC 12, Fedora 36 or later users need to install `clang`, and configure CMake to use it via `-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang` - - CMake arguments to force system libraries: - - SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` - - FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` - - [RPM Fusion](https://rpmfusion.org/) (free) is required to install `ffmpeg-devel` - -### Cloning Eden with Git - -**Master:** - -```bash -git clone --recursive https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -The `--recursive` option automatically clones the required Git submodules. - -### Building Eden in Release Mode (Optimised) - -If you need to run ctests, you can disable `-DYUZU_TESTS=OFF` and install Catch2. - -```bash -mkdir build && cd build -cmake .. -GNinja -DYUZU_TESTS=OFF -ninja -sudo ninja install -``` -You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..` - -`-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` might be needed if ninja command failed with `undefined reference to symbol 'spvOptimizerOptionsCreate`, reason currently unknown - -Optionally, you can use `cmake-gui ..` to adjust various options (e.g. disable the Qt GUI). - -### Building Eden in Debug Mode (Slow) - -```bash -mkdir build && cd build -cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DYUZU_TESTS=OFF -ninja -``` - -### Building with debug symbols - -```bash -mkdir build && cd build -cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU -DYUZU_TESTS=OFF -ninja -``` - -### Building with Scripts -A convenience script for building is provided in `.ci/linux/build.sh`. You must provide an arch target for optimization, e.g. `.ci/linux/build.sh amd64`. Valid targets: -- `legacy`: x86_64 generic, only needed for CPUs older than 2013 or so -- `amd64`: x86_64-v3, for CPUs newer than 2013 or so -- `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) -- `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) -- `aarch64`: For armv8-a CPUs, older than mid-2021 or so -- `armv9`: For armv9-a CPUs, newer than mid-2021 or so -- `native`: Optimize to your native host architecture - -Extra flags to pass to CMake should be passed after the arch target. - -Additional environment variables can be used to control building: -- `NPROC`: Number of threads to use for compilation (defaults to all) -- `TARGET`: Set to `appimage` to disable standalone `eden-cli` and `eden-room` executables -- `BUILD_TYPE`: Sets the build type to use. Defaults to `Release` - -The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: -- `DEVEL` (default FALSE): Disable Qt update checker -- `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine -- `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia - -After building, an AppImage can be packaged via `.ci/linux/package.sh`. This script takes the same arch targets as the build script. If the build was created in a different directory, you can specify its path relative to the source directory, e.g. `.ci/linux/package.sh amd64 build-appimage`. Additionally, set the `DEVEL` environment variable to `true` to change the app name to `Eden Nightly`. - -### Running without installing - -After building, the binaries `eden` and `eden-cmd` (depending on your build options) will end up in `build/bin/`. - -```bash -# SDL -cd build/bin/ -./eden-cmd - -# Qt -cd build/bin/ -./eden -``` diff --git a/docs/build/OpenBSD.md b/docs/build/OpenBSD.md deleted file mode 100644 index 6a55fd269d..0000000000 --- a/docs/build/OpenBSD.md +++ /dev/null @@ -1,10 +0,0 @@ -# Building for OpenBSD - -```sh -pkg_add -u -pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq -git --recursive https://git.eden-emu.dev/eden-emu/eden -cmake -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DDYNARMIC_USE_PRECOMPILED_HEADERS=OFF -DCMAKE_BUILD_TYPE=Debug -DENABLE_QT=OFF -DENABLE_OPENSSL=OFF -DENABLE_WEB_SERVICE=OFF -B /usr/obj/eden -``` - -- Modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`. diff --git a/docs/build/Solaris.md b/docs/build/Solaris.md deleted file mode 100644 index f7174c2869..0000000000 --- a/docs/build/Solaris.md +++ /dev/null @@ -1,51 +0,0 @@ -# Building for Solaris - -## Dependencies. -Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability. - -Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`. - -- **gcc**: `sudo pkg install developer/gcc-14`. -- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. - -Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. - -### Building - -Clone eden with git `git clone --recursive https://git.eden-emu.dev/eden-emu/eden` - -```sh -# Needed for some dependencies that call cc directly (tz) -echo '#!/bin/sh' >cc -echo 'gcc $@' >>cc -chmod +x cc -export PATH="$PATH:$PWD" -``` - -Patch for FFmpeg: -```sh -sed -i 's/ make / gmake /' externals/ffmpeg/CMakeFiles/ffmpeg-build.dir/build.make -``` - -- **Configure**: `cmake -B build -DYUZU_USE_CPM=ON -DCMAKE_CXX_FLAGS="-I/usr/include/SDL2" -DCMAKE_C_FLAGS="-I/usr/include/SDL2"`. -- **Build**: `cmake --build build`. -- **Installing**: `sudo cmake --install build`. - -### Running - -Default Mesa is a bit outdated, the following environment variables should be set for a smoother experience: -```sh -export MESA_GL_VERSION_OVERRIDE=4.6 -export MESA_GLSL_VERSION_OVERRIDE=460 -export MESA_EXTENSION_MAX_YEAR=2025 -export MESA_DEBUG=1 -export MESA_VK_VERSION_OVERRIDE=1.3 -# Only if nvidia/intel drm drivers cause crashes, will severely hinder performance -export LIBGL_ALWAYS_SOFTWARE=1 -``` - -### Notes - -- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). -- If using OpenIndiana, due to a bug in SDL2 cmake configuration; Audio driver defaults to SunOS ``, which does not exist on OpenIndiana. -- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_CPM=ON` to use a bundled static OpenSSL, or build a system dependency from source. \ No newline at end of file diff --git a/docs/build/Windows.md b/docs/build/Windows.md deleted file mode 100644 index 76602e6d69..0000000000 --- a/docs/build/Windows.md +++ /dev/null @@ -1,259 +0,0 @@ -# ⚠️ This guide is for developers ONLY! Support will be provided to developers ONLY. - -## 📋 Current building methods: - -* [ Minimal Dependencies](#minimal-dependencies) -* [⚡ Method I: MSVC Build for Windows](#method-i-msvc-build-for-windows) -* [🐧 Method II: MinGW-w64 Build with MSYS2](#method-ii-mingw-w64-build-with-msys2) -* [🖥️ Method III: CLion Environment Setup](#method-iii-clion-environment-setup) -* [💻 Building from the command line with MSVC](#building-from-the-command-line-with-msvc) -* [📜 Building with Scripts](#building-with-scripts) - ---- - - -## Minimal Dependencies - -On Windows, **all** library dependencies are **automatically included** within the `externals` folder. - -You still need to install: - -* **[CMake](https://cmake.org/download/)** - Used to generate Visual Studio project files. -* **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - Make sure to select **Latest SDK**. - - * *A convenience script to install the latest SDK is provided in `.ci/windows/install-vulkan-sdk.ps1`* -* **[Git for Windows](https://gitforwindows.org)** - We recommend installing Git for command line use and version control integration. - - - - * *While installing Git Bash, select "Git from the command line and also from 3rd-party software". If missed, manually set `git.exe` path in CMake.* - ---- - -## ⚡ Method I: MSVC Build for Windows - -### a. Prerequisites to MSVC Build - -* **[Visual Studio 2022 Community](https://visualstudio.microsoft.com/downloads/)** - Make sure to **select C++ support** in the installer, or **update to the latest version** if already installed. - - * *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* - ---- - -### b. Clone the eden repository with Git - -Open Terminal on - -```cmd -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -* *By default `eden` downloads to `C:\Users\\eden`* - ---- - -### c. Building - -* Open the CMake GUI application and point it to the `eden` - - - -* For the build directory, use a `build/` subdirectory inside the source directory or some other directory of your choice. (Tell CMake to create it.) - -* Click the "Configure" button and choose `Visual Studio 17 2022`, with `x64` for the optional platform. - - - - * *(You may also want to disable `YUZU_TESTS` in this case since Catch2 is not yet supported with this.)* - - - -* Click "Generate" to create the project files. - - - -* Open the solution file `yuzu.sln` in Visual Studio 2022, which is located in the build folder. - - - -* * Depending on whether you want a graphical user interface or not, select in the Solution Explorer: - * `eden` (GUI) - * `eden-cmd` (command-line only) - * Then **right-click** and choose `Set as StartUp Project`. - - - - -* Select the appropriate build type, `Debug` for debug purposes or `Release` for performance (in case of doubt choose `Release`). - - - -* **Right-click** the project you want to build and press **Build** in the submenu or press `F5`. - - - ---- - -## 🐧 Method II: MinGW-w64 Build with MSYS2 - -### a. Prerequisites to MinGW-w64 - -* **[MSYS2](https://www.msys2.org)** - A versatile and up-to-date development environment for Windows, providing a Unix-like shell, package manager, and toolchain. - ---- - -### b. Install eden dependencies for MinGW-w64 - -* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) -* Download and install all dependencies using: - * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` -* Add MinGW binaries to the PATH: - * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` -* Add VulkanSDK to the PATH: - * `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` - ---- - -### c. Clone the eden repository with Git - -```cmd -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - ---- - -### d. Building dynamically-linked eden - -* This process will generate a *dynamically* linked build - -```bash -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF - -# Build -make -j$(nproc) - -# Run eden! -./bin/eden.exe -``` - -* *Warning: This build is not a **static** build meaning that you **need** to include all of the DLLs with the .exe in order to use it or other systems!* - ---- - -### Additional notes - - -* Eden doesn't require the rather large Qt dependency, but you will lack a GUI frontend - -```bash -# ... - -# Generate CMake Makefiles (withou QT) -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DENABLE_QT=no - -$ ... -``` - -* Running programs from inside `MSYS2 MinGW x64` shell has a different `%PATH%` than directly from explorer. - * This different `%PATH%` has the locations of the other DLLs required. - - - ---- - -## 🖥️ Method III: CLion Environment Setup - -### a. Prerequisites to CLion - -* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I - ---- - -### b. Cloning eden with CLion - -* Clone the Repository: - - - - - ---- - -### c. Building & Setup - -* Once Cloned, You will be taken to a prompt like the image below: - - - -* Set the settings to the image below: -* Change `Build type: Release` -* Change `Name: Release` -* Change `Toolchain Visual Studio` -* Change `Generator: Let CMake decide` -* Change `Build directory: build` - - - -* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. -* Once this process has been completed (No loading bar bottom right), you can now build eden -* In the top right, click on the drop-down menu, select all configurations, then select eden - - - -* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. - - - ---- - -## 💻 Building from the command line with MSVC - -```cmd -# Clone eden and enter -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden - -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -G "Visual Studio 17 2022" -A x64 -DYUZU_TESTS=OFF - -# Build -cmake --build . --config Release -``` - -## 📜 Building with Scripts - -* A convenience script for building is provided in `.ci/windows/build.sh`. -* You must run this with Bash, e.g. Git Bash or MinGW TTY. -* To use this script, you must have `windeployqt` installed (usually bundled with Qt) and set the `WINDEPLOYQT` environment variable to its canonical Bash location: - * `WINDEPLOYQT="/c/Qt/6.9.1/msvc2022_64/bin/windeployqt6.exe" .ci/windows/build.sh`. -* You can use `aqtinstall`, more info on and - - -* Extra CMake flags should be placed in the arguments of the script. - -#### Additional environment variables can be used to control building: - -* `BUILD_TYPE` (default `Release`): Sets the build type to use. - -* The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: - - * `DEVEL` (default FALSE): Disable Qt update checker - * `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine - * `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia - * `BUNDLE_QT` (default FALSE): Use bundled Qt - - * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH` - * `.ci/windows/build.sh -DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` - -* After building, a zip can be packaged via `.ci/windows/package.sh`. You must have 7-zip installed and in your PATH. - * The resulting zip will be placed into `artifacts` in the source directory. - diff --git a/docs/build/macOS.md b/docs/build/macOS.md deleted file mode 100644 index fd1873b849..0000000000 --- a/docs/build/macOS.md +++ /dev/null @@ -1,78 +0,0 @@ -Please note this article is intended for development, and Eden on macOS is not currently ready for regular use. - -This article was written for developers. Eden support for macOS is not ready for casual use. - -## Dependencies -Install dependencies from Homebrew: -```sh -brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools -``` - -If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`. - -Now, clone the repo: -```sh -git clone --recursive https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -## Method I: ninja - ---- -Build for release -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON -ninja -``` - -You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF -ninja -``` - -Run the output: -``` -bin/eden.app/Contents/MacOS/eden -``` - -## Method II: Xcode - ---- -Build for release -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -# Only if having errors about Xcode 15.0 -sudo /usr/bin/xcode-select --switch /Users/admin/Downloads/Xcode.ap -cmake -B build -GXcode -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON -xcodebuild build -project yuzu.xcodeproj -scheme "yuzu" -configuration "RelWithDebInfo" -``` - -Build with debug symbols: -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF -ninja -``` - -Run the output: -``` -bin/eden.app/Contents/MacOS/eden -``` - ---- - -To run with MoltenVK, install additional dependencies: -```sh -brew install molten-vk vulkan-loader -``` - -Run with Vulkan loader path: -```sh -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -bin/eden.app/Contents/MacOS/eden -``` diff --git a/docs/img/creator-1.png b/docs/img/creator-1.png new file mode 100644 index 0000000000..14d679cfbb Binary files /dev/null and b/docs/img/creator-1.png differ diff --git a/docs/scripts/Linux.md b/docs/scripts/Linux.md new file mode 100644 index 0000000000..8b18e41ced --- /dev/null +++ b/docs/scripts/Linux.md @@ -0,0 +1,31 @@ +# Linux Build Scripts + +* Provided script: `.ci/linux/build.sh` +* Must specify arch target, e.g.: `.ci/linux/build.sh amd64` +* Valid targets: + * `native`: Optimize to your native host architecture + * `legacy`: x86\_64 generic, only needed for CPUs older than 2013 or so + * `amd64`: x86\_64-v3, for CPUs newer than 2013 or so + * `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) + * `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) + * `aarch64`: For armv8-a CPUs, older than mid-2021 or so + * `armv9`: For armv9-a CPUs, newer than mid-2021 or so +* Extra CMake flags go after the arch target. + +### Environment Variables + +* `NPROC`: Number of compilation threads (default: all cores) +* `TARGET`: Set `appimage` to disable standalone `eden-cli` and `eden-room` +* `BUILD_TYPE`: Build type (default: `Release`) + +Boolean flags (set `true` to enable, `false` to disable): + +* `DEVEL` (default `FALSE`): Disable Qt update checker +* `USE_WEBENGINE` (default `FALSE`): Enable Qt WebEngine +* `USE_MULTIMEDIA` (default `FALSE`): Enable Qt Multimedia + +* AppImage packaging script: `.ci/linux/package.sh` + + * Accepts same arch targets as build script + * Use `DEVEL=true` to rename app to `Eden Nightly` + * This should generally not be used unless in a tailor-made packaging environment (e.g. Actions/CI) \ No newline at end of file diff --git a/docs/scripts/Windows.md b/docs/scripts/Windows.md new file mode 100644 index 0000000000..e60c2119a2 --- /dev/null +++ b/docs/scripts/Windows.md @@ -0,0 +1,29 @@ +# Windows Build Scripts + +* A convenience script for building is provided in `.ci/windows/build.sh`. +* You must run this with Bash, e.g. Git Bash or the MinGW TTY. +* To use this script, you must have `windeployqt` installed (usually bundled with Qt) and set the `WINDEPLOYQT` environment variable to its canonical Bash location: + * `WINDEPLOYQT="/c/Qt/6.9.1/msvc2022_64/bin/windeployqt6.exe" .ci/windows/build.sh`. +* You can use `aqtinstall`, more info on and + + +* Extra CMake flags should be placed in the arguments of the script. + +#### Additional environment variables can be used to control building: + +* `BUILD_TYPE` (default `Release`): Sets the build type to use. + +* The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: + + * `DEVEL` (default FALSE): Disable Qt update checker + * `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine + * `USE_MULTIMEDIA` (default FALSE): Enable Qt Multimedia + * `BUNDLE_QT` (default FALSE): Use bundled Qt + + * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH` + * `.ci/windows/build.sh -DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` + +* After building, a zip can be packaged via `.ci/windows/package.sh`. You must have 7-zip installed and in your PATH. + * The resulting zip will be placed into `artifacts` in the source directory. + + diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 9f89cfc1f5..ce1450e241 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -1,9 +1,6 @@ # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - # SPDX-FileCopyrightText: 2016 Citra Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later @@ -54,36 +51,27 @@ endif() # Glad add_subdirectory(glad) -# mbedtls -AddJsonPackage(mbedtls) - -if (mbedtls_ADDED) - target_include_directories(mbedtls PUBLIC ${mbedtls_SOURCE_DIR}/include) - - if (NOT MSVC) - target_compile_options(mbedcrypto PRIVATE - -Wno-unused-but-set-variable - -Wno-string-concatenation - ) - elseif(CXX_CLANG) - foreach(TARGET mbedtls mbedcrypto mbedx509) - target_compile_options(${TARGET} PRIVATE - -w - ) - endforeach() - endif() -endif() - # libusb if (ENABLE_LIBUSB) add_subdirectory(libusb) endif() -# Sirit -# TODO(crueter): spirv-tools doesn't work w/ system -set(SPIRV_WERROR OFF) -AddJsonPackage(spirv-headers) +# VMA +AddJsonPackage(vulkan-memory-allocator) +if (VulkanMemoryAllocator_ADDED) + if (CXX_CLANG) + target_compile_options(VulkanMemoryAllocator INTERFACE + -Wno-unused-variable + ) + elseif(MSVC) + target_compile_options(VulkanMemoryAllocator INTERFACE + /wd4189 + ) + endif() +endif() + +# Sirit AddJsonPackage(sirit) if(MSVC AND USE_CCACHE AND sirit_ADDED) @@ -117,46 +105,9 @@ if (YUZU_USE_BUNDLED_FFMPEG) set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE) endif() -# VulkanUtilityHeaders - pulls in headers and utility libs -AddJsonPackage( - NAME vulkan-utility-headers - BUNDLED_PACKAGE ${YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES} -) - -# small hack -if (NOT VulkanUtilityLibraries_ADDED) - find_package(VulkanHeaders 1.3.274 REQUIRED) -endif() - -# SPIRV Tools -AddJsonPackage( - NAME spirv-tools - 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 -AddJsonPackage(vulkan-memory-allocator) - -if (VulkanMemoryAllocator_ADDED) - if (CXX_CLANG) - target_compile_options(VulkanMemoryAllocator INTERFACE - -Wno-unused-variable - ) - elseif(MSVC) - target_compile_options(VulkanMemoryAllocator INTERFACE - /wd4189 - ) - endif() -endif() - if (NOT TARGET LLVM::Demangle) add_library(demangle demangle/ItaniumDemangle.cpp) target_include_directories(demangle PUBLIC ./demangle) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 65f50ffdfc..283da76743 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -1,15 +1,10 @@ { - "mbedtls": { - "repo": "eden-emulator/mbedtls", - "sha": "ce4f81f4a9", - "hash": "f2e7f887651b28745e508149214d409fd7cfdb92cb94b4146b47ff1e0fc09e47143f203ac18e34c2c1814b5bd031d04c74828676c0d4342920a2ddb7fd35e9a5", - "find_args": "MODULE" - }, - "spirv-headers": { - "package": "SPIRV-Headers", - "repo": "KhronosGroup/SPIRV-Headers", - "sha": "4e209d3d7e", - "hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4" + "vulkan-memory-allocator": { + "package": "VulkanMemoryAllocator", + "repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator", + "sha": "1076b348ab", + "hash": "a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772", + "find_args": "CONFIG" }, "sirit": { "repo": "eden-emulator/sirit", @@ -35,31 +30,6 @@ "CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF" ] }, - "vulkan-utility-headers": { - "package": "VulkanUtilityLibraries", - "repo": "scripts/VulkanUtilityHeaders", - "tag": "1.4.326", - "artifact": "VulkanUtilityHeaders.tar.zst", - "git_host": "git.crueter.xyz", - "hash": "5924629755cb1605c4aa4eee20ef7957a9dd8d61e4df548be656d98054f2730c4109693c1bd35811f401f4705d2ccff9fc849be32b0d8480bc3f73541a5e0964" - }, - "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", diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt index 8908aa234f..c5a8b3555b 100644 --- a/externals/ffmpeg/CMakeLists.txt +++ b/externals/ffmpeg/CMakeLists.txt @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2021 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt index 0a20ca94b8..77a762d070 100644 --- a/externals/libusb/CMakeLists.txt +++ b/externals/libusb/CMakeLists.txt @@ -1,14 +1,29 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2020 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later include(CPMUtil) -AddJsonPackage(libusb) +# we love our libraries don't we folks +if (PLATFORM_SUN) + set(libusb_bundled ON) +else() + set(libusb_bundled OFF) +endif() + +# TODO(crueter): Fix on Solaris +AddJsonPackage( + NAME libusb + BUNDLED_PACKAGE ${libusb_bundled} +) if (NOT libusb_ADDED) return() endif() +# TODO: *BSD fails to compile--may need different configs/symbols if (MINGW OR PLATFORM_LINUX OR APPLE) set(LIBUSB_FOUND ON CACHE BOOL "libusb is present" FORCE) set(LIBUSB_VERSION "1.0.24" CACHE STRING "libusb version string" FORCE) diff --git a/externals/nx_tzdb/CMakeLists.txt b/externals/nx_tzdb/CMakeLists.txt index a08c80f2bd..a51939f7c8 100644 --- a/externals/nx_tzdb/CMakeLists.txt +++ b/externals/nx_tzdb/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: 2023 yuzu Emulator Project diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb66e55964..184b049d06 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -234,6 +234,8 @@ if (YUZU_ROOM_STANDALONE) endif() if (ENABLE_QT) + add_definitions(-DYUZU_QT_WIDGETS) + add_subdirectory(qt_common) add_subdirectory(yuzu) endif() diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt index 98f342c274..9ea2a9ee17 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt @@ -36,17 +36,18 @@ 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.databinding.CardGameGridCompactBinding 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(exact = false) { companion object { const val VIEW_TYPE_GRID = 0 - const val VIEW_TYPE_LIST = 1 - const val VIEW_TYPE_CAROUSEL = 2 + const val VIEW_TYPE_GRID_COMPACT = 1 + const val VIEW_TYPE_LIST = 2 + const val VIEW_TYPE_CAROUSEL = 3 } private var viewType = 0 @@ -80,6 +81,7 @@ class GameAdapter(private val activity: AppCompatActivity) : listBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT listBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT } + VIEW_TYPE_GRID -> { val gridBinding = holder.binding as CardGameGridBinding gridBinding.cardGameGrid.scaleX = 1f @@ -89,6 +91,17 @@ class GameAdapter(private val activity: AppCompatActivity) : gridBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT } + + VIEW_TYPE_GRID_COMPACT -> { + val gridCompactBinding = holder.binding as CardGameGridCompactBinding + gridCompactBinding.cardGameGridCompact.scaleX = 1f + gridCompactBinding.cardGameGridCompact.scaleY = 1f + gridCompactBinding.cardGameGridCompact.alpha = 1f + // Reset layout params to XML defaults (same as normal grid) + gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT + gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT + } + VIEW_TYPE_CAROUSEL -> { val carouselBinding = holder.binding as CardGameCarouselBinding // soothens transient flickering @@ -105,16 +118,25 @@ class GameAdapter(private val activity: AppCompatActivity) : parent, false ) + VIEW_TYPE_GRID -> CardGameGridBinding.inflate( LayoutInflater.from(parent.context), parent, false ) + + VIEW_TYPE_GRID_COMPACT -> CardGameGridCompactBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + VIEW_TYPE_CAROUSEL -> CardGameCarouselBinding.inflate( LayoutInflater.from(parent.context), parent, false ) + else -> throw IllegalArgumentException("Invalid view type") } return GameViewHolder(binding, viewType) @@ -130,6 +152,7 @@ class GameAdapter(private val activity: AppCompatActivity) : VIEW_TYPE_LIST -> bindListView(model) VIEW_TYPE_GRID -> bindGridView(model) VIEW_TYPE_CAROUSEL -> bindCarouselView(model) + VIEW_TYPE_GRID_COMPACT -> bindGridCompactView(model) } } @@ -168,6 +191,23 @@ class GameAdapter(private val activity: AppCompatActivity) : gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT } + private fun bindGridCompactView(model: Game) { + val gridCompactBinding = binding as CardGameGridCompactBinding + + gridCompactBinding.imageGameScreenCompact.scaleType = ImageView.ScaleType.CENTER_CROP + GameIconUtils.loadGameIcon(model, gridCompactBinding.imageGameScreenCompact) + + gridCompactBinding.textGameTitleCompact.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ") + + gridCompactBinding.textGameTitleCompact.marquee() + gridCompactBinding.cardGameGridCompact.setOnClickListener { onClick(model) } + gridCompactBinding.cardGameGridCompact.setOnLongClickListener { onLongClick(model) } + + // Reset layout params to XML defaults (same as normal grid) + gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT + gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT + } + private fun bindCarouselView(model: Game) { val carouselBinding = binding as CardGameCarouselBinding @@ -232,8 +272,6 @@ 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) @@ -248,23 +286,6 @@ 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() } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 6d4bfd97ac..3c5b9003de 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -35,7 +35,6 @@ 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"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt index 2564849ef4..a52f582031 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt @@ -37,7 +37,6 @@ 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 diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 883d8efaef..1f2ba81a73 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -297,13 +297,6 @@ 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, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 630bcb0d74..14d62ceec3 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -210,7 +210,6 @@ 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) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index 5cc912fbbe..8162098caa 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt @@ -810,28 +810,26 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) - if (_binding == null) { - return - } + val b = _binding ?: return updateScreenLayout() val showInputOverlay = BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean() if (emulationActivity?.isInPictureInPictureMode == true) { - if (binding.drawerLayout.isOpen) { - binding.drawerLayout.close() + if (b.drawerLayout.isOpen) { + b.drawerLayout.close() } if (showInputOverlay) { - binding.surfaceInputOverlay.setVisible(visible = false, gone = false) + b.surfaceInputOverlay.setVisible(visible = false, gone = false) } } else { - binding.surfaceInputOverlay.setVisible( + b.surfaceInputOverlay.setVisible( showInputOverlay && emulationViewModel.emulationStarted.value ) if (!isInFoldableLayout) { if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { - binding.surfaceInputOverlay.layout = OverlayLayout.Portrait + b.surfaceInputOverlay.layout = OverlayLayout.Portrait } else { - binding.surfaceInputOverlay.layout = OverlayLayout.Landscape + b.surfaceInputOverlay.layout = OverlayLayout.Landscape } } } @@ -847,8 +845,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } private fun updateQuickOverlayMenuEntry(isVisible: Boolean) { - val menu = binding.inGameMenu.menu - val item = menu.findItem(R.id.menu_quick_overlay) + val b = _binding ?: return + val item = b.inGameMenu.menu.findItem(R.id.menu_quick_overlay) ?: return + if (isVisible) { item.title = getString(R.string.emulation_hide_overlay) item.icon = ResourcesCompat.getDrawable( @@ -867,8 +866,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } private fun updatePauseMenuEntry(isPaused: Boolean) { - val menu = binding.inGameMenu.menu - val pauseItem = menu.findItem(R.id.menu_pause_emulation) + val b = _binding ?: return + val pauseItem = b.inGameMenu.menu.findItem(R.id.menu_pause_emulation) ?: return if (isPaused) { pauseItem.title = getString(R.string.emulation_unpause) pauseItem.icon = ResourcesCompat.getDrawable( @@ -887,9 +886,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } override fun onPause() { - if (emulationState.isRunning && emulationActivity?.isInPictureInPictureMode != true) { - emulationState.pause() - updatePauseMenuEntry(true) + if (this::emulationState.isInitialized) { + if (emulationState.isRunning && emulationActivity?.isInPictureInPictureMode != true) { + emulationState.pause() + updatePauseMenuEntry(true) + } } super.onPause() } @@ -906,15 +907,15 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { override fun onResume() { super.onResume() - // If the overlay is enabled, we need to update the position if changed - val position = IntSetting.PERF_OVERLAY_POSITION.getInt() - updateStatsPosition(position) + val b = _binding ?: return + updateStatsPosition(IntSetting.PERF_OVERLAY_POSITION.getInt()) + updateSocPosition(IntSetting.SOC_OVERLAY_POSITION.getInt()) - val socPosition = IntSetting.SOC_OVERLAY_POSITION.getInt() - updateSocPosition(socPosition) - - binding.inGameMenu.post { - emulationState?.isPaused?.let { updatePauseMenuEntry(it) } + if (this::emulationState.isInitialized) { + b.inGameMenu.post { + if (!this::emulationState.isInitialized || _binding == null) return@post + updatePauseMenuEntry(emulationState.isPaused) + } } } @@ -1229,6 +1230,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } private fun updateScreenLayout() { + val b = _binding ?: return val verticalAlignment = EmulationVerticalAlignment.from(IntSetting.VERTICAL_ALIGNMENT.getInt()) val aspectRatio = when (IntSetting.RENDERER_ASPECT_RATIO.getInt()) { @@ -1240,35 +1242,37 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } when (verticalAlignment) { EmulationVerticalAlignment.Top -> { - binding.surfaceEmulation.setAspectRatio(aspectRatio) + b.surfaceEmulation.setAspectRatio(aspectRatio) val params = FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) params.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL - binding.surfaceEmulation.layoutParams = params + b.surfaceEmulation.layoutParams = params } EmulationVerticalAlignment.Center -> { - binding.surfaceEmulation.setAspectRatio(null) - binding.surfaceEmulation.updateLayoutParams { + b.surfaceEmulation.setAspectRatio(null) + b.surfaceEmulation.updateLayoutParams { width = ViewGroup.LayoutParams.MATCH_PARENT height = ViewGroup.LayoutParams.MATCH_PARENT } } EmulationVerticalAlignment.Bottom -> { - binding.surfaceEmulation.setAspectRatio(aspectRatio) + b.surfaceEmulation.setAspectRatio(aspectRatio) val params = FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) params.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL - binding.surfaceEmulation.layoutParams = params + b.surfaceEmulation.layoutParams = params } } - emulationState.updateSurface() + if (this::emulationState.isInitialized) { + emulationState.updateSurface() + } emulationActivity?.buildPictureInPictureParams() updateOrientation() } @@ -1722,4 +1726,4 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { private val perfStatsUpdateHandler = Handler(Looper.myLooper()!!) private val socUpdateHandler = Handler(Looper.myLooper()!!) } -} +} \ No newline at end of file diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt index 03fa1a3a2e..80055628e1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt @@ -194,6 +194,10 @@ class GamesFragment : Fragment() { val columns = resources.getInteger(R.integer.game_columns_grid) GridLayoutManager(context, columns) } + GameAdapter.VIEW_TYPE_GRID_COMPACT -> { + val columns = resources.getInteger(R.integer.game_columns_grid) + GridLayoutManager(context, columns) + } GameAdapter.VIEW_TYPE_LIST -> { val columns = resources.getInteger(R.integer.game_columns_list) GridLayoutManager(context, columns) @@ -300,6 +304,7 @@ class GamesFragment : Fragment() { val currentViewType = getCurrentViewType() when (currentViewType) { GameAdapter.VIEW_TYPE_LIST -> popup.menu.findItem(R.id.view_list).isChecked = true + GameAdapter.VIEW_TYPE_GRID_COMPACT -> popup.menu.findItem(R.id.view_grid_compact).isChecked = true GameAdapter.VIEW_TYPE_GRID -> popup.menu.findItem(R.id.view_grid).isChecked = true GameAdapter.VIEW_TYPE_CAROUSEL -> popup.menu.findItem(R.id.view_carousel).isChecked = true } @@ -314,6 +319,14 @@ class GamesFragment : Fragment() { true } + R.id.view_grid_compact -> { + if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause() + setCurrentViewType(GameAdapter.VIEW_TYPE_GRID_COMPACT) + applyGridGamesBinding() + item.isChecked = true + true + } + R.id.view_list -> { if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause() setCurrentViewType(GameAdapter.VIEW_TYPE_LIST) diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index 9ad00d26ee..1390d2854c 100644 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2023 yuzu Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/android/app/src/main/res/drawable/gradient_overlay_bottom.xml b/src/android/app/src/main/res/drawable/gradient_overlay_bottom.xml new file mode 100644 index 0000000000..f74cfa0d05 --- /dev/null +++ b/src/android/app/src/main/res/drawable/gradient_overlay_bottom.xml @@ -0,0 +1,9 @@ + + + + diff --git a/src/android/app/src/main/res/layout/card_game_grid.xml b/src/android/app/src/main/res/layout/card_game_grid.xml index 3e0bf6005c..f03a77c4f1 100644 --- a/src/android/app/src/main/res/layout/card_game_grid.xml +++ b/src/android/app/src/main/res/layout/card_game_grid.xml @@ -5,27 +5,32 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:focusable="false" - android:focusableInTouchMode="false"> + android:focusableInTouchMode="false" + android:padding="4dp"> + app:cardCornerRadius="16dp" + android:foreground="@color/eden_border_gradient_start"> + android:paddingTop="14dp" + android:paddingLeft="6dp" + android:paddingRight="6dp" + android:paddingBottom="6dp"> + + + + + + + + + + + + + + + + + + + + + diff --git a/src/android/app/src/main/res/menu/menu_game_views.xml b/src/android/app/src/main/res/menu/menu_game_views.xml index 241cdcb4b5..11bf3e695e 100644 --- a/src/android/app/src/main/res/menu/menu_game_views.xml +++ b/src/android/app/src/main/res/menu/menu_game_views.xml @@ -4,6 +4,9 @@ + يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقت أثناء تحديثات الذاكرة، مما يقلل استخدام المعالج ويحسن أدائه. قد يسبب هذا أعطالاً أو تعطلًا في بعض الألعاب. تمكين محاكاة MMU المضيف يعمل هذا التحسين على تسريع وصول الذاكرة بواسطة البرنامج الضيف. يؤدي تمكينه إلى إجراء عمليات قراءة/كتابة ذاكرة الضيف مباشرة في الذاكرة والاستفادة من MMU المضيف. يؤدي تعطيل هذا إلى إجبار جميع عمليات الوصول إلى الذاكرة على استخدام محاكاة MMU البرمجية. - مستوى DMA - يتحكم في دقة تحديد مستوى DMA. الدقة الأعلى يمكنها إصلاح بعض المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اتركه على الوضع الافتراضي. + دقة DMA + يتحكم في دقة تحديد DMA. يمكن أن تصلح الدقة الآمنة المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اترك هذا على الوضع الافتراضي. 4 جيجابايت (موصى به) @@ -498,8 +498,6 @@ ساعة مخصصة في الوقت الحقيقي يسمح لك بتعيين ساعة مخصصة في الوقت الفعلي منفصلة عن وقت النظام الحالي لديك تعيين ساعة مخصصة في الوقت الحقيقي - تعطيل التحقق من NCA - يعطل التحقق من سلامة أرشيفات محتوى NCA. قد يحسن هذا من سرعة التحميل لكنه يخاطر بتلف البيانات أو تمرير ملفات غير صالحة دون اكتشاف. ضروري لجعل الألعاب والتحديثات التي تتطلب نظامًا أساسيًا 20+ تعمل. توليد @@ -794,9 +792,8 @@ افتراضي - عادي - عالي - مفرط + غير آمن (سريع) + آمن (مستقر) 0.25X (180p/270p) @@ -839,13 +836,13 @@ تمتد إلى النافذة - Dynarmic (بطيء) + Dynarmic (JIT) تنفيذ التعليمات البرمجية الأصلية (NCE) دقه غير آمن - Paranoid (بطيء) + Paranoid الأسهم diff --git a/src/android/app/src/main/res/values-ckb/strings.xml b/src/android/app/src/main/res/values-ckb/strings.xml index af0eeeaa45..fe94f97dc5 100644 --- a/src/android/app/src/main/res/values-ckb/strings.xml +++ b/src/android/app/src/main/res/values-ckb/strings.xml @@ -128,8 +128,8 @@ هەندێک لە بازنەکردنەکانی هەڵگر لە کاتی نوێکردنەوەی بیرگە دەنێرێت، کەمکردنەوەی بەکارهێنانی CPU و باشترکردنی کارایی. لەوانەیە لە هەندێک یاری کێشە درووست بکات. چالاککردنی میمیکردنی MMU میواندە ئەم باشکردنە خێرایی دەستکەوتنی بیرگە لەلایەن پرۆگرامی میوانەکە زیاد دەکات. چالاککردنی وای لێدەکات کە خوێندنەوە/نووسینەکانی بیرگەی میوانەکە ڕاستەوخۆ لە بیرگە ئەنجام بدرێت و میمیکردنی MMU میواندە بەکاربهێنێت. ناچالاککردنی ئەمە هەموو دەستکەوتنەکانی بیرگە ڕەت دەکاتەوە لە بەکارهێنانی میمیکردنی MMU نەرمەکاڵا. - ئاستی DMA - کۆنتڕۆڵی وردی ڕێکخستنی DMA دەکات. وردی زیاتر دەتوانێ هەندێک کێشە لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، بە ڕێکخستنی بنەڕەتی بێڵە. + وردیی DMA + کۆنتڕۆڵی وردیی وردیی DMA دەکات. وردییی پارێزراو دەتوانێت کێشەکان لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، ئەمە بە سەر ڕەھەوادا بهێڵە. 4GB (پێشنیارکراو) 6GB (نائاسایش) @@ -482,8 +482,6 @@ RTCی تایبەتمەند ڕێگەت پێدەدات کاتژمێرێکی کاتی ڕاستەقینەی تایبەتمەند دابنێیت کە جیاوازە لە کاتی ئێستای سیستەمەکەت. دانانی RTCی تایبەتمەند - ناچالاککردنی پشکنینی NCA - پشکنینی پێکهاتەی ئارشیڤەکانی ناوەڕۆکی NCA ناچالاک دەکات. ئەمە لەوانەیە خێرایی بارکردن بهرهوپێش ببات، بەڵام مەترسی لەناوچوونی داتا یان ئەوەی فایلە نادروستەکان بەبێ ئەوەی دۆزرایەوە تێپەڕبن زیاتر دەکات. بۆ ئەوەی یاری و نوێکردنەوەکان کار بکەن کە پێویستی بە فریموێری 20+ هەیە زۆر پێویستە. بەرهەم هێنان @@ -763,9 +761,8 @@ بنەڕەتی - ئاسایی - بەرز - زۆر بەرز + نەپارێزراو (خێرا) + پارێزراو (جێگیر) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-cs/strings.xml b/src/android/app/src/main/res/values-cs/strings.xml index 8d42b8303f..785f96b84c 100644 --- a/src/android/app/src/main/res/values-cs/strings.xml +++ b/src/android/app/src/main/res/values-cs/strings.xml @@ -127,8 +127,8 @@ 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. Povolit emulaci hostitelské MMU 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. - Úroveň DMA - 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í. + Přesnost DMA + Ovládá přesnost DMA. Bezpečná přesnost může opravit problémy v některých hrách, ale v některých případech může také ovlivnit výkon. Pokud si nejste jisti, ponechte to na výchozím nastavení. 4GB (Doporučeno) 6GB (Nebezpečné) @@ -458,8 +458,6 @@ Vlastní RTC Vlastní nastavení času Nastavit vlastní RTC - Zakázat ověřování NCA - 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+. Generovat @@ -737,9 +735,8 @@ Výchozí - Normální - Vysoká - Extrémní + Nebezpečné (rychlé) + Bezpečné (stabilní) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml index 907b114388..495804e328 100644 --- a/src/android/app/src/main/res/values-de/strings.xml +++ b/src/android/app/src/main/res/values-de/strings.xml @@ -128,8 +128,8 @@ Ü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. Host-MMU-Emulation aktivieren 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. - DMA-Level - 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. + DMA-Genauigkeit + Steuert die DMA-Präzisionsgenauigkeit. Sichere Präzision kann Probleme in einigen Spielen beheben, kann aber in einigen Fällen auch die Leistung beeinträchtigen. Im Zweifel lassen Sie dies auf Standard stehen. 4 GB (Empfohlen) 6 GB (Unsicher) @@ -486,8 +486,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die RTC-Datum auswählen RTC-Zeit auswählen Benutzerdefinierte Echtzeituhr - NCA-Verifizierung deaktivieren - 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. Generieren @@ -829,9 +827,8 @@ Wirklich fortfahren? Standard - Normal - Hoch - Extrem + Unsicher (schnell) + Sicher (stabil) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml index 12b7183cae..1f73df7385 100644 --- a/src/android/app/src/main/res/values-es/strings.xml +++ b/src/android/app/src/main/res/values-es/strings.xml @@ -128,8 +128,8 @@ Omite ciertas invalidaciones de caché durante actualizaciones de memoria, reduciendo el uso de CPU y mejorando su rendimiento. Puede causar fallos en algunos juegos. Habilitar emulación de MMU del host 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. - Nivel de DMA - 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. + Precisión de DMA + Controla la precisión de DMA. La precisión segura puede solucionar problemas en algunos juegos, pero también puede afectar al rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado. 4GB (Recomendado) 6GB (Inseguro) @@ -506,8 +506,6 @@ RTC personalizado Te permite tener un reloj personalizado en tiempo real diferente del tiempo del propio sistema. Configurar RTC personalizado - Desactivar verificación NCA - 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+. Generar @@ -872,9 +870,8 @@ Predeterminado - Normal - Alto - Extremo + Inseguro (rápido) + Seguro (estable) 0.25X (180p/270p) @@ -922,13 +919,13 @@ Ajustar a la ventana - DynARMic (lento) + Dynarmic (JIT) Ejecución nativa de código (NCE) Preciso Impreciso - Paranoico (Lento) + Paranoico Cruceta diff --git a/src/android/app/src/main/res/values-fa/strings.xml b/src/android/app/src/main/res/values-fa/strings.xml index d7ac1b770a..fd5c6ae6ca 100644 --- a/src/android/app/src/main/res/values-fa/strings.xml +++ b/src/android/app/src/main/res/values-fa/strings.xml @@ -128,8 +128,8 @@ بعضی ابطالهای حافظه نهان در هنگام بهروزرسانیهای حافظه را رد میکند، استفاده از CPU را کاهش داده و عملکرد آن را بهبود میبخشد. ممکن است در برخی بازیها باعث مشکلات یا خرابی شود. فعالسازی شبیهسازی MMU میزبان این بهینهسازی دسترسیهای حافظه توسط برنامه میهمان را تسریع میکند. فعالسازی آن باعث میشود خواندن/نوشتن حافظه میهمان مستقیماً در حافظه انجام شود و از MMU میزبان استفاده کند. غیرفعال کردن این قابلیت، همه دسترسیهای حافظه را مجبور به استفاده از شبیهسازی نرمافزاری MMU میکند. - سطح DMA - دقت صحت DMA را کنترل می کند. دقت بالاتر می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز می تواند بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، آن را روی پیش فرض بگذارید. + دقت DMA + دقت صحت DMA را کنترل می کند. دقت ایمن می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز ممکن است بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، این گزینه را روی پیش فرض بگذارید. 4 گیگابایت (توصیه شده) 6 گیگابایت (ناامن) @@ -504,8 +504,6 @@ زمان سفارشی به شما امکان میدهد یک ساعت سفارشی جدا از زمان فعلی سیستم خود تنظیم کنید. تنظیم زمان سفارشی - غیرفعال کردن تأیید اعتبار NCA - بررسی صحت آرشیوهای محتوای NCA را غیرفعال میکند. این ممکن است سرعت بارگذاری را بهبود بخشد اما خطر خرابی داده یا تشخیص داده نشدن فایلهای نامعتبر را به همراه دارد. برای کار کردن بازیها و بهروزرسانیهایی که به فرمور ۲۰+ نیاز دارند، ضروری است. تولید @@ -871,9 +869,8 @@ پیش فرض - معمولی - بالا - فوق العاده + ناایمن (سریع) + ایمن (پایدار) 0.25X (180p/270p) @@ -921,13 +918,13 @@ کشش تا پر کردن پنجره - دینارمیک (کند) + Dynarmic (JIT) اجرای کد اصلی (NCE) دقیق ناامن - بدگمان (کند) + بدگمان کلیدهای جهتی diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml index 62e67a6fee..97496ef33d 100644 --- a/src/android/app/src/main/res/values-fr/strings.xml +++ b/src/android/app/src/main/res/values-fr/strings.xml @@ -128,8 +128,8 @@ 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. Activer l\'émulation de la MMU hôte 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. - Niveau DMA - 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. + Précision DMA + Contrôle la précision du DMA. Une précision sûre 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 ce paramètre sur Par défaut. 4 Go (Recommandé) 6 Go (Dangereux) @@ -506,8 +506,6 @@ RTC personnalisé Vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système. Définir l\'horloge RTC personnalisée - Désactiver la vérification NCA - 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+. Générer @@ -920,9 +918,8 @@ Défaut - Normal - Élevé - Extrême + Dangereux (rapide) + Sûr (stable) 0.25X (180p/270p) @@ -970,13 +967,13 @@ Étirer à la fenêtre - Dynarmic (Lent) + Dynarmic (JIT) Exécution de code natif (NCE) Précis Risqué - Paranoïaque (Lent) + Paranoïaque Pavé directionnel diff --git a/src/android/app/src/main/res/values-he/strings.xml b/src/android/app/src/main/res/values-he/strings.xml index ec5b526ce0..359e8dff9a 100644 --- a/src/android/app/src/main/res/values-he/strings.xml +++ b/src/android/app/src/main/res/values-he/strings.xml @@ -129,8 +129,8 @@ מדלג על איפוסי מטמון מסוימים במהלך עדכוני זיכרון, מפחית שימוש במעבד ומשפר ביצועים. עלול לגרום לתקלות או קריסות בחלק מהמשחקים. הפעל אמולציית MMU מארח אופטימיזציה זו מאיצה את גישת הזיכרון על ידי התוכנית האורחת. הפעלתה גורמת לכך שפעולות קריאה/כתיבה לזיכרון האורח מתבצעות ישירות לזיכרון ומשתמשות ב-MMU של המארח. השבתת זאת מאלצת את כל גישות הזיכרון להשתמש באמולציית MMU תוכנתית. - רמת DMA - שולטת בדיוק הדיוק של DMA. דיוק גבוה יותר יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר ברירת מחדל. + דיוק DMA + שולט בדיוק הדיוק של DMA. דיוק בטוח יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר זאת על ברירת מחדל. 4GB (מומלץ) 6GB (לא בטוח) @@ -505,8 +505,6 @@ RTC מותאם אישית מאפשר לך לקבוע שעון זמן אמת נפרד משעון המערכת שלך. קבע RTC מותאם אישית - השבת אימות NCA - משבית את אימות השלמות של ארכיוני התוכן של NCA. זה עשוי לשפר את מהירות הטעינה אך מסתכן בשחיקת נתונים או שמא קבצים לא חוקיים יעברו ללא זיהוי. זה הכרחי כדי לגרום למשחקים ועדכונים הדורשים firmware 20+ לעבוד. יצירה @@ -802,9 +800,8 @@ ברירת מחדל - רגיל - גבוה - קיצוני + לא בטוח (מהיר) + בטוח (יציב) 0.25X (180p/270p) @@ -847,13 +844,13 @@ הרחב לגודל המסך - דינמי (איטי) + דינמי ביצוע קוד מקורי (NCE) מדויק לא בטוח - פראנואידי (איטי) + פראנואידי D-pad diff --git a/src/android/app/src/main/res/values-hu/strings.xml b/src/android/app/src/main/res/values-hu/strings.xml index b45692f147..36157d1578 100644 --- a/src/android/app/src/main/res/values-hu/strings.xml +++ b/src/android/app/src/main/res/values-hu/strings.xml @@ -128,8 +128,8 @@ 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. Gazda MMU emuláció engedélyezése 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. - DMA szint - 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. + DMA pontosság + Szabályozza a DMA pontosságát. A biztonságos 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áson. 4GB (Ajánlott) 6GB (Nem biztonságos) @@ -501,8 +501,6 @@ Egyéni RTC Megadhatsz egy valós idejű órát, amely eltér a rendszer által használt órától. Egyéni RTC beállítása - NCA ellenőrzés letiltása - 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. Generálás @@ -909,9 +907,8 @@ Alapértelmezett - Normál - Magas - Extrém + Nem biztonságos (gyors) + Biztonságos (stabil) 0.25X (180p/270p) @@ -957,13 +954,13 @@ Ablakhoz nyújtás - Dinamikus (lassú) + Dynarmic (JIT) Natív kód végrehajtás (Native code execution (NCE)) Pontos Nem biztonságos - Paranoid (Lassú) + Paranoid D-pad diff --git a/src/android/app/src/main/res/values-id/strings.xml b/src/android/app/src/main/res/values-id/strings.xml index 1817fc654a..18e881a97b 100644 --- a/src/android/app/src/main/res/values-id/strings.xml +++ b/src/android/app/src/main/res/values-id/strings.xml @@ -128,8 +128,8 @@ Melewati beberapa pembatalan cache sisi CPU selama pembaruan memori, mengurangi penggunaan CPU dan meningkatkan kinerjanya. Mungkin menyebabkan gangguan atau crash pada beberapa game. Aktifkan Emulasi MMU Host 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. - Level DMA - 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. + Akurasi DMA + Mengontrol keakuratan presisi DMA. Presisi aman dapat memperbaiki masalah di beberapa game, tetapi juga dapat memengaruhi kinerja dalam beberapa kasus. Jika tidak yakin, biarkan ini pada Bawaan. 4GB (Direkomendasikan) 6GB (Tidak Aman) @@ -502,8 +502,6 @@ RTC Kustom Memungkinkan Anda untuk mengatur jam waktu nyata kustom yang terpisah dari waktu sistem saat ini Anda. Setel RTC Kustom - Nonaktifkan Verifikasi NCA - 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. Hasilkan @@ -864,9 +862,8 @@ Bawaan - Normal - Tinggi - Ekstrem + Tidak Aman (cepat) + Aman (stabil) 0.25X (180p/270p) @@ -914,13 +911,13 @@ Merentangkan - Dynamic (Lambat) + Dynarmic (JIT) Native code execution (NCE) Akurat Berbahaya - Paranoid (Slow) + Paranoid D Pad diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml index ff3706dd40..38a82b3c11 100644 --- a/src/android/app/src/main/res/values-it/strings.xml +++ b/src/android/app/src/main/res/values-it/strings.xml @@ -128,8 +128,8 @@ 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. Abilita emulazione MMU host 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. - Livello DMA - 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. + Precisione DMA + Controlla la precisione del DMA. La precisione sicura può risolvere problemi in alcuni giochi, ma in alcuni casi può anche influire sulle prestazioni. In caso di dubbi, lascia questo su Predefinito. 4GB (Consigliato) 6GB (Non sicuro) @@ -505,8 +505,6 @@ RTC Personalizzato Ti permette di impostare un orologio in tempo reale personalizzato, completamente separato da quello di sistema. Imposta un orologio in tempo reale personalizzato - Disabilita verifica NCA - 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+. Genera @@ -833,9 +831,8 @@ Predefinito - Normale - Alto - Estremo + Non sicuro (veloce) + Sicuro (stabile) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml index a6c1ebf8ab..0a873b04eb 100644 --- a/src/android/app/src/main/res/values-ja/strings.xml +++ b/src/android/app/src/main/res/values-ja/strings.xml @@ -128,8 +128,8 @@ メモリ更新時のCPU側キャッシュ無効化をスキップし、CPU使用率を減らして性能を向上させます。一部のゲームで不具合やクラッシュが発生する可能性があります。 ホストMMUエミュレーションを有効化 この最適化により、ゲストプログラムによるメモリアクセスが高速化されます。有効にすると、ゲストのメモリ読み書きが直接メモリ内で実行され、ホストのMMUを利用します。無効にすると、すべてのメモリアクセスでソフトウェアMMUエミュレーションが使用されます。 - DMAレベル - DMAの精度を制御します。精度を高くすると一部のゲームの問題が修正される場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、デフォルトのままにしてください。 + DMA精度 + DMAの精度を制御します。安全な精度は一部のゲームの問題を修正できる場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、これをデフォルトのままにしてください。 4GB (推奨) 6GB (安全でない) @@ -491,8 +491,6 @@ カスタム RTC 現在のシステム時間とは別に、任意のリアルタイムクロックを設定できます。 カスタムRTCを設定 - NCA検証を無効化 - NCAコンテンツアーカイブの整合性検証を無効にします。読み込み速度が向上する可能性がありますが、データ破損や不正なファイルが検出されないリスクがあります。ファームウェア20以上が必要なゲームや更新を動作させるために必要です。 生成 @@ -792,9 +790,8 @@ デフォルト - 標準 - 高 - 最高 + 安全でない(高速) + 安全(安定) 0.25X (180p/270p) @@ -837,13 +834,13 @@ 画面に合わせる - Dynarmic (低速) + Dynarmic (JIT) ネイティブコード実行 (NCE) 正確 不安定 - パラノイド (低速) + パラノイド 方向ボタン diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml index 01e2c5f4c0..e598bb1120 100644 --- a/src/android/app/src/main/res/values-ko/strings.xml +++ b/src/android/app/src/main/res/values-ko/strings.xml @@ -128,8 +128,8 @@ 메모리 업데이트 시 일부 CPU 측 캐시 무효화를 건너뛰어 CPU 사용량을 줄이고 성능을 향상시킵니다. 일부 게임에서 오류 또는 충돌을 일으킬 수 있습니다. 호스트 MMU 에뮬레이션 사용 이 최적화는 게스트 프로그램의 메모리 접근 속도를 높입니다. 활성화하면 게스트의 메모리 읽기/쓰기가 메모리에서 직접 수행되고 호스트의 MMU를 활용합니다. 비활성화하면 모든 메모리 접근에 소프트웨어 MMU 에뮬레이션을 사용하게 됩니다. - DMA 수준 - DMA 정밀도를 제어합니다. 높은 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않다면 기본값으로 두세요. + DMA 정확도 + DMA 정밀도 정확도를 제어합니다. 안전한 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않은 경우 기본값으로 두십시오. 4GB (권장) 6GB (안전하지 않음) @@ -501,8 +501,6 @@ 사용자 지정 RTC 현재 시스템 시간과 별도로 사용자 지정 RTC를 설정할 수 있습니다. 사용자 지정 RTC 설정 - NCA 검증 비활성화 - NCA 콘텐츠 아카이브의 무결성 검증을 비활성화합니다. 로딩 속도를 향상시킬 수 있지만 데이터 손상이나 유효하지 않은 파일이 미검증될 위험이 있습니다. 펌웨어 20+가 필요한 게임 및 업데이트를 실행하려면 필요합니다. 생성 @@ -863,9 +861,8 @@ 기본값 - 보통 - 높음 - 극단적 + 안전하지 않음(빠름) + 안전함(안정적) 0.25X (180p/270p) @@ -913,13 +910,13 @@ 화면에 맞춤 - Dynarmic (느림) + Dynarmic (JIT) 네이티브 코드 실행 (NCE) 정확함 최적화 (안전하지 않음) - 최적화하지 않음 (느림) + 최적화하지 않음 십자키 diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml index 90c0dbf05e..7f0cffc7c4 100644 --- a/src/android/app/src/main/res/values-nb/strings.xml +++ b/src/android/app/src/main/res/values-nb/strings.xml @@ -128,8 +128,8 @@ Hopper over enkelte CPU-side cache-invalideringer under minneoppdateringer, reduserer CPU-bruk og forbedrer ytelsen. Kan forårsake feil eller krasj i noen spill. Aktiver verts-MMU-emulering 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. - DMA-nivå - 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. + DMA-nøyaktighet + Kontrollerer DMA-presisjonsnøyaktigheten. Sikker presisjon kan fikse problemer i noen spill, men kan også påvirke ytelsen i noen tilfeller. Hvis du er usikker, la dette stå på Standard. 4GB (Anbefalt) 6GB (Usikkert) @@ -482,8 +482,6 @@ Tilpasset Sannhetstidsklokke Gjør det mulig å stille inn en egendefinert sanntidsklokke separat fra den gjeldende systemtiden. Angi tilpasset RTC - Deaktiver NCA-verifisering - 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. Generer @@ -773,9 +771,8 @@ Standard - Normal - Høy - Ekstrem + Usikker (rask) + Sikker (stabil) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml index 080064edaf..de9b8f47fc 100644 --- a/src/android/app/src/main/res/values-pl/strings.xml +++ b/src/android/app/src/main/res/values-pl/strings.xml @@ -128,8 +128,8 @@ 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. Włącz emulację MMU hosta 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. - Poziom DMA - 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». + Dokładność DMA + Kontroluje dokładność precyzji DMA. Bezpieczna precyzja może naprawić problemy w niektórych grach, ale w niektórych przypadkach może również wpłynąć na wydajność. Jeśli nie jesteś pewien, pozostaw wartość Domyślną. 4GB (Zalecane) 6GB (Niebezpieczne) @@ -482,8 +482,6 @@ Niestandardowy RTC Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android. Ustaw niestandardowy czas RTC - Wyłącz weryfikację NCA - 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+. Generuj @@ -770,9 +768,8 @@ 預設 - 普通 - 高 - 極高 + Niezabezpieczone (szybkie) + Bezpieczne (stabilne) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml index 3dc1f83e6e..5571c2aea4 100644 --- a/src/android/app/src/main/res/values-pt-rBR/strings.xml +++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml @@ -128,8 +128,8 @@ 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. Ativar Emulação de MMU do Host 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. - Nível DMA - 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. + Precisão de DMA + Controla a precisão do DMA. A precisão segura pode corrigir problemas em alguns jogos, mas também pode afetar o desempenho em alguns casos. Se não tiver certeza, deixe isso como Padrão. 4GB (Recomendado) 6GB (Inseguro) @@ -506,8 +506,6 @@ Data e hora personalizadas Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo. Definir um relógio em tempo real personalizado - Desativar verificação NCA - 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. Gerar @@ -921,9 +919,8 @@ uma tentativa de mapeamento automático Padrão - Normal - Alto - Extremo + Inseguro (rápido) + Seguro (estável) 0.25X (180p/270p) @@ -971,13 +968,13 @@ uma tentativa de mapeamento automático Esticar à janela - Dynarmic (Lenta) + Dynarmic (JIT) Execução de código nativo (NCE) Precisa Não segura - Paranoica (Lenta) + Paranoica Botões Direcionais diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml index feb4950fcb..81aa7e92c0 100644 --- a/src/android/app/src/main/res/values-pt-rPT/strings.xml +++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml @@ -128,8 +128,8 @@ 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. Ativar Emulação de MMU do Anfitrião 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. - Nível DMA - 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. + Precisão da DMA + Controla a precisão da DMA. A precisão segura pode resolver problemas em alguns jogos, mas também pode afetar o desempenho nalguns casos. Se não tiver a certeza, deixe esta opção em Predefinido. 4GB (Recomendado) 6GB (Inseguro) @@ -506,8 +506,6 @@ RTC personalizado Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo. Defina um relógio em tempo real personalizado - Desativar verificação NCA - 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. Gerar @@ -921,9 +919,8 @@ uma tentativa de mapeamento automático Predefinido - Normal - Alto - Extremo + Inseguro (rápido) + Seguro (estável) 0.25X (180p/270p) @@ -971,13 +968,13 @@ uma tentativa de mapeamento automático Esticar à janela - Dynarmic (Lento) + Dynarmic (JIT) Native code execution (NCE) Preciso Inseguro - Paranoid (Lento) + Paranoid Botões Direcionais diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml index d56c94f10b..eee249c44a 100644 --- a/src/android/app/src/main/res/values-ru/strings.xml +++ b/src/android/app/src/main/res/values-ru/strings.xml @@ -128,8 +128,8 @@ Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх. Включить эмуляцию MMU хоста Эта оптимизация ускоряет доступ к памяти гостевой программой. При включении операции чтения/записи памяти гостя выполняются напрямую в памяти с использованием MMU хоста. Отключение заставляет все обращения к памяти использовать программную эмуляцию MMU. - Уровень DMA - Управляет точностью DMA. Более высокий уровень может исправить проблемы в некоторых играх, но также может повлиять на производительность. Если не уверены, оставьте значение «По умолчанию». + Точность DMA + Управляет точностью DMA. Безопасная точность может исправить проблемы в некоторых играх, но в некоторых случаях также может повлиять на производительность. Если не уверены, оставьте значение По умолчанию. 4 ГБ (Рекомендуется) 6 ГБ (Небезопасно) @@ -508,8 +508,6 @@ Пользовательский RTC Позволяет установить пользовательские часы реального времени отдельно от текущего системного времени. Установить пользовательский RTC - Отключить проверку NCA - Отключает проверку целостности архивов содержимого NCA. Может улучшить скорость загрузки, но есть риск повреждения данных или того, что недействительные файлы останутся незамеченными. Необходимо для работы игр и обновлений, требующих прошивку 20+. Создать @@ -922,9 +920,8 @@ По умолчанию - Нормальный - Высокий - Экстремальный + Небезопасно (быстро) + Безопасно (стабильно) 0.25X (180p/270p) @@ -958,7 +955,7 @@ Авто Альбомная (сенсор) - Пейзаж + Альбомная Обратная альбомная Портретная (сенсор) Портрет @@ -972,13 +969,13 @@ Растянуть до окна - Dynarmic (Медленно) + Dynarmic (JIT) Нативное выполнение (NCE) Точно Небезопасно - Параноик (медленно) + Параноик Крестовина diff --git a/src/android/app/src/main/res/values-sr/strings.xml b/src/android/app/src/main/res/values-sr/strings.xml index 5b444f6187..b123757f5a 100644 --- a/src/android/app/src/main/res/values-sr/strings.xml +++ b/src/android/app/src/main/res/values-sr/strings.xml @@ -121,8 +121,8 @@ 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. Омогући емулацију MMU домаћина Ова оптимизација убрзава приступ меморији од стране гостујућег програма. Укључивање изазива да се читања/уписа меморије госта обављају директно у меморији и користе MMU домаћина. Искључивање присиљава све приступе меморији да користе софтверску емулацију MMU. - DMA ниво - Контролише тачност DMA прецизности. Виши ниво може да поправи проблеме у неким играма, али може и да утиче на перформансе. Ако нисте сигурни, оставите на «Подразумевано». + DMA тачност + Управља прецизношћу DMA-а. Сигурна прецизност може да исправи проблеме у неким играма, али у неким случајевима може да утиче и на перформансе. Ако нисте сигурни, оставите ово на Подразумевано. Схадер Бацкенд @@ -457,8 +457,6 @@ Цустом РТЦ Омогућава вам да поставите прилагођени сат у реалном времену одвојено од тренутног времена система. Подесите прилагођени РТЦ - Искључи верификацију НЦА - Искључује верификацију интегритета НЦА архива садржаја. Ово може побољшати брзину учитавања, али ризикује оштећење података или да неважећи фајлови прођу незапажено. Неопходно је да би игре и ажурирања која захтевају firmware 20+ радили. Генериши @@ -917,9 +915,8 @@ Подразумевано - Нормално - Високо - Екстремно + Небезбедно (брзо) + Безбедно (стабилно) АСТЦ метода декодирања @@ -991,13 +988,13 @@ Протезање до прозора - Динамина (споро) + Dynarmic (JIT) Извођење изворног кода (НЦЕ) Тачан Несигуран - Параноичан (споро) + Параноичан Д-пад diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml index 4ae61340dc..2222402a25 100644 --- a/src/android/app/src/main/res/values-uk/strings.xml +++ b/src/android/app/src/main/res/values-uk/strings.xml @@ -128,8 +128,8 @@ Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх. Увімкнути емуляцію MMU хоста Ця оптимізація пришвидшує доступ до пам\'яті гостьовою програмою. Увімкнення призводить до того, що читання/запис пам\'яті гостя виконуються безпосередньо в пам\'яті та використовують MMU хоста. Вимкнення змушує всі звернення до пам\'яті використовувати програмну емуляцію MMU. - Рівень DMA - Керує точністю DMA. Вищий рівень може виправити проблеми в деяких іграх, але також може вплинути на продуктивність. Якщо не впевнені, залиште значення «Типово». + Точність DMA + Керує точністю DMA. Безпечна точність може виправити проблеми в деяких іграх, але в деяких випадках також може вплинути на продуктивність. Якщо не впевнені, залиште це значення за замовчуванням. 4 ГБ (Рекомендовано) 6 ГБ (Небезпечно) @@ -495,8 +495,6 @@ Свій RTC Дозволяє встановити власний час (Real-time clock, або RTC), відмінний від системного. Встановити RTC - Вимкнути перевірку NCA - Вимкає перевірку цілісності архівів вмісту NCA. Може покращити швидкість завантаження, але ризикує пошкодженням даних або тим, що недійсні файли залишаться непоміченими. Необхідно для роботи ігор та оновлень, які вимагають прошивки 20+. Створити @@ -811,9 +809,8 @@ Типово - Нормальний - Високий - Екстремальний + Небезпечно (швидко) + Безпечно (стабільно) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-vi/strings.xml b/src/android/app/src/main/res/values-vi/strings.xml index dd64fbca55..784b2dec14 100644 --- a/src/android/app/src/main/res/values-vi/strings.xml +++ b/src/android/app/src/main/res/values-vi/strings.xml @@ -128,8 +128,8 @@ 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. Bật giả lập MMU Máy chủ 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. - Cấp độ DMA - Đ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. + Độ chính xác DMA + Điều khiển độ chính xác của DMA. Độ chính xác an toàn có thể khắc phục sự cố trong một số trò chơi, nhưng trong một số trường hợp cũng có thể ảnh hưởng đến hiệu suất. Nếu không chắc chắn, hãy để giá trị này ở Mặc định. 4GB (Được đề xuất) 6GB (Không an toàn) @@ -482,8 +482,6 @@ RTC tuỳ chỉnh 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. Thiết lập RTC tùy chỉnh - Tắt xác minh NCA - 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. Tạo @@ -776,9 +774,8 @@ Mặc định - Bình thường - Cao - Cực cao + Không an toàn (nhanh) + An toàn (ổn định) 0.25X (180p/270p) diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml index a12c00063f..5cf657ef3d 100644 --- a/src/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml @@ -127,8 +127,8 @@ 在内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。 启用主机 MMU 模拟 此优化可加速来宾程序的内存访问。启用后,来宾内存读取/写入将直接在内存中执行并利用主机的 MMU。禁用此功能将强制所有内存访问使用软件 MMU 模拟。 - DMA 级别 - 控制 DMA 精度。更高的精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。 + DMA 精度 + 控制 DMA 精度。安全精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。 4GB (推荐) 6GB (不安全) @@ -500,8 +500,6 @@ 自定义系统时间 此选项允许您设置与目前系统时间相独立的自定义系统时钟。 设置自定义系统时间 -禁用NCA验证 -禁用NCA内容存档的完整性验证。可能会提高加载速度,但存在数据损坏或无效文件未被检测到的风险。对于需要固件20+的游戏和更新是必需的。 生成 @@ -914,9 +912,8 @@ 默认 - 普通 - 高 - 极高 + 不安全(快速) + 安全(稳定) 0.25X (180p/270p) @@ -964,13 +961,13 @@ 拉伸窗口 - 动态编译 (慢速) + Dynarmic (JIT) 本机代码执行 (NCE) 高精度 低精度 - 偏执模式 (慢速) + 偏执模式 十字方向键 diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml index a125553102..f4d690dbaa 100644 --- a/src/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml @@ -120,8 +120,8 @@ 在記憶體更新期間跳過某些CPU端快取無效化,減少CPU使用率並提高其性能。可能會導致某些遊戲出現故障或崩潰。 啟用主機 MMU 模擬 此最佳化可加速來賓程式的記憶體存取。啟用後,來賓記憶體讀取/寫入將直接在記憶體中執行並利用主機的 MMU。停用此功能將強制所有記憶體存取使用軟體 MMU 模擬。 - DMA 級別 - 控制 DMA 精確度。更高的精確度可以修復某些遊戲中的問題,但在某些情況下也可能影響效能。如果不確定,請保留為「預設」。 + DMA 精度 + 控制 DMA 精度。安全精度可以修復某些遊戲中的問題,但在某些情況下也可能影響效能。如果不確定,請保留為「預設」。 4GB (推薦) @@ -505,8 +505,6 @@ 自訂 RTC 允許您設定與您的目前系統時間相互獨立的自訂即時時鐘。 設定自訂 RTC - 停用NCA驗證 - 停用NCA內容存檔的完整性驗證。可能會提高載入速度,但存在資料損毀或無效檔案未被偵測到的風險。對於需要韌體20+的遊戲和更新是必需的。 生成 @@ -919,9 +917,8 @@ 預設 - 普通 - 高 - 極高 + 不安全(快速) + 安全(穩定) 0.25X (180p/270p) @@ -969,13 +966,13 @@ 延展視窗 - 動態 (慢) + Dynarmic (JIT) 機器碼執行 (NCE) 高精度 低精度 - 不合理 (慢) + 不合理 方向鍵 diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 2f0392675d..08ca53ad81 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -454,15 +454,13 @@ @string/dma_accuracy_default - @string/dma_accuracy_normal - @string/dma_accuracy_high - @string/dma_accuracy_extreme + @string/dma_accuracy_unsafe + @string/dma_accuracy_safe 0 1 2 - 3 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 2c7923d5a3..3b76c0ba79 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -115,8 +115,8 @@ Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock. Memory Layout (EXPERIMENTAL) Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Only works on the Dynarmic (JIT) backend. - DMA Level - Controls the DMA precision accuracy. Higher precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave it at Default. + DMA Accuracy + Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default. Shader Backend @@ -266,6 +266,7 @@ Alphabetical List Grid + Compact Grid Carousel Screenshot for %1$s Folder @@ -474,8 +475,6 @@ Custom RTC Allows you to set a custom real-time clock separate from your current system time. Set custom RTC - Disable NCA Verification - 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. Generate @@ -784,9 +783,6 @@ Game Requires Firmware dump and install firmware, or press "OK" to launch anyways.]]> - NCA Verification Disabled - 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. - Searching for game... Game not found for Title ID: %1$s @@ -944,9 +940,8 @@ Default - Normal - High - Extreme + Unsafe (fast) + Safe (stable) ASTC Decoding Method @@ -1019,13 +1014,13 @@ Stretch to window - Dynarmic (Slow) + Dynarmic (JIT) Native code execution (NCE) Accurate Unsafe - Paranoid (Slow) + Paranoid D-pad diff --git a/src/audio_core/common/common.h b/src/audio_core/common/common.h index eaf0c6470f..f1c35ad60f 100644 --- a/src/audio_core/common/common.h +++ b/src/audio_core/common/common.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/device/audio_buffers.h b/src/audio_core/device/audio_buffers.h index 9016246fbf..0ee3225bf6 100644 --- a/src/audio_core/device/audio_buffers.h +++ b/src/audio_core/device/audio_buffers.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/audio_device.cpp b/src/audio_core/renderer/audio_device.cpp index 387d23b0b4..b5092f023a 100644 --- a/src/audio_core/renderer/audio_device.cpp +++ b/src/audio_core/renderer/audio_device.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/behavior/behavior_info.cpp b/src/audio_core/renderer/behavior/behavior_info.cpp index f139e63ffb..d0df1f29de 100644 --- a/src/audio_core/renderer/behavior/behavior_info.cpp +++ b/src/audio_core/renderer/behavior/behavior_info.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/command_buffer.cpp b/src/audio_core/renderer/command/command_buffer.cpp index f9e8575691..d680e0c74b 100644 --- a/src/audio_core/renderer/command/command_buffer.cpp +++ b/src/audio_core/renderer/command/command_buffer.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/command_generator.h b/src/audio_core/renderer/command/command_generator.h index 497cfa92f2..b74ad525ae 100644 --- a/src/audio_core/renderer/command/command_generator.h +++ b/src/audio_core/renderer/command/command_generator.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/data_source/decode.cpp b/src/audio_core/renderer/command/data_source/decode.cpp index b42ecb961f..5a97aadad4 100644 --- a/src/audio_core/renderer/command/data_source/decode.cpp +++ b/src/audio_core/renderer/command/data_source/decode.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/effect/aux_.cpp b/src/audio_core/renderer/command/effect/aux_.cpp index cb23007a66..5cee02a55c 100644 --- a/src/audio_core/renderer/command/effect/aux_.cpp +++ b/src/audio_core/renderer/command/effect/aux_.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/effect/biquad_filter.cpp b/src/audio_core/renderer/command/effect/biquad_filter.cpp index dbc7085d16..539e0c6370 100644 --- a/src/audio_core/renderer/command/effect/biquad_filter.cpp +++ b/src/audio_core/renderer/command/effect/biquad_filter.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/effect/capture.cpp b/src/audio_core/renderer/command/effect/capture.cpp index 95bc88e464..4267580128 100644 --- a/src/audio_core/renderer/command/effect/capture.cpp +++ b/src/audio_core/renderer/command/effect/capture.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp b/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp index 14e77b3cb2..6c3dd7986a 100644 --- a/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp +++ b/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/effect/light_limiter.cpp b/src/audio_core/renderer/command/effect/light_limiter.cpp index 3488dd37b5..7f0455461f 100644 --- a/src/audio_core/renderer/command/effect/light_limiter.cpp +++ b/src/audio_core/renderer/command/effect/light_limiter.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/effect/reverb.cpp b/src/audio_core/renderer/command/effect/reverb.cpp index 67b893305a..cc61cd6ad6 100644 --- a/src/audio_core/renderer/command/effect/reverb.cpp +++ b/src/audio_core/renderer/command/effect/reverb.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp b/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp index f80fb92631..5c062b2e9c 100644 --- a/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp +++ b/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/resample/upsample.cpp b/src/audio_core/renderer/command/resample/upsample.cpp index add975504c..71d865264a 100644 --- a/src/audio_core/renderer/command/resample/upsample.cpp +++ b/src/audio_core/renderer/command/resample/upsample.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/sink/circular_buffer.cpp b/src/audio_core/renderer/command/sink/circular_buffer.cpp index 8ef48a26df..b2d4ccfcd8 100644 --- a/src/audio_core/renderer/command/sink/circular_buffer.cpp +++ b/src/audio_core/renderer/command/sink/circular_buffer.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/command/sink/device.cpp b/src/audio_core/renderer/command/sink/device.cpp index 86a257363b..16b1bd7467 100644 --- a/src/audio_core/renderer/command/sink/device.cpp +++ b/src/audio_core/renderer/command/sink/device.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/mix/mix_context.cpp b/src/audio_core/renderer/mix/mix_context.cpp index 1103af910b..0253556eb8 100644 --- a/src/audio_core/renderer/mix/mix_context.cpp +++ b/src/audio_core/renderer/mix/mix_context.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/sink/sink_info_base.h b/src/audio_core/renderer/sink/sink_info_base.h index 2a7fd81f68..b368f7ba48 100644 --- a/src/audio_core/renderer/sink/sink_info_base.h +++ b/src/audio_core/renderer/sink/sink_info_base.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/splitter/splitter_context.cpp b/src/audio_core/renderer/splitter/splitter_context.cpp index 583cbaf735..fb118e981e 100644 --- a/src/audio_core/renderer/splitter/splitter_context.cpp +++ b/src/audio_core/renderer/splitter/splitter_context.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index c4a2768b93..2053ec6dd4 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/common/free_region_manager.h b/src/common/free_region_manager.h index 39d52f866c..913668b291 100644 --- a/src/common/free_region_manager.h +++ b/src/common/free_region_manager.h @@ -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 diff --git a/src/common/heap_tracker.cpp b/src/common/heap_tracker.cpp index 7cce54976e..a99d386d8a 100644 --- a/src/common/heap_tracker.cpp +++ b/src/common/heap_tracker.cpp @@ -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 diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 1b7532b6b9..2e36d59569 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -598,12 +598,17 @@ public: bool ClearBackingRegion(size_t physical_offset, size_t length) { #ifdef __linux__ - // Set MADV_REMOVE on backing map to destroy it instantly. - // This also deletes the area from the backing file. - int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE); - ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno)); - - return true; + // Only incur syscall cost IF memset would be slower (theshold = 16MiB) + // TODO(lizzie): Smarter way to dynamically get this threshold (broadwell != raptor lake) for example + if (length >= 2097152UL * 8) { + // Set MADV_REMOVE on backing map to destroy it instantly. + // This also deletes the area from the backing file. + int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE); + ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno)); + return true; + } else { + return false; + } #else return false; #endif diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 252c83aa2c..bd7a7d7f49 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -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 diff --git a/src/common/math_util.h b/src/common/math_util.h index f52a0a35ae..967d755f53 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h @@ -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 diff --git a/src/common/overflow.h b/src/common/overflow.h index d39fa24041..5f048de7e6 100644 --- a/src/common/overflow.h +++ b/src/common/overflow.h @@ -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 diff --git a/src/common/range_map.h b/src/common/range_map.h index e9cb50825b..1ea29897c9 100644 --- a/src/common/range_map.h +++ b/src/common/range_map.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in index a157d03878..1630ceae83 100644 --- a/src/common/scm_rev.cpp.in +++ b/src/common/scm_rev.cpp.in @@ -6,8 +6,8 @@ #include "common/scm_rev.h" -#define GIT_REV "@GIT_REV@" -#define GIT_BRANCH "@GIT_BRANCH@" +#define GIT_REV "@GIT_COMMIT@" +#define GIT_BRANCH "@GIT_REFSPEC@" #define GIT_DESC "@GIT_DESC@" #define BUILD_NAME "@REPO_NAME@" #define BUILD_DATE "@BUILD_DATE@" @@ -31,7 +31,7 @@ constexpr const char g_build_version[] = BUILD_VERSION; constexpr const char g_build_id[] = BUILD_ID; constexpr const char g_title_bar_format_idle[] = TITLE_BAR_FORMAT_IDLE; constexpr const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING; -constexpr const bool g_is_dev_build = IS_DEV_BUILD; constexpr const char g_compiler_id[] = COMPILER_ID; +constexpr const bool g_is_dev_build = IS_DEV_BUILD; } // namespace Common diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index 84356ad64a..8f48241557 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: 2014 Citra Emulator Project @@ -19,7 +19,7 @@ extern const char g_build_id[]; extern const char g_title_bar_format_idle[]; extern const char g_title_bar_format_running[]; extern const char g_shader_cache_version[]; -extern const bool g_is_dev_build; extern const char g_compiler_id[]; +extern const bool g_is_dev_build; } // namespace Common diff --git a/src/common/settings.cpp b/src/common/settings.cpp index d4f16f4853..b41f4c75f5 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -154,11 +154,19 @@ bool IsGPULevelHigh() { values.current_gpu_accuracy == GpuAccuracy::High; } +bool IsDMALevelDefault() { + return values.dma_accuracy.GetValue() == DmaAccuracy::Default; +} + +bool IsDMALevelSafe() { + return values.dma_accuracy.GetValue() == DmaAccuracy::Safe; +} + bool IsFastmemEnabled() { if (values.cpu_debug_mode) { return static_cast(values.cpuopt_fastmem); } - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { + if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) { return static_cast(values.cpuopt_unsafe_host_mmu); } #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) diff --git a/src/common/settings.h b/src/common/settings.h index 9d448a2b38..8605445837 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -443,7 +443,7 @@ struct Values { SwitchableSetting dma_accuracy{linkage, DmaAccuracy::Default, DmaAccuracy::Default, - DmaAccuracy::Extreme, + DmaAccuracy::Safe, "dma_accuracy", Category::RendererAdvanced, Specialization::Default, @@ -626,10 +626,6 @@ struct Values { true, true, &rng_seed_enabled}; Setting device_name{ linkage, "Eden", "device_name", Category::System, Specialization::Default, true, true}; - SwitchableSetting disable_nca_verification{linkage, true, "disable_nca_verification", - Category::System, Specialization::Default}; - Setting hide_nca_verification_popup{ - linkage, false, "hide_nca_verification_popup", Category::System, Specialization::Default}; Setting current_user{linkage, 0, "current_user", Category::System}; @@ -787,6 +783,9 @@ void UpdateGPUAccuracy(); bool IsGPULevelExtreme(); bool IsGPULevelHigh(); +bool IsDMALevelDefault(); +bool IsDMALevelSafe(); + bool IsFastmemEnabled(); void SetNceEnabled(bool is_64bit); bool IsNceEnabled(); diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 52b4a128f7..ebfa4ceb9e 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -136,7 +136,7 @@ ENUM(ShaderBackend, Glsl, Glasm, SpirV); ENUM(GpuAccuracy, Normal, High, Extreme); -ENUM(DmaAccuracy, Default, Normal, High, Extreme); +ENUM(DmaAccuracy, Default, Unsafe, Safe); ENUM(CpuBackend, Dynarmic, Nce); @@ -166,7 +166,7 @@ ENUM(ResolutionSetup, Res7X, Res8X); -ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, ScaleForce, Fsr, Area, MaxEnum); +ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum); ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h index ce7a3e91a6..0aba2e11c9 100644 --- a/src/common/settings_setting.h +++ b/src/common/settings_setting.h @@ -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 diff --git a/src/common/slot_vector.h b/src/common/slot_vector.h index 8db4bba30b..3fabec9852 100644 --- a/src/common/slot_vector.h +++ b/src/common/slot_vector.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/common/tiny_mt.h b/src/common/tiny_mt.h index a757591c9b..c9f9ed4a5d 100644 --- a/src/common/tiny_mt.h +++ b/src/common/tiny_mt.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/common/uint128.h b/src/common/uint128.h index 56433096fe..3d142d7f83 100644 --- a/src/common/uint128.h +++ b/src/common/uint128.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/common/x64/cpu_wait.cpp b/src/common/x64/cpu_wait.cpp index b578d75ece..12f2e9d4b1 100644 --- a/src/common/x64/cpu_wait.cpp +++ b/src/common/x64/cpu_wait.cpp @@ -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 diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1e8e4ec07a..6b64ab7820 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -107,9 +107,6 @@ 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 file_sys/fssystem/fssystem_sparse_storage.h file_sys/fssystem/fssystem_switch_storage.h @@ -1200,7 +1197,7 @@ else() target_link_libraries(core PUBLIC Boost::headers) endif() -target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API mbedtls mbedcrypto) +target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto MbedTLS::mbedtls) if (MINGW) target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY}) endif() diff --git a/src/core/arm/debug.cpp b/src/core/arm/debug.cpp index 20f1ea00df..3049ea0be1 100644 --- a/src/core/arm/debug.cpp +++ b/src/core/arm/debug.cpp @@ -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 diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 2c2c54a1ad..d2035d0fe0 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -305,7 +305,7 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; } - // Paranoid mode for debugging optimizations + // Paranoia mode for debugging optimizations if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { config.unsafe_optimizations = false; config.optimizations = Dynarmic::no_optimizations; diff --git a/src/core/arm/dynarmic/dynarmic_cp15.cpp b/src/core/arm/dynarmic/dynarmic_cp15.cpp index 0d5e5912ae..e3e2d8339d 100644 --- a/src/core/arm/dynarmic/dynarmic_cp15.cpp +++ b/src/core/arm/dynarmic/dynarmic_cp15.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/arm/nce/interpreter_visitor.h b/src/core/arm/nce/interpreter_visitor.h index 9dfbdb2fe9..daae204310 100644 --- a/src/core/arm/nce/interpreter_visitor.h +++ b/src/core/arm/nce/interpreter_visitor.h @@ -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-FileCopyrightText: Copyright 2023 merryhime // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h index c2fd587a73..7cc672635e 100644 --- a/src/core/crypto/aes_util.h +++ b/src/core/crypto/aes_util.h @@ -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 @@ -16,7 +19,7 @@ struct CipherContext; enum class Mode { CTR = 11, ECB = 2, - XTS = 70, + XTS = 74, }; enum class Op { diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 04b75d5e8f..6d0b32ba70 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -539,7 +539,7 @@ static std::array MGF1(const std::array& seed) { while (out.size() < target_size) { out.resize(out.size() + 0x20); seed_exp[in_size + 3] = static_cast(i); - mbedtls_sha256_ret(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0); + mbedtls_sha256(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0); ++i; } diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 4b45e72c43..8e4fc2e595 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -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 @@ -178,7 +181,7 @@ std::array FindKeyFromHex(const std::vector& binary, std::array temp{}; for (size_t i = 0; i < binary.size() - key_size; ++i) { - mbedtls_sha256_ret(binary.data() + i, key_size, temp.data(), 0); + mbedtls_sha256(binary.data() + i, key_size, temp.data(), 0); if (temp != hash) continue; @@ -206,7 +209,7 @@ static std::array FindEncryptedMasterKeyFromHex(const std::vector< AESCipher cipher(key, Mode::ECB); for (size_t i = 0; i < binary.size() - 0x10; ++i) { cipher.Transcode(binary.data() + i, dec_temp.size(), dec_temp.data(), Op::Decrypt); - mbedtls_sha256_ret(dec_temp.data(), dec_temp.size(), temp.data(), 0); + mbedtls_sha256(dec_temp.data(), dec_temp.size(), temp.data(), 0); for (size_t k = 0; k < out.size(); ++k) { if (temp == master_key_hashes[k]) { diff --git a/src/core/crypto/xts_encryption_layer.cpp b/src/core/crypto/xts_encryption_layer.cpp index 34e58463de..36cc501b90 100644 --- a/src/core/crypto/xts_encryption_layer.cpp +++ b/src/core/crypto/xts_encryption_layer.cpp @@ -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 diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index 460e0d19b4..1c86b38bf5 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 5c3c045b3c..16c42bf175 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/debugger/gdbstub_arch.cpp b/src/core/debugger/gdbstub_arch.cpp index ee7108376a..fec75c3432 100644 --- a/src/core/debugger/gdbstub_arch.cpp +++ b/src/core/debugger/gdbstub_arch.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index b961cdb096..6c413c2dfb 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -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 diff --git a/src/core/file_sys/fs_path_utility.h b/src/core/file_sys/fs_path_utility.h index 3af23b0bba..d0060c4fc6 100644 --- a/src/core/file_sys/fs_path_utility.h +++ b/src/core/file_sys/fs_path_utility.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/fsa/fs_i_directory.h b/src/core/file_sys/fsa/fs_i_directory.h index a4adcd2beb..8f28314860 100644 --- a/src/core/file_sys/fsa/fs_i_directory.h +++ b/src/core/file_sys/fsa/fs_i_directory.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/fsa/fs_i_file.h b/src/core/file_sys/fsa/fs_i_file.h index 99468ef0e2..8b70185522 100644 --- a/src/core/file_sys/fsa/fs_i_file.h +++ b/src/core/file_sys/fsa/fs_i_file.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.cpp b/src/core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.cpp index c9fb5f64d6..506624669b 100644 --- a/src/core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.cpp +++ b/src/core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.cpp @@ -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 diff --git a/src/core/file_sys/fssystem/fssystem_aes_ctr_storage.cpp b/src/core/file_sys/fssystem/fssystem_aes_ctr_storage.cpp index c18fde18f4..aaf7788801 100644 --- a/src/core/file_sys/fssystem/fssystem_aes_ctr_storage.cpp +++ b/src/core/file_sys/fssystem/fssystem_aes_ctr_storage.cpp @@ -1,10 +1,12 @@ +// 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/alignment.h" #include "common/swap.h" #include "core/file_sys/fssystem/fssystem_aes_ctr_storage.h" -#include "core/file_sys/fssystem/fssystem_pooled_buffer.h" #include "core/file_sys/fssystem/fssystem_utility.h" namespace FileSys { @@ -76,13 +78,6 @@ size_t AesCtrStorage::Write(const u8* buffer, size_t size, size_t offset) { ASSERT(Common::IsAligned(offset, BlockSize)); ASSERT(Common::IsAligned(size, BlockSize)); - // Get a pooled buffer. - PooledBuffer pooled_buffer; - const bool use_work_buffer = true; - if (use_work_buffer) { - pooled_buffer.Allocate(size, BlockSize); - } - // Setup the counter. std::array ctr; std::memcpy(ctr.data(), m_iv.data(), IvSize); @@ -91,25 +86,20 @@ size_t AesCtrStorage::Write(const u8* buffer, size_t size, size_t offset) { // Loop until all data is written. size_t remaining = size; s64 cur_offset = 0; + + // Get a pooled buffer. + std::vector pooled_buffer(BlockSize); while (remaining > 0) { // Determine data we're writing and where. - const size_t write_size = - use_work_buffer ? (std::min)(pooled_buffer.GetSize(), remaining) : remaining; - - void* write_buf; - if (use_work_buffer) { - write_buf = pooled_buffer.GetBuffer(); - } else { - write_buf = const_cast(buffer); - } + const size_t write_size = std::min(pooled_buffer.size(), remaining); + u8* write_buf = reinterpret_cast(pooled_buffer.data()); // Encrypt the data. m_cipher->SetIV(ctr); - m_cipher->Transcode(buffer, write_size, reinterpret_cast(write_buf), - Core::Crypto::Op::Encrypt); + m_cipher->Transcode(buffer, write_size, write_buf, Core::Crypto::Op::Encrypt); // Write the encrypted data. - m_base_storage->Write(reinterpret_cast(write_buf), write_size, offset + cur_offset); + m_base_storage->Write(write_buf, write_size, offset + cur_offset); // Advance. cur_offset += write_size; diff --git a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp index 5ef2544dfb..9e7a104c89 100644 --- a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp +++ b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp @@ -1,11 +1,12 @@ +// 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/alignment.h" #include "common/swap.h" -#include "core/file_sys/errors.h" #include "core/file_sys/fssystem/fssystem_aes_xts_storage.h" -#include "core/file_sys/fssystem/fssystem_pooled_buffer.h" #include "core/file_sys/fssystem/fssystem_utility.h" namespace FileSys { @@ -69,17 +70,14 @@ size_t AesXtsStorage::Read(u8* buffer, size_t size, size_t offset) const { // Decrypt into a pooled buffer. { - PooledBuffer tmp_buf(m_block_size, m_block_size); - ASSERT(tmp_buf.GetSize() >= m_block_size); - - std::memset(tmp_buf.GetBuffer(), 0, skip_size); - std::memcpy(tmp_buf.GetBuffer() + skip_size, buffer, data_size); + std::vector tmp_buf(m_block_size, 0); + std::memcpy(tmp_buf.data() + skip_size, buffer, data_size); m_cipher->SetIV(ctr); - m_cipher->Transcode(tmp_buf.GetBuffer(), m_block_size, tmp_buf.GetBuffer(), + m_cipher->Transcode(tmp_buf.data(), m_block_size, tmp_buf.data(), Core::Crypto::Op::Decrypt); - std::memcpy(buffer, tmp_buf.GetBuffer() + skip_size, data_size); + std::memcpy(buffer, tmp_buf.data() + skip_size, data_size); } AddCounter(ctr.data(), IvSize, 1); diff --git a/src/core/file_sys/fssystem/fssystem_alignment_matching_storage.h b/src/core/file_sys/fssystem/fssystem_alignment_matching_storage.h index f96691d03d..60a6d24435 100644 --- a/src/core/file_sys/fssystem/fssystem_alignment_matching_storage.h +++ b/src/core/file_sys/fssystem/fssystem_alignment_matching_storage.h @@ -1,13 +1,14 @@ +// 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 "common/alignment.h" -#include "core/file_sys/errors.h" #include "core/file_sys/fssystem/fs_i_storage.h" #include "core/file_sys/fssystem/fssystem_alignment_matching_storage_impl.h" -#include "core/file_sys/fssystem/fssystem_pooled_buffer.h" namespace FileSys { @@ -89,10 +90,11 @@ private: VirtualFile m_base_storage; s64 m_base_storage_size; size_t m_data_align; + mutable std::vector work_buffer; public: explicit AlignmentMatchingStoragePooledBuffer(VirtualFile bs, size_t da) - : m_base_storage(std::move(bs)), m_data_align(da) { + : m_base_storage(std::move(bs)), m_data_align(da), work_buffer(da) { ASSERT(Common::IsPowerOfTwo(da)); } @@ -104,16 +106,10 @@ public: // Validate arguments. ASSERT(buffer != nullptr); - s64 bs_size = this->GetSize(); ASSERT(R_SUCCEEDED(IStorage::CheckAccessRange(offset, size, bs_size))); - - // Allocate a pooled buffer. - PooledBuffer pooled_buffer; - pooled_buffer.AllocateParticularlyLarge(m_data_align, m_data_align); - - return AlignmentMatchingStorageImpl::Read(m_base_storage, pooled_buffer.GetBuffer(), - pooled_buffer.GetSize(), m_data_align, + return AlignmentMatchingStorageImpl::Read(m_base_storage, work_buffer.data(), + work_buffer.size(), m_data_align, BufferAlign, offset, buffer, size); } @@ -125,16 +121,10 @@ public: // Validate arguments. ASSERT(buffer != nullptr); - s64 bs_size = this->GetSize(); ASSERT(R_SUCCEEDED(IStorage::CheckAccessRange(offset, size, bs_size))); - - // Allocate a pooled buffer. - PooledBuffer pooled_buffer; - pooled_buffer.AllocateParticularlyLarge(m_data_align, m_data_align); - - return AlignmentMatchingStorageImpl::Write(m_base_storage, pooled_buffer.GetBuffer(), - pooled_buffer.GetSize(), m_data_align, + return AlignmentMatchingStorageImpl::Write(m_base_storage, work_buffer.data(), + work_buffer.size(), m_data_align, BufferAlign, offset, buffer, size); } diff --git a/src/core/file_sys/fssystem/fssystem_alignment_matching_storage_impl.cpp b/src/core/file_sys/fssystem/fssystem_alignment_matching_storage_impl.cpp index 08b77d790a..322e6e05f2 100644 --- a/src/core/file_sys/fssystem/fssystem_alignment_matching_storage_impl.cpp +++ b/src/core/file_sys/fssystem/fssystem_alignment_matching_storage_impl.cpp @@ -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 diff --git a/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp b/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp index 615a624f4f..ce3b62f26d 100644 --- a/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp +++ b/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp @@ -4,11 +4,9 @@ // 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" -#include "core/file_sys/fssystem/fssystem_pooled_buffer.h" namespace FileSys { @@ -238,9 +236,7 @@ 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(end_offset > 0); ASSERT(!this->IsInitialized()); m_node_size = node_size; @@ -468,16 +464,8 @@ Result BucketTree::Visitor::Find(s64 virtual_address) { } Result BucketTree::Visitor::FindEntrySet(s32* out_index, s64 virtual_address, s32 node_index) { - const auto node_size = m_tree->m_node_size; - - PooledBuffer pool(node_size, 1); - if (node_size <= pool.GetSize()) { - R_RETURN( - this->FindEntrySetWithBuffer(out_index, virtual_address, node_index, pool.GetBuffer())); - } else { - pool.Deallocate(); - R_RETURN(this->FindEntrySetWithoutBuffer(out_index, virtual_address, node_index)); - } + std::vector pool(m_tree->m_node_size); + R_RETURN(FindEntrySetWithBuffer(out_index, virtual_address, node_index, pool.data())); } Result BucketTree::Visitor::FindEntrySetWithBuffer(s32* out_index, s64 virtual_address, @@ -528,15 +516,8 @@ Result BucketTree::Visitor::FindEntrySetWithoutBuffer(s32* out_index, s64 virtua } Result BucketTree::Visitor::FindEntry(s64 virtual_address, s32 entry_set_index) { - const auto entry_set_size = m_tree->m_node_size; - - PooledBuffer pool(entry_set_size, 1); - if (entry_set_size <= pool.GetSize()) { - R_RETURN(this->FindEntryWithBuffer(virtual_address, entry_set_index, pool.GetBuffer())); - } else { - pool.Deallocate(); - R_RETURN(this->FindEntryWithoutBuffer(virtual_address, entry_set_index)); - } + std::vector pool(m_tree->m_node_size); + R_RETURN(FindEntryWithBuffer(virtual_address, entry_set_index, pool.data())); } Result BucketTree::Visitor::FindEntryWithBuffer(s64 virtual_address, s32 entry_set_index, diff --git a/src/core/file_sys/fssystem/fssystem_bucket_tree_template_impl.h b/src/core/file_sys/fssystem/fssystem_bucket_tree_template_impl.h index 030b2916b0..fac6c37214 100644 --- a/src/core/file_sys/fssystem/fssystem_bucket_tree_template_impl.h +++ b/src/core/file_sys/fssystem/fssystem_bucket_tree_template_impl.h @@ -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 @@ -6,7 +9,6 @@ #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" -#include "core/file_sys/fssystem/fssystem_pooled_buffer.h" namespace FileSys { @@ -35,23 +37,19 @@ Result BucketTree::ScanContinuousReading(ContinuousReadingInfo* out_info, R_UNLESS(entry.GetVirtualOffset() <= cur_offset, ResultOutOfRange); // Create a pooled buffer for our scan. - PooledBuffer pool(m_node_size, 1); - char* buffer = nullptr; - + std::vector pool(m_node_size); s64 entry_storage_size = m_entry_storage->GetSize(); // Read the node. - if (m_node_size <= pool.GetSize()) { - buffer = pool.GetBuffer(); - const auto ofs = param.entry_set.index * static_cast(m_node_size); - R_UNLESS(m_node_size + ofs <= static_cast(entry_storage_size), - ResultInvalidBucketTreeNodeEntryCount); + u8* buffer = reinterpret_cast(pool.data()); + const auto ofs = param.entry_set.index * s64(m_node_size); + R_UNLESS(m_node_size + ofs <= size_t(entry_storage_size), + ResultInvalidBucketTreeNodeEntryCount); - m_entry_storage->Read(reinterpret_cast(buffer), m_node_size, ofs); - } + m_entry_storage->Read(buffer, m_node_size, ofs); // Calculate extents. - const auto end_offset = cur_offset + static_cast(param.size); + const auto end_offset = cur_offset + s64(param.size); s64 phys_offset = entry.GetPhysicalOffset(); // Start merge tracking. @@ -76,14 +74,8 @@ Result BucketTree::ScanContinuousReading(ContinuousReadingInfo* out_info, s64 next_entry_offset; if (entry_index + 1 < entry_count) { - if (buffer != nullptr) { - const auto ofs = impl::GetBucketTreeEntryOffset(0, m_entry_size, entry_index + 1); - std::memcpy(std::addressof(next_entry), buffer + ofs, m_entry_size); - } else { - const auto ofs = impl::GetBucketTreeEntryOffset(param.entry_set.index, m_node_size, - m_entry_size, entry_index + 1); - m_entry_storage->ReadObject(std::addressof(next_entry), ofs); - } + const auto offset = impl::GetBucketTreeEntryOffset(0, m_entry_size, entry_index + 1); + std::memcpy(std::addressof(next_entry), buffer + offset, m_entry_size); next_entry_offset = next_entry.GetVirtualOffset(); R_UNLESS(param.offsets.IsInclude(next_entry_offset), ResultInvalidIndirectEntryOffset); diff --git a/src/core/file_sys/fssystem/fssystem_compressed_storage.h b/src/core/file_sys/fssystem/fssystem_compressed_storage.h index 74c98630ec..223d51647e 100644 --- a/src/core/file_sys/fssystem/fssystem_compressed_storage.h +++ b/src/core/file_sys/fssystem/fssystem_compressed_storage.h @@ -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 @@ -9,8 +12,6 @@ #include "core/file_sys/fssystem/fs_i_storage.h" #include "core/file_sys/fssystem/fssystem_bucket_tree.h" #include "core/file_sys/fssystem/fssystem_compression_common.h" -#include "core/file_sys/fssystem/fssystem_pooled_buffer.h" -#include "core/file_sys/vfs/vfs.h" namespace FileSys { @@ -317,23 +318,11 @@ private: R_SUCCEED_IF(entry_count == 0); // Get the remaining size in a convenient form. - const size_t total_required_size = - static_cast(required_access_physical_size); + const size_t total_required_size = size_t(required_access_physical_size); // Perform the read based on whether we need to allocate a buffer. if (will_allocate_pooled_buffer) { - // Allocate a pooled buffer. - PooledBuffer pooled_buffer; - if (pooled_buffer.GetAllocatableSizeMax() >= total_required_size) { - pooled_buffer.Allocate(total_required_size, m_block_size_max); - } else { - pooled_buffer.AllocateParticularlyLarge( - std::min( - total_required_size, - PooledBuffer::GetAllocatableParticularlyLargeSizeMax()), - m_block_size_max); - } - + std::vector pooled_buffer(std::max(m_block_size_max, total_required_size)); // Read each of the entries. for (s32 entry_idx = 0; entry_idx < entry_count; ++entry_idx) { // Determine the current read size. @@ -342,13 +331,13 @@ private: if (const size_t target_entry_size = static_cast(entries[entry_idx].physical_size) + static_cast(entries[entry_idx].gap_from_prev); - target_entry_size <= pooled_buffer.GetSize()) { + target_entry_size <= pooled_buffer.size()) { // We'll be using the pooled buffer. will_use_pooled_buffer = true; // Determine how much we can read. const size_t max_size = std::min( - required_access_physical_size, pooled_buffer.GetSize()); + required_access_physical_size, pooled_buffer.size()); size_t read_size = 0; for (auto n = entry_idx; n < entry_count; ++n) { @@ -376,7 +365,7 @@ private: // Perform the read based on whether or not we'll use the pooled buffer. if (will_use_pooled_buffer) { // Read the compressed data into the pooled buffer. - auto* const buffer = pooled_buffer.GetBuffer(); + auto* const buffer = pooled_buffer.data(); m_data_storage->Read(reinterpret_cast(buffer), cur_read_size, required_access_physical_offset); @@ -863,11 +852,9 @@ private: static_cast(unaligned_range->virtual_size)); // Get a pooled buffer for our read. - PooledBuffer pooled_buffer; - pooled_buffer.Allocate(size_buffer_required, size_buffer_required); - + std::vector pooled_buffer(size_buffer_required); // Perform read. - Result rc = read_impl(pooled_buffer.GetBuffer(), size_buffer_required); + Result rc = read_impl(pooled_buffer.data(), size_buffer_required); if (R_FAILED(rc)) { R_THROW(rc); } @@ -876,8 +863,7 @@ private: const size_t skip_size = cur_offset - unaligned_range->virtual_offset; const size_t copy_size = std::min( cur_size, unaligned_range->GetEndVirtualOffset() - cur_offset); - - std::memcpy(cur_dst, pooled_buffer.GetBuffer() + skip_size, copy_size); + std::memcpy(cur_dst, pooled_buffer.data() + skip_size, copy_size); // Advance. cur_dst += copy_size; diff --git a/src/core/file_sys/fssystem/fssystem_crypto_configuration.cpp b/src/core/file_sys/fssystem/fssystem_crypto_configuration.cpp index 0a9f28975b..073508a18b 100644 --- a/src/core/file_sys/fssystem/fssystem_crypto_configuration.cpp +++ b/src/core/file_sys/fssystem/fssystem_crypto_configuration.cpp @@ -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 diff --git a/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp b/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp index c1bad3ec36..15bb609110 100644 --- a/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp +++ b/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp index 4cfa5c58f8..25036b02c1 100644 --- a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp +++ b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp @@ -1,10 +1,9 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// 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" @@ -14,7 +13,6 @@ #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" @@ -1296,91 +1294,65 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl( 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; + // Define storage types. + using VerificationStorage = HierarchicalIntegrityVerificationStorage; + using StorageInfo = VerificationStorage::HierarchicalStorageInformation; - // Validate the meta info. - HierarchicalIntegrityVerificationInformation level_hash_info; - std::memcpy(std::addressof(level_hash_info), std::addressof(meta_info.level_hash_info), - sizeof(level_hash_info)); + // Validate the meta info. + HierarchicalIntegrityVerificationInformation level_hash_info; + std::memcpy(std::addressof(level_hash_info), + std::addressof(meta_info.level_hash_info), + sizeof(level_hash_info)); - R_UNLESS(IntegrityMinLayerCount <= level_hash_info.max_layers, - ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount); - R_UNLESS(level_hash_info.max_layers <= IntegrityMaxLayerCount, - ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount); + R_UNLESS(IntegrityMinLayerCount <= level_hash_info.max_layers, + ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount); + R_UNLESS(level_hash_info.max_layers <= IntegrityMaxLayerCount, + ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount); - // Get the base storage size. - s64 base_storage_size = base_storage->GetSize(); + // Get the base storage size. + s64 base_storage_size = base_storage->GetSize(); - // Create storage info. - StorageInfo storage_info; - for (s32 i = 0; i < static_cast(level_hash_info.max_layers - 2); ++i) { - const auto& layer_info = level_hash_info.info[i]; - R_UNLESS(layer_info_offset + layer_info.offset + layer_info.size <= base_storage_size, - ResultNcaBaseStorageOutOfRangeD); - - storage_info[i + 1] = std::make_shared( - base_storage, layer_info.size, layer_info_offset + layer_info.offset); - } - - // Set the last layer info. - const auto& layer_info = level_hash_info.info[level_hash_info.max_layers - 2]; - const s64 last_layer_info_offset = layer_info_offset > 0 ? 0LL : layer_info.offset.Get(); - R_UNLESS(last_layer_info_offset + layer_info.size <= base_storage_size, + // Create storage info. + StorageInfo storage_info; + for (s32 i = 0; i < static_cast(level_hash_info.max_layers - 2); ++i) { + const auto& layer_info = level_hash_info.info[i]; + R_UNLESS(layer_info_offset + layer_info.offset + layer_info.size <= base_storage_size, ResultNcaBaseStorageOutOfRangeD); - if (layer_info_offset > 0) { - R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset, - ResultRomNcaInvalidIntegrityLayerInfoOffset); - } - storage_info[level_hash_info.max_layers - 1] = std::make_shared( - std::move(base_storage), layer_info.size, last_layer_info_offset); - // Make the integrity romfs storage. - auto integrity_storage = std::make_shared(); - R_UNLESS(integrity_storage != nullptr, ResultAllocationMemoryFailedAllocateShared); - - // Initialize the integrity storage. - R_TRY(integrity_storage->Initialize(level_hash_info, meta_info.master_hash, storage_info, - max_data_cache_entries, max_hash_cache_entries, - buffer_level)); - - // 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(base_storage, data_li.size, data_off); - R_UNLESS(data_view != nullptr, ResultAllocationMemoryFailedAllocateShared); - - auto passthrough = std::make_shared(std::move(data_view)); - R_UNLESS(passthrough != nullptr, ResultAllocationMemoryFailedAllocateShared); - - *out = std::move(passthrough); - R_SUCCEED(); + storage_info[i + 1] = std::make_shared(base_storage, + layer_info.size, + layer_info_offset + layer_info.offset); } + + // Set the last layer info. + const auto& layer_info = level_hash_info.info[level_hash_info.max_layers - 2]; + const s64 last_layer_info_offset = layer_info_offset > 0 ? 0LL : layer_info.offset.Get(); + R_UNLESS(last_layer_info_offset + layer_info.size <= base_storage_size, + ResultNcaBaseStorageOutOfRangeD); + if (layer_info_offset > 0) { + R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset, + ResultRomNcaInvalidIntegrityLayerInfoOffset); + } + storage_info[level_hash_info.max_layers - 1] + = std::make_shared(std::move(base_storage), + layer_info.size, + last_layer_info_offset); + + // Make the integrity romfs storage. + auto integrity_storage = std::make_shared(); + R_UNLESS(integrity_storage != nullptr, ResultAllocationMemoryFailedAllocateShared); + + // Initialize the integrity storage. + R_TRY(integrity_storage->Initialize(level_hash_info, + meta_info.master_hash, + storage_info, + max_data_cache_entries, + max_hash_cache_entries, + buffer_level)); + + // Set the output. + *out = std::move(integrity_storage); + R_SUCCEED(); } Result NcaFileSystemDriver::CreateRegionSwitchStorage(VirtualFile* out, diff --git a/src/core/file_sys/fssystem/fssystem_nca_header.cpp b/src/core/file_sys/fssystem/fssystem_nca_header.cpp index 2226c087c0..77042dfd43 100644 --- a/src/core/file_sys/fssystem/fssystem_nca_header.cpp +++ b/src/core/file_sys/fssystem/fssystem_nca_header.cpp @@ -13,13 +13,11 @@ u8 NcaHeader::GetProperKeyGeneration() const { } bool NcaPatchInfo::HasIndirectTable() const { - static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'}; - return std::memcmp(indirect_header.data(), BKTR, sizeof(BKTR)) == 0; + return this->indirect_size != 0; } bool NcaPatchInfo::HasAesCtrExTable() const { - static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'}; - return std::memcmp(aes_ctr_ex_header.data(), BKTR, sizeof(BKTR)) == 0; + return this->aes_ctr_ex_size != 0; } } // namespace FileSys diff --git a/src/core/file_sys/fssystem/fssystem_passthrough_storage.h b/src/core/file_sys/fssystem/fssystem_passthrough_storage.h deleted file mode 100644 index 8fc6f4962a..0000000000 --- a/src/core/file_sys/fssystem/fssystem_passthrough_storage.h +++ /dev/null @@ -1,32 +0,0 @@ -// 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 diff --git a/src/core/file_sys/fssystem/fssystem_pooled_buffer.cpp b/src/core/file_sys/fssystem/fssystem_pooled_buffer.cpp deleted file mode 100644 index dcd08dac3e..0000000000 --- a/src/core/file_sys/fssystem/fssystem_pooled_buffer.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/alignment.h" -#include "core/file_sys/fssystem/fssystem_pooled_buffer.h" - -namespace FileSys { - -namespace { - -constexpr size_t HeapBlockSize = BufferPoolAlignment; -static_assert(HeapBlockSize == 4_KiB); - -// A heap block is 4KiB. An order is a power of two. -// This gives blocks of the order 32KiB, 512KiB, 4MiB. -constexpr s32 HeapOrderMax = 7; -constexpr s32 HeapOrderMaxForLarge = HeapOrderMax + 3; - -constexpr size_t HeapAllocatableSizeMax = HeapBlockSize * (static_cast(1) << HeapOrderMax); -constexpr size_t HeapAllocatableSizeMaxForLarge = - HeapBlockSize * (static_cast(1) << HeapOrderMaxForLarge); - -} // namespace - -size_t PooledBuffer::GetAllocatableSizeMaxCore(bool large) { - return large ? HeapAllocatableSizeMaxForLarge : HeapAllocatableSizeMax; -} - -void PooledBuffer::AllocateCore(size_t ideal_size, size_t required_size, bool large) { - // Ensure preconditions. - ASSERT(m_buffer == nullptr); - - // Check that we can allocate this size. - ASSERT(required_size <= GetAllocatableSizeMaxCore(large)); - - const size_t target_size = - (std::min)((std::max)(ideal_size, required_size), GetAllocatableSizeMaxCore(large)); - - // Dummy implementation for allocate. - if (target_size > 0) { - m_buffer = - reinterpret_cast(::operator new(target_size, std::align_val_t{HeapBlockSize})); - m_size = target_size; - - // Ensure postconditions. - ASSERT(m_buffer != nullptr); - } -} - -void PooledBuffer::Shrink(size_t ideal_size) { - ASSERT(ideal_size <= GetAllocatableSizeMaxCore(true)); - - // Shrinking to zero means that we have no buffer. - if (ideal_size == 0) { - ::operator delete(m_buffer, std::align_val_t{HeapBlockSize}); - m_buffer = nullptr; - m_size = ideal_size; - } -} - -} // namespace FileSys diff --git a/src/core/file_sys/fssystem/fssystem_pooled_buffer.h b/src/core/file_sys/fssystem/fssystem_pooled_buffer.h deleted file mode 100644 index 9a6adbcb5a..0000000000 --- a/src/core/file_sys/fssystem/fssystem_pooled_buffer.h +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/literals.h" -#include "core/hle/result.h" - -namespace FileSys { - -using namespace Common::Literals; - -constexpr inline size_t BufferPoolAlignment = 4_KiB; -constexpr inline size_t BufferPoolWorkSize = 320; - -class PooledBuffer { - YUZU_NON_COPYABLE(PooledBuffer); - -public: - // Constructor/Destructor. - constexpr PooledBuffer() : m_buffer(), m_size() {} - - PooledBuffer(size_t ideal_size, size_t required_size) : m_buffer(), m_size() { - this->Allocate(ideal_size, required_size); - } - - ~PooledBuffer() { - this->Deallocate(); - } - - // Move and assignment. - explicit PooledBuffer(PooledBuffer&& rhs) : m_buffer(rhs.m_buffer), m_size(rhs.m_size) { - rhs.m_buffer = nullptr; - rhs.m_size = 0; - } - - PooledBuffer& operator=(PooledBuffer&& rhs) { - PooledBuffer(std::move(rhs)).Swap(*this); - return *this; - } - - // Allocation API. - void Allocate(size_t ideal_size, size_t required_size) { - return this->AllocateCore(ideal_size, required_size, false); - } - - void AllocateParticularlyLarge(size_t ideal_size, size_t required_size) { - return this->AllocateCore(ideal_size, required_size, true); - } - - void Shrink(size_t ideal_size); - - void Deallocate() { - // Shrink the buffer to empty. - this->Shrink(0); - ASSERT(m_buffer == nullptr); - } - - char* GetBuffer() const { - ASSERT(m_buffer != nullptr); - return m_buffer; - } - - size_t GetSize() const { - ASSERT(m_buffer != nullptr); - return m_size; - } - -public: - static size_t GetAllocatableSizeMax() { - return GetAllocatableSizeMaxCore(false); - } - static size_t GetAllocatableParticularlyLargeSizeMax() { - return GetAllocatableSizeMaxCore(true); - } - -private: - static size_t GetAllocatableSizeMaxCore(bool large); - -private: - void Swap(PooledBuffer& rhs) { - std::swap(m_buffer, rhs.m_buffer); - std::swap(m_size, rhs.m_size); - } - - void AllocateCore(size_t ideal_size, size_t required_size, bool large); - -private: - char* m_buffer; - size_t m_size; -}; - -} // namespace FileSys diff --git a/src/core/file_sys/fssystem/fssystem_sparse_storage.h b/src/core/file_sys/fssystem/fssystem_sparse_storage.h index 1cc7e7b1eb..759a6b5092 100644 --- a/src/core/file_sys/fssystem/fssystem_sparse_storage.h +++ b/src/core/file_sys/fssystem/fssystem_sparse_storage.h @@ -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 diff --git a/src/core/file_sys/nca_metadata.cpp b/src/core/file_sys/nca_metadata.cpp index 55ea4d0803..324ecbc8c9 100644 --- a/src/core/file_sys/nca_metadata.cpp +++ b/src/core/file_sys/nca_metadata.cpp @@ -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 diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index cb2089e9b3..f750a2e871 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -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 @@ -64,7 +67,7 @@ static std::string GetRelativePathFromNcaID(const std::array& nca_id, bo } Core::Crypto::SHA256Hash hash{}; - mbedtls_sha256_ret(nca_id.data(), nca_id.size(), hash.data(), 0); + mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0); const auto format_str = fmt::runtime(cnmt_suffix ? "/000000{:02X}/{}.cnmt.nca" : "/000000{:02X}/{}.nca"); @@ -146,7 +149,7 @@ bool PlaceholderCache::Create(const NcaID& id, u64 size) const { } Core::Crypto::SHA256Hash hash{}; - mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0); + mbedtls_sha256(id.data(), id.size(), hash.data(), 0); const auto dirname = fmt::format("000000{:02X}", hash[0]); const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname); @@ -170,7 +173,7 @@ bool PlaceholderCache::Delete(const NcaID& id) const { } Core::Crypto::SHA256Hash hash{}; - mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0); + mbedtls_sha256(id.data(), id.size(), hash.data(), 0); const auto dirname = fmt::format("000000{:02X}", hash[0]); const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname); @@ -665,7 +668,7 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type, const OptionalHeader opt_header{0, 0}; ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}}; const auto& data = nca.GetBaseFile()->ReadBytes(0x100000); - mbedtls_sha256_ret(data.data(), data.size(), c_rec.hash.data(), 0); + mbedtls_sha256(data.data(), data.size(), c_rec.hash.data(), 0); std::memcpy(&c_rec.nca_id, &c_rec.hash, 16); const CNMT new_cnmt(header, opt_header, {c_rec}, {}); if (!RawInstallYuzuMeta(new_cnmt)) { @@ -776,7 +779,7 @@ InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFuncti id = *override_id; } else { const auto& data = in->ReadBytes(0x100000); - mbedtls_sha256_ret(data.data(), data.size(), hash.data(), 0); + mbedtls_sha256(data.data(), data.size(), hash.data(), 0); memcpy(id.data(), hash.data(), 16); } diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp index fee75f9de6..9cf4928cd9 100644 --- a/src/core/file_sys/romfs.cpp +++ b/src/core/file_sys/romfs.cpp @@ -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 diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 106922e04f..edf51e74de 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -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 @@ -126,6 +129,10 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir, std::string out = GetSaveDataSpaceIdPath(space); + LOG_INFO(Common_Filesystem, "Save ID: {:016X}", save_id); + LOG_INFO(Common_Filesystem, "User ID[1]: {:016X}", user_id[1]); + LOG_INFO(Common_Filesystem, "User ID[0]: {:016X}", user_id[0]); + switch (type) { case SaveDataType::System: return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); diff --git a/src/core/file_sys/vfs/vfs.cpp b/src/core/file_sys/vfs/vfs.cpp index 2be7084209..b85b843e3e 100644 --- a/src/core/file_sys/vfs/vfs.cpp +++ b/src/core/file_sys/vfs/vfs.cpp @@ -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 diff --git a/src/core/file_sys/vfs/vfs_static.h b/src/core/file_sys/vfs/vfs_static.h index 6dc4ef8fbf..b673ba1d2a 100644 --- a/src/core/file_sys/vfs/vfs_static.h +++ b/src/core/file_sys/vfs/vfs_static.h @@ -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 diff --git a/src/core/file_sys/vfs/vfs_vector.cpp b/src/core/file_sys/vfs/vfs_vector.cpp index 7576a023cf..4d4a90f640 100644 --- a/src/core/file_sys/vfs/vfs_vector.cpp +++ b/src/core/file_sys/vfs/vfs_vector.cpp @@ -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 diff --git a/src/core/file_sys/vfs/vfs_vector.h b/src/core/file_sys/vfs/vfs_vector.h index 27f2c03ca7..86beed931c 100644 --- a/src/core/file_sys/vfs/vfs_vector.h +++ b/src/core/file_sys/vfs/vfs_vector.h @@ -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 diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp index fd5342021c..c1912b2bda 100644 --- a/src/core/file_sys/xts_archive.cpp +++ b/src/core/file_sys/xts_archive.cpp @@ -68,7 +68,7 @@ NAX::NAX(VirtualFile file_, std::array nca_id) : header(std::make_unique()), file(std::move(file_)), keys{Core::Crypto::KeyManager::Instance()} { Core::Crypto::SHA256Hash hash{}; - mbedtls_sha256_ret(nca_id.data(), nca_id.size(), hash.data(), 0); + mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0); status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0], Common::HexToString(nca_id, false))); } diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index ec5cec8fa0..9b771ed092 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -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 diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 3de975c20f..63e17f9ceb 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -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 diff --git a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp index fa918ff204..3e98584216 100644 --- a/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp +++ b/src/core/hle/kernel/board/nintendo/nx/k_memory_layout.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp index db654d730d..1446653916 100644 --- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp +++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_dynamic_page_manager.h b/src/core/hle/kernel/k_dynamic_page_manager.h index 2357fe0f4d..16bd61a98a 100644 --- a/src/core/hle/kernel/k_dynamic_page_manager.h +++ b/src/core/hle/kernel/k_dynamic_page_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h index 22fdc7e47a..7381e951f5 100644 --- a/src/core/hle/kernel/k_handle_table.h +++ b/src/core/hle/kernel/k_handle_table.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_hardware_timer.cpp b/src/core/hle/kernel/k_hardware_timer.cpp index f3098a59e0..019e709fbe 100644 --- a/src/core/hle/kernel/k_hardware_timer.cpp +++ b/src/core/hle/kernel/k_hardware_timer.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_hardware_timer.h b/src/core/hle/kernel/k_hardware_timer.h index cb83e9c5b5..d39d6c3855 100644 --- a/src/core/hle/kernel/k_hardware_timer.h +++ b/src/core/hle/kernel/k_hardware_timer.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_light_server_session.cpp b/src/core/hle/kernel/k_light_server_session.cpp index 5ea448b998..a4d2b11231 100644 --- a/src/core/hle/kernel/k_light_server_session.cpp +++ b/src/core/hle/kernel/k_light_server_session.cpp @@ -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 diff --git a/src/core/hle/kernel/k_light_server_session.h b/src/core/hle/kernel/k_light_server_session.h index 87ec9db016..67db3f76ca 100644 --- a/src/core/hle/kernel/k_light_server_session.h +++ b/src/core/hle/kernel/k_light_server_session.h @@ -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 diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h index acf48cb757..f6543bdb3a 100644 --- a/src/core/hle/kernel/k_memory_block.h +++ b/src/core/hle/kernel/k_memory_block.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_memory_layout.cpp b/src/core/hle/kernel/k_memory_layout.cpp index 6821f4c07e..721a9cc5cb 100644 --- a/src/core/hle/kernel/k_memory_layout.cpp +++ b/src/core/hle/kernel/k_memory_layout.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp index 2aa393ac06..743e290541 100644 --- a/src/core/hle/kernel/k_memory_manager.cpp +++ b/src/core/hle/kernel/k_memory_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h index 41d33fa55d..2f4ae7f04f 100644 --- a/src/core/hle/kernel/k_memory_manager.h +++ b/src/core/hle/kernel/k_memory_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_memory_region.h b/src/core/hle/kernel/k_memory_region.h index cad7b31126..5188e92717 100644 --- a/src/core/hle/kernel/k_memory_region.h +++ b/src/core/hle/kernel/k_memory_region.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_page_bitmap.h b/src/core/hle/kernel/k_page_bitmap.h index 4ad5483b28..fc21b81574 100644 --- a/src/core/hle/kernel/k_page_bitmap.h +++ b/src/core/hle/kernel/k_page_bitmap.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_page_heap.h b/src/core/hle/kernel/k_page_heap.h index 0d63a6b1f5..7d34509983 100644 --- a/src/core/hle/kernel/k_page_heap.h +++ b/src/core/hle/kernel/k_page_heap.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index d6742f0637..d9a128c804 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -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 diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index 1403317d72..e886f97ebd 100644 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h index 2ec3d185dc..c91e7969a2 100644 --- a/src/core/hle/kernel/k_slab_heap.h +++ b/src/core/hle/kernel/k_slab_heap.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 6aef191c87..6b68a56ab4 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index bc0684e76c..db912b71fb 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp @@ -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 diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index 54844bfe7d..df4e5ad00b 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp @@ -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 @@ -18,7 +21,8 @@ ACC_U0::ACC_U0(std::shared_ptr module_, std::shared_ptr {5, &ACC_U0::GetProfile, "GetProfile"}, {6, nullptr, "GetProfileDigest"}, // 3.0.0+ {50, &ACC_U0::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, - {51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, + {51, &ACC_U0::TrySelectUserWithoutInteractionDeprecated, "TrySelectUserWithoutInteractionDeprecated"}, + {52, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, {60, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0 {99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+ {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"}, diff --git a/src/core/hle/service/am/frontend/applet_cabinet.cpp b/src/core/hle/service/am/frontend/applet_cabinet.cpp index 58401479d3..71fa2a0c17 100644 --- a/src/core/hle/service/am/frontend/applet_cabinet.cpp +++ b/src/core/hle/service/am/frontend/applet_cabinet.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/am/frontend/applet_controller.cpp b/src/core/hle/service/am/frontend/applet_controller.cpp index d457885773..d5699d7848 100644 --- a/src/core/hle/service/am/frontend/applet_controller.cpp +++ b/src/core/hle/service/am/frontend/applet_controller.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/am/service/application_accessor.cpp b/src/core/hle/service/am/service/application_accessor.cpp index 2ac07f838e..88a1724fc6 100644 --- a/src/core/hle/service/am/service/application_accessor.cpp +++ b/src/core/hle/service/am/service/application_accessor.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp index 091aadc9fc..4d36d306bd 100644 --- a/src/core/hle/service/am/service/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/bcat/bcat_service.cpp b/src/core/hle/service/bcat/bcat_service.cpp index 5c23760113..253eff9d16 100644 --- a/src/core/hle/service/bcat/bcat_service.cpp +++ b/src/core/hle/service/bcat/bcat_service.cpp @@ -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 diff --git a/src/core/hle/service/bcat/delivery_cache_directory_service.cpp b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp index fea373a607..70b875a2bf 100644 --- a/src/core/hle/service/bcat/delivery_cache_directory_service.cpp +++ b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -15,7 +18,7 @@ namespace Service::BCAT { static BcatDigest DigestFile(const FileSys::VirtualFile& file) { BcatDigest out{}; const auto bytes = file->ReadAllBytes(); - mbedtls_md5_ret(bytes.data(), bytes.size(), out.data()); + mbedtls_md5(bytes.data(), bytes.size(), out.data()); return out; } diff --git a/src/core/hle/service/bcat/delivery_cache_storage_service.cpp b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp index 0ce798eb75..46ed4dae67 100644 --- a/src/core/hle/service/bcat/delivery_cache_storage_service.cpp +++ b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h index 03b2a130a1..cdbf32c8ee 100644 --- a/src/core/hle/service/cmif_serialization.h +++ b/src/core/hle/service/cmif_serialization.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp index 9ad8d0e9b5..4b7d7dc753 100644 --- a/src/core/hle/service/es/es.cpp +++ b/src/core/hle/service/es/es.cpp @@ -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 diff --git a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp index 490ac49d42..495b131df4 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp @@ -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 diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp index dd3f1954de..3daec85210 100644 --- a/src/core/hle/service/glue/notif.cpp +++ b/src/core/hle/service/glue/notif.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index bfe57999c8..0da790e1c8 100644 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp @@ -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 diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp index 450c1e953f..0a5d479094 100644 --- a/src/core/hle/service/hid/hid_debug_server.cpp +++ b/src/core/hle/service/hid/hid_debug_server.cpp @@ -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-3.0-or-later diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 06a2368fe5..8fd7db17c2 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/ldn/lan_discovery.cpp b/src/core/hle/service/ldn/lan_discovery.cpp index 7d677e6664..f37dbe492f 100644 --- a/src/core/hle/service/ldn/lan_discovery.cpp +++ b/src/core/hle/service/ldn/lan_discovery.cpp @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/ldn/lan_discovery.h" #include "core/internal_network/network.h" diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h index 56a3cd1b4b..975af5b6c8 100644 --- a/src/core/hle/service/ldn/ldn_types.h +++ b/src/core/hle/service/ldn/ldn_types.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp index 69170a879d..b8770120a7 100644 --- a/src/core/hle/service/ldn/user_local_communication_service.cpp +++ b/src/core/hle/service/ldn/user_local_communication_service.cpp @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later #include diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index 508f91546d..3fbde3db8e 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -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 diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index c026d47e86..98ed7b97bc 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/ns/platform_service_manager.cpp b/src/core/hle/service/ns/platform_service_manager.cpp index 301cf4ac4f..8468661b20 100644 --- a/src/core/hle/service/ns/platform_service_manager.cpp +++ b/src/core/hle/service/ns/platform_service_manager.cpp @@ -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 diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index a7551ec154..d7a65ce445 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -256,61 +256,103 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) { } NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) { - LOG_DEBUG(Service_NVDRV, "called"); - ZbcEntry entry = {}; - std::memset(&entry, 0, sizeof(entry)); - // TODO(ogniK): What does this even actually do? - // TODO(myself): This thing I guess - if (params.type == 1) { - for (auto i = 0; i < 4; ++i) { - entry.color_ds[i] = params.color_ds[i]; - entry.color_l2[i] = params.color_l2[i]; - } - ASSERT(this->max_color_entries < 16); - this->color_entries[this->max_color_entries] = entry; - ++this->max_color_entries; - } else if (params.type == 2) { - entry.depth = params.depth; - ASSERT(this->max_depth_entries < 16); - this->depth_entries[this->max_depth_entries] = entry; - ++this->max_depth_entries; + if (params.type > supported_types) { + LOG_ERROR(Service_NVDRV, "ZBCSetTable: invalid type {:#X}", params.type); + return NvResult::BadParameter; } + + std::scoped_lock lk(zbc_mutex); + + switch (static_cast(params.type)) { + case ZBCTypes::color: { + ZbcColorEntry color_entry{}; + std::copy_n(std::begin(params.color_ds), color_entry.color_ds.size(), color_entry.color_ds.begin()); + std::copy_n(std::begin(params.color_l2), color_entry.color_l2.size(), color_entry.color_l2.begin()); + color_entry.format = params.format; + color_entry.ref_cnt = 1u; + + auto color_it = std::ranges::find_if(zbc_colors, + [&](const ZbcColorEntry& color_in_question) { + return color_entry.format == color_in_question.format && + color_entry.color_ds == color_in_question.color_ds && + color_entry.color_l2 == color_in_question.color_l2; + }); + + if (color_it != zbc_colors.end()) { + ++color_it->ref_cnt; + LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused color entry fmt={:#X}, ref_cnt={:#X}", + params.format, color_it->ref_cnt); + } else { + zbc_colors.push_back(color_entry); + LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added color entry fmt={:#X}, index={:#X}", + params.format, zbc_colors.size() - 1); + } + break; + } + case ZBCTypes::depth: { + ZbcDepthEntry depth_entry{params.depth, params.format, 1u}; + + auto depth_it = std::ranges::find_if(zbc_depths, + [&](const ZbcDepthEntry& depth_entry_in_question) { + return depth_entry.format == depth_entry_in_question.format && + depth_entry.depth == depth_entry_in_question.depth; + }); + + if (depth_it != zbc_depths.end()) { + ++depth_it->ref_cnt; + LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused depth entry fmt={:#X}, ref_cnt={:#X}", + depth_entry.format, depth_it->ref_cnt); + } else { + zbc_depths.push_back(depth_entry); + LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added depth entry fmt={:#X}, index={:#X}", + depth_entry.format, zbc_depths.size() - 1); + } + } + } + return NvResult::Success; } NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) { - LOG_DEBUG(Service_NVDRV, "called"); - struct ZbcQueryParams { - u32_le color_ds[4]; - u32_le color_l2[4]; - u32_le depth; - u32_le ref_cnt; - u32_le format; - u32_le type; - u32_le index_size; - } entry = {}; - std::memset(&entry, 0, sizeof(entry)); - auto const index = params.index_size; - if (params.type == 0) { //no - entry.index_size = 15; - } else if (params.type == 1) { //color - ASSERT(index < 16); - for (auto i = 0; i < 4; ++i) { - params.color_ds[i] = this->color_entries[index].color_ds[i]; - params.color_l2[i] = this->color_entries[index].color_l2[i]; - } - // TODO: Only if no error thrown (otherwise dont modify) - params.format = this->color_entries[index].format; - //params.ref_cnt = this->color_entries[index].ref_cnt; - } else if (params.type == 2) { //depth - ASSERT(index < 16); - params.depth = this->depth_entries[index].depth; - // TODO: Only if no error thrown (otherwise dont modify) - params.format = this->depth_entries[index].format; - //params.ref_cnt = this->depth_entries[index].ref_cnt; - } else { - UNREACHABLE(); + if (params.type > supported_types) { + LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid type {:#X}", params.type); + return NvResult::BadParameter; } + + std::scoped_lock lk(zbc_mutex); + + switch (static_cast(params.type)) { + case ZBCTypes::color: { + if (params.index_size >= zbc_colors.size()) { + LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid color index {:#X}", params.index_size); + return NvResult::BadParameter; + } + + const auto& colors = zbc_colors[params.index_size]; + std::copy_n(colors.color_ds.begin(), colors.color_ds.size(), std::begin(params.color_ds)); + std::copy_n(colors.color_l2.begin(), colors.color_l2.size(), std::begin(params.color_l2)); + params.depth = 0; + params.ref_cnt = colors.ref_cnt; + params.format = colors.format; + params.index_size = static_cast(zbc_colors.size()); + break; + } + case ZBCTypes::depth: { + if (params.index_size >= zbc_depths.size()) { + LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid depth index {:#X}", params.index_size); + return NvResult::BadParameter; + } + + const auto& depth_entry = zbc_depths[params.index_size]; + std::fill(std::begin(params.color_ds), std::end(params.color_ds), 0); + std::fill(std::begin(params.color_l2), std::end(params.color_l2), 0); + params.depth = depth_entry.depth; + params.ref_cnt = depth_entry.ref_cnt; + params.format = depth_entry.format; + params.index_size = static_cast(zbc_depths.size()); + } + } + return NvResult::Success; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index c36fcbaa69..e0603f9a71 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -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 @@ -34,6 +37,11 @@ public: Kernel::KEvent* QueryEvent(u32 event_id) override; private: + enum class ZBCTypes { + color = 1, + depth = 2, + }; + struct IoctlGpuCharacteristics { u32_le arch; // 0x120 (NVGPU_GPU_ARCH_GM200) u32_le impl; // 0xB (NVGPU_GPU_IMPL_GM20B) @@ -139,6 +147,21 @@ private: }; static_assert(sizeof(IoctlZbcQueryTable) == 52, "IoctlZbcQueryTable is incorrect size"); + struct ZbcColorEntry { + std::array color_ds{}; + std::array color_l2{}; + u32 format{}; + u32 ref_cnt{}; + }; + static_assert(sizeof(ZbcColorEntry) == 40, "ZbcColorEntry is incorrect size"); + + struct ZbcDepthEntry { + u32 depth{}; + u32 format{}; + u32 ref_cnt{}; + }; + static_assert(sizeof(ZbcDepthEntry) == 12, "ZbcDepthEntry is incorrect size"); + struct IoctlFlushL2 { u32_le flush; // l2_flush | l2_invalidate << 1 | fb_flush << 2 u32_le reserved; @@ -182,17 +205,11 @@ private: Kernel::KEvent* error_notifier_event; Kernel::KEvent* unknown_event; - struct ZbcEntry { - u32_le color_ds[4]; - u32_le color_l2[4]; - u32_le depth; - u32_le type; - u32_le format; - }; - std::array color_entries; - std::array depth_entries; - u8 max_color_entries; - u8 max_depth_entries; + // ZBC Tables + std::mutex zbc_mutex{}; + std::vector zbc_colors{}; + std::vector zbc_depths{}; + const u32 supported_types = 2u; }; } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index fa46c2f280..de4197c52d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp index a9b0f9d2f3..2913d25819 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -97,18 +100,18 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, slots[slot].needs_cleanup_on_release = false; slots[slot].buffer_state = BufferState::Acquired; + // Mark tracked buffer history records as acquired + for (auto& buffer_history_record : core->buffer_history) { + if (buffer_history_record.frame_number == core->frame_counter) { + buffer_history_record.state = BufferState::Acquired; + break; + } + } + // TODO: for now, avoid resetting the fence, so that when we next return this // slot to the producer, it will wait for the fence to pass. We should fix this // by properly waiting for the fence in the BufferItemConsumer. // slots[slot].fence = Fence::NoFence(); - - const auto target_frame_number = slots[slot].frame_number; - for (size_t i = 0; i < core->history.size(); i++) { - if (core->history[i].frame_number == target_frame_number) { - core->history[i].state = BufferState::Acquired; - break; - } - } } // If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp index 27ac930f96..6120d8eae1 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -10,12 +13,19 @@ namespace Service::android { -BufferQueueCore::BufferQueueCore() { - history.resize(8); -}; - +BufferQueueCore::BufferQueueCore() = default; BufferQueueCore::~BufferQueueCore() = default; +void BufferQueueCore::PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state) { + buffer_history_pos = (buffer_history_pos + 1) % BUFFER_HISTORY_SIZE; + buffer_history[buffer_history_pos] = BufferHistoryInfo{ + .frame_number = frame_number, + .queue_time = queue_time, + .presentation_time = presentation_time, + .state = state, + }; +} + void BufferQueueCore::SignalDequeueCondition() { dequeue_possible.store(true); dequeue_condition.notify_all(); @@ -47,7 +57,7 @@ s32 BufferQueueCore::GetMinMaxBufferCountLocked(bool async) const { s32 BufferQueueCore::GetMaxBufferCountLocked(bool async) const { const auto min_buffer_count = GetMinMaxBufferCountLocked(async); - auto max_buffer_count = (std::max)(default_max_buffer_count, min_buffer_count); + auto max_buffer_count = std::max(default_max_buffer_count, min_buffer_count); if (override_max_buffer_count != 0) { ASSERT(override_max_buffer_count >= min_buffer_count); diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.h b/src/core/hle/service/nvnflinger/buffer_queue_core.h index 341634352b..ed7d4b4069 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_core.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_core.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -15,6 +18,7 @@ #include "core/hle/service/nvnflinger/buffer_item.h" #include "core/hle/service/nvnflinger/buffer_queue_defs.h" +#include "core/hle/service/nvnflinger/buffer_slot.h" #include "core/hle/service/nvnflinger/pixel_format.h" #include "core/hle/service/nvnflinger/status.h" #include "core/hle/service/nvnflinger/window.h" @@ -23,22 +27,19 @@ namespace Service::android { #ifdef _MSC_VER #pragma pack(push, 1) +struct BufferHistoryInfo { +#elif defined(__GNUC__) || defined(__clang__) +struct __attribute__((packed)) BufferHistoryInfo { #endif -struct BufferInfo { u64 frame_number; s64 queue_time; - s64 presentation_time{}; - BufferState state{BufferState::Free}; -} -#if defined(__GNUC__) || defined(__clang__) -__attribute__((packed)) -#endif -; + s64 presentation_time; + BufferState state; +}; #ifdef _MSC_VER #pragma pack(pop) #endif -static_assert(sizeof(BufferInfo) == 0x1C, - "BufferInfo is an invalid size"); +static_assert(sizeof(BufferHistoryInfo) == 0x1C, "BufferHistoryInfo must be 28 bytes"); class IConsumerListener; class IProducerListener; @@ -49,10 +50,13 @@ class BufferQueueCore final { public: static constexpr s32 INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT; + static constexpr u32 BUFFER_HISTORY_SIZE = 8; BufferQueueCore(); ~BufferQueueCore(); + void PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state); + private: void SignalDequeueCondition(); bool WaitForDequeueCondition(std::unique_lock& lk); @@ -88,11 +92,11 @@ private: const s32 max_acquired_buffer_count{}; // This is always zero on HOS bool buffer_has_been_queued{}; u64 frame_counter{}; + std::array buffer_history{}; + u32 buffer_history_pos{BUFFER_HISTORY_SIZE-1}; u32 transform_hint{}; bool is_allocating{}; mutable std::condition_variable_any is_allocating_condition; - - std::vector history{8}; }; } // namespace Service::android diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index f9e1dba965..bc3076d20b 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -530,11 +533,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, item.is_droppable = core->dequeue_buffer_cannot_block || async; item.swap_interval = swap_interval; - position = (position + 1) % 8; - core->history[position] = {.frame_number = core->frame_counter, - .queue_time = slots[slot].queue_time, - .state = BufferState::Queued}; - sticky_transform = sticky_transform_; if (core->queue.empty()) { @@ -551,6 +549,15 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, // mark it as freed if (core->StillTracking(*front)) { slots[front->slot].buffer_state = BufferState::Free; + + // Mark tracked buffer history records as free + for (auto& buffer_history_record : core->buffer_history) { + if (buffer_history_record.frame_number == front->frame_number) { + buffer_history_record.state = BufferState::Free; + break; + } + } + // Reset the frame number of the freed buffer so that it is the first in line to // be dequeued again slots[front->slot].frame_number = 0; @@ -564,6 +571,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, } } + core->PushHistory(core->frame_counter, slots[slot].queue_time, slots[slot].presentation_time, BufferState::Queued); core->buffer_has_been_queued = true; core->SignalDequeueCondition(); output->Inflate(core->default_width, core->default_height, core->transform_hint, @@ -938,33 +946,46 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, break; } case TransactionId::GetBufferHistory: { - LOG_WARNING(Service_Nvnflinger, "called, transaction=GetBufferHistory"); + LOG_DEBUG(Service_Nvnflinger, "called, transaction=GetBufferHistory"); - std::scoped_lock lock{core->mutex}; - - auto buffer_history_count = (std::min)(parcel_in.Read(), (s32)core->history.size()); - - if (buffer_history_count <= 0) { + const s32 request = parcel_in.Read(); + if (request <= 0) { parcel_out.Write(Status::BadValue); parcel_out.Write(0); - status = Status::None; break; } - auto info = new BufferInfo[buffer_history_count]; - auto pos = position; - for (int i = 0; i < buffer_history_count; i++) { - info[i] = core->history[(pos - i) % core->history.size()]; - LOG_WARNING(Service_Nvnflinger, "frame_number={}, state={}", - core->history[(pos - i) % core->history.size()].frame_number, - (u32)core->history[(pos - i) % core->history.size()].state); - pos--; + constexpr u32 history_max = BufferQueueCore::BUFFER_HISTORY_SIZE; + std::array buffer_history_snapshot{}; + s32 valid_index{}; + { + std::scoped_lock lk(core->mutex); + + const u32 current_history_pos = core->buffer_history_pos; + u32 index_reversed{}; + for (u32 i = 0; i < history_max; ++i) { + // Wrap values backwards e.g. 7, 6, 5, etc. in the range of 0-7 + index_reversed = (current_history_pos + history_max - i) % history_max; + const auto& current_history_buffer = core->buffer_history[index_reversed]; + + // Here we use the frame number as a terminator. + // Because a buffer without frame_number is not considered complete + if (current_history_buffer.frame_number == 0) { + break; + } + + buffer_history_snapshot[valid_index] = current_history_buffer; + ++valid_index; + } } + const s32 limit = std::min(request, valid_index); parcel_out.Write(Status::NoError); - parcel_out.Write(buffer_history_count); - parcel_out.WriteFlattenedObject(info); - status = Status::None; + parcel_out.Write(limit); + for (s32 i = 0; i < limit; ++i) { + parcel_out.Write(buffer_history_snapshot[i]); + } + break; } default: @@ -972,9 +993,7 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, break; } - if (status != Status::None) { - parcel_out.Write(status); - } + parcel_out.Write(status); const auto serialized = parcel_out.Serialize(); std::memcpy(parcel_reply.data(), serialized.data(), diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index 28195cd3c5..6610e0853a 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/core/hle/service/nvnflinger/buffer_slot.h b/src/core/hle/service/nvnflinger/buffer_slot.h index 5b5cbb6fbd..d348b331cb 100644 --- a/src/core/hle/service/nvnflinger/buffer_slot.h +++ b/src/core/hle/service/nvnflinger/buffer_slot.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -15,7 +18,7 @@ namespace Service::android { class GraphicBuffer; -enum class BufferState : s32 { +enum class BufferState : u32 { Free = 0, Dequeued = 1, Queued = 2, diff --git a/src/core/hle/service/nvnflinger/hardware_composer.cpp b/src/core/hle/service/nvnflinger/hardware_composer.cpp index a262a3dcd5..5c0515d473 100644 --- a/src/core/hle/service/nvnflinger/hardware_composer.cpp +++ b/src/core/hle/service/nvnflinger/hardware_composer.cpp @@ -53,6 +53,19 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, // Set default speed limit to 100%. *out_speed_scale = 1.0f; + // If no layers are available, skip the logic. + bool any_visible = false; + for (auto& layer : display.stack.layers) { + if (layer->visible) { + any_visible = true; + break; + } + } + if (!any_visible) { + *out_speed_scale = 1.0f; + return 1; + } + // Determine the number of vsync periods to wait before composing again. std::optional swap_interval{}; bool has_acquired_buffer{}; @@ -110,7 +123,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, } // If any new buffers were acquired, we can present. - if (has_acquired_buffer) { + if (has_acquired_buffer && !composition_stack.empty()) { // Sort by Z-index. std::stable_sort(composition_stack.begin(), composition_stack.end(), [&](auto& l, auto& r) { return l.z_index < r.z_index; }); @@ -119,6 +132,19 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display, nvdisp.Composite(composition_stack); } + // Batch framebuffer releases, instead of one-into-one. + std::vector> to_release; + for (auto& [layer_id, framebuffer] : m_framebuffers) { + if (framebuffer.release_frame_number > m_frame_number || !framebuffer.is_acquired) + continue; + if (auto layer = display.stack.FindLayer(layer_id); layer) + to_release.emplace_back(layer.get(), &framebuffer); + } + for (auto& [layer, framebuffer] : to_release) { + layer->buffer_item_consumer->ReleaseBuffer(framebuffer->item, android::Fence::NoFence()); + framebuffer->is_acquired = false; + } + // Advance by at least one frame. const u32 frame_advance = swap_interval.value_or(1); m_frame_number += frame_advance; diff --git a/src/core/hle/service/psc/time/power_state_request_manager.cpp b/src/core/hle/service/psc/time/power_state_request_manager.cpp index 15fe8e2918..b28b513649 100644 --- a/src/core/hle/service/psc/time/power_state_request_manager.cpp +++ b/src/core/hle/service/psc/time/power_state_request_manager.cpp @@ -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 diff --git a/src/core/hle/service/ro/ro.cpp b/src/core/hle/service/ro/ro.cpp index 3d3ad2d62c..05806e9bf3 100644 --- a/src/core/hle/service/ro/ro.cpp +++ b/src/core/hle/service/ro/ro.cpp @@ -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 @@ -178,7 +181,7 @@ struct ProcessContext { std::vector nro_data(size); m_process->GetMemory().ReadBlock(base_address, nro_data.data(), size); - mbedtls_sha256_ret(nro_data.data(), size, hash.data(), 0); + mbedtls_sha256(nro_data.data(), size, hash.data(), 0); } for (size_t i = 0; i < MaxNrrInfos; i++) { diff --git a/src/core/hle/service/set/settings_server.cpp b/src/core/hle/service/set/settings_server.cpp index 7d1869a4e8..f6080926a7 100644 --- a/src/core/hle/service/set/settings_server.cpp +++ b/src/core/hle/service/set/settings_server.cpp @@ -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 diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index c70fdea24b..22e12b1b9c 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -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 diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index 3b63d162c4..d5245e80eb 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp @@ -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 diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index ed6b576a65..ccc6a7d7f2 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once diff --git a/src/core/hle/service/spl/spl_module.cpp b/src/core/hle/service/spl/spl_module.cpp index f59eeac06c..b8aa99ccd1 100644 --- a/src/core/hle/service/spl/spl_module.cpp +++ b/src/core/hle/service/spl/spl_module.cpp @@ -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 diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 7720c93d5a..0b0108bbd5 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -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 diff --git a/src/core/hle/service/vi/application_display_service.cpp b/src/core/hle/service/vi/application_display_service.cpp index cd28b81dc1..969c86f53b 100644 --- a/src/core/hle/service/vi/application_display_service.cpp +++ b/src/core/hle/service/vi/application_display_service.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index 400bd04bdf..b21d8a7a16 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp index 1600c061f0..f37fdc8795 100644 --- a/src/core/internal_network/socket_proxy.cpp +++ b/src/core/internal_network/socket_proxy.cpp @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #include #include diff --git a/src/core/internal_network/socket_proxy.h b/src/core/internal_network/socket_proxy.h index 93cf0757af..caf5d1ee23 100644 --- a/src/core/internal_network/socket_proxy.h +++ b/src/core/internal_network/socket_proxy.h @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 9a82dae144..1d4846df09 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -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 @@ -150,7 +153,7 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function // Initialize sha256 verification context. mbedtls_sha256_context ctx; mbedtls_sha256_init(&ctx); - mbedtls_sha256_starts_ret(&ctx, 0); + mbedtls_sha256_starts(&ctx, 0); // Ensure we maintain a clean state on exit. SCOPE_EXIT { @@ -168,7 +171,7 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function const size_t read_size = file->Read(buffer.data(), intended_read_size, processed_size); // Update the hash function with the buffer contents. - mbedtls_sha256_update_ret(&ctx, buffer.data(), read_size); + mbedtls_sha256_update(&ctx, buffer.data(), read_size); // Update counters. processed_size += read_size; @@ -181,7 +184,7 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function // Finalize context and compute the output hash. std::array output_hash; - mbedtls_sha256_finish_ret(&ctx, output_hash.data()); + mbedtls_sha256_finish(&ctx, output_hash.data()); // Compare to expected. if (std::memcmp(input_hash.data(), output_hash.data(), NcaSha256HalfHashLength) != 0) { diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 4439611d2e..35e76624f4 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -41,7 +44,14 @@ PerfStats::~PerfStats() { const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::LogDir); // %F Date format expanded is "%Y-%m-%d" - const auto filename = fmt::format("{:%F-%H-%M}_{:016X}.csv", *std::localtime(&t), title_id); + const auto filename = fmt::format("{}_{:016X}.csv", + [&] { + std::ostringstream oss; + oss << std::put_time(std::localtime(&t), "%F-%H-%M"); + return oss.str(); + }(), + title_id); + const auto filepath = path / filename; if (Common::FS::CreateParentDir(filepath)) { diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 4bac8142c3..1723636811 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -33,7 +36,9 @@ std::filesystem::path GetPath(std::string_view type, u64 title_id, std::string_v std::string GetTimestamp() { const auto time = std::time(nullptr); - return fmt::format("{:%FT%H-%M-%S}", *std::localtime(&time)); + std::ostringstream oss; + oss << std::put_time(std::localtime(&time), "%FT%H-%M-%S"); + return oss.str(); } using namespace nlohmann; diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt index e5934c941a..5166329156 100644 --- a/src/dedicated_room/CMakeLists.txt +++ b/src/dedicated_room/CMakeLists.txt @@ -20,7 +20,7 @@ if (ENABLE_WEB_SERVICE) target_link_libraries(yuzu-room PRIVATE web_service) endif() -target_link_libraries(yuzu-room PRIVATE mbedtls mbedcrypto) +target_link_libraries(yuzu-room PRIVATE MbedTLS::mbedcrypto MbedTLS::mbedtls) if (MSVC) target_link_libraries(yuzu-room PRIVATE getopt) endif() diff --git a/src/dynarmic/CMakeLists.txt b/src/dynarmic/CMakeLists.txt index 38457deb50..a9808391ae 100644 --- a/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/CMakeLists.txt @@ -27,7 +27,7 @@ endif() option(DYNARMIC_FATAL_ERRORS "Errors are fatal" OFF) option(DYNARMIC_IGNORE_ASSERTS "Ignore asserts" OFF) option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF) -option(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF) +CMAKE_DEPENDENT_OPTION(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF "NOT YUZU_DISABLE_LLVM" OFF) if (PLATFORM_OPENBSD) option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF) diff --git a/src/dynarmic/docs/Design.md b/src/dynarmic/docs/Design.md index 3c0deb5972..ffa8ccecdb 100644 --- a/src/dynarmic/docs/Design.md +++ b/src/dynarmic/docs/Design.md @@ -273,52 +273,73 @@ Exclusive OR (i.e.: XOR) ### Callback: {Read,Write}Memory{8,16,32,64} - ReadMemory8( vaddr) - ReadMemory16( vaddr) - ReadMemory32( vaddr) - ReadMemory64( vaddr) - WriteMemory8( vaddr, value_to_store) - WriteMemory16( vaddr, value_to_store) - WriteMemory32( vaddr, value_to_store) - WriteMemory64( vaddr, value_to_store) +```c++ + ReadMemory8( vaddr) + ReadMemory16( vaddr) + ReadMemory32( vaddr) + ReadMemory64( vaddr) + WriteMemory8( vaddr, value_to_store) + WriteMemory16( vaddr, value_to_store) + WriteMemory32( vaddr, value_to_store) + WriteMemory64( vaddr, value_to_store) +``` Memory access. ### Terminal: Interpret - SetTerm(IR::Term::Interpret{next}) +```c++ +SetTerm(IR::Term::Interpret{next}) +``` This terminal instruction calls the interpreter, starting at `next`. The interpreter must interpret exactly one instruction. ### Terminal: ReturnToDispatch - SetTerm(IR::Term::ReturnToDispatch{}) +```c++ +SetTerm(IR::Term::ReturnToDispatch{}) +``` This terminal instruction returns control to the dispatcher. The dispatcher will use the value in R15 to determine what comes next. ### Terminal: LinkBlock - SetTerm(IR::Term::LinkBlock{next}) +```c++ +SetTerm(IR::Term::LinkBlock{next}) +``` This terminal instruction jumps to the basic block described by `next` if we have enough cycles remaining. If we do not have enough cycles remaining, we return to the dispatcher, which will return control to the host. +### Terminal: LinkBlockFast + +```c++ +SetTerm(IR::Term::LinkBlockFast{next}) +``` + +This terminal instruction jumps to the basic block described by `next` unconditionally. +This promises guarantees that must be held at runtime - i.e that the program wont hang, + ### Terminal: PopRSBHint - SetTerm(IR::Term::PopRSBHint{}) +```c++ +SetTerm(IR::Term::PopRSBHint{}) +``` This terminal instruction checks the top of the Return Stack Buffer against R15. If RSB lookup fails, control is returned to the dispatcher. This is an optimization for faster function calls. A backend that doesn't support this optimization or doesn't have a RSB may choose to implement this exactly as -ReturnToDispatch. +`ReturnToDispatch`. ### Terminal: If - SetTerm(IR::Term::If{cond, term_then, term_else}) +```c++ +SetTerm(IR::Term::If{cond, term_then, term_else}) +``` This terminal instruction conditionally executes one terminal or another depending on the run-time state of the ARM flags. diff --git a/src/dynarmic/docs/FastMemory.md b/src/dynarmic/docs/FastMemory.md new file mode 100644 index 0000000000..c4f57996ba --- /dev/null +++ b/src/dynarmic/docs/FastMemory.md @@ -0,0 +1,19 @@ +# Fast memory (Fastmem) + +The main way of accessing memory in JITed programs is via an invoked function, say "Read()" and "Write()". On our translator, such functions usually take a sizable amounts of code space (push + call + pop). Trash the i-cache (due to an indirect call) and overall make code emission more bloated. + +The solution? Delegate invalid accesses to a dedicated arena, similar to a swap. The main idea behind such mechanism is to allow the OS to transmit page faults from invalid accesses into the JIT translator directly, bypassing address space calls, while this sacrifices i-cache coherency, it allows for smaller code-size and "faster" throguhput. + +Many kernels however, do not support fast signal dispatching (Solaris, OpenBSD, FreeBSD). Only Linux and Windows support relatively "fast" signal dispatching. Hence this feature is better suited for them only. + + + + + +In x86_64 for example, when a page fault occurs, the CPU will transmit via control registers and the stack (see `IRETQ`) the appropriate arguments for a page fault handler, the OS then will transform that into something that can be sent into userspace. + +Most modern OSes implement kernel-page-table-isolation, which means a set of system calls will invoke a context switch (not often used syscalls), whereas others are handled by the same process address space (the smaller kernel portion, often used syscalls) without needing a context switch. This effect can be negated on systems with PCID (up to 4096 unique IDs). + +Signal dispatching takes a performance hit from reloading `%cr3` - but Linux does something more clever to avoid reloads: VDSO will take care of the entire thing in the same address space. Making dispatching as costly as an indirect call - without the hazards of increased code size. + +The main downside from this is the constant i-cache trashing and pipeline hazards introduced by the VDSO signal handlers. However on most benchmarks fastmem does perform faster than without (Linux only). This also abuses the fact of continous address space emulation by using an arena - which can then be potentially transparently mapped into a hugepage, reducing TLB walk times. diff --git a/src/dynarmic/docs/Fastmem.svg b/src/dynarmic/docs/Fastmem.svg new file mode 100644 index 0000000000..a3ed0bb68b --- /dev/null +++ b/src/dynarmic/docs/Fastmem.svg @@ -0,0 +1,4 @@ + + + +EmulatorAddress SpaceGuest Address SpaceSIGSEGV TrapFastmemOnly needs to linearly offset from fastmem arenaLess codegen (SIGSEGV traps)Is fast only if SIGSEGV handlers are sufficiently fast \ No newline at end of file diff --git a/src/dynarmic/docs/HostToGuest.svg b/src/dynarmic/docs/HostToGuest.svg new file mode 100644 index 0000000000..6a15a44b46 --- /dev/null +++ b/src/dynarmic/docs/HostToGuest.svg @@ -0,0 +1,4 @@ + + + +EmulatorAddress SpaceGuest Address SpaceResolverHost to Guest translationLooks up correct PTETranslates each address Is slow \ No newline at end of file diff --git a/src/dynarmic/docs/RegisterAllocator.md b/src/dynarmic/docs/RegisterAllocator.md index fea6f19e6a..f5bbaaf168 100644 --- a/src/dynarmic/docs/RegisterAllocator.md +++ b/src/dynarmic/docs/RegisterAllocator.md @@ -16,19 +16,34 @@ Note that `Use`ing a value decrements its `use_count` by one. When the `use_coun The member functions on `RegAlloc` are just a combination of the above concepts. +The following registers are reserved for internal use and should NOT participate in register allocation: +- `%xmm0`, `%xmm1`, `%xmm2`: Used as scratch in exclusive memory access. +- `%rsp`: Stack pointer. +- `%r15`: JIT pointer +- `%r14`: Page table pointer. +- `%r13`: Fastmem pointer. + +The layout convenes `%r15` as the JIT state pointer - while it may be tempting to turn it into a synthetic pointer, keeping an entire register (out of 12 available) is preferable over inlining a directly computed immediate. + +Do NEVER modify `%r15`, we must make it clear that this register is "immutable" for the entirety of the JIT block duration. + ### `Scratch` - Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr) - Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm) +```c++ +Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr); +Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm); +``` At runtime, allocate one of the registers in `desired_locations`. You are free to modify the register. The register is discarded at the end of the allocation scope. ### Pure `Use` - Xbyak::Reg64 UseGpr(Argument& arg); - Xbyak::Xmm UseXmm(Argument& arg); - OpArg UseOpArg(Argument& arg); - void Use(Argument& arg, HostLoc host_loc); +```c++ +Xbyak::Reg64 UseGpr(Argument& arg); +Xbyak::Xmm UseXmm(Argument& arg); +OpArg UseOpArg(Argument& arg); +void Use(Argument& arg, HostLoc host_loc); +``` At runtime, the value corresponding to `arg` will be placed a register. The actual register is determined by which one of the above functions is called. `UseGpr` places it in an unused GPR, `UseXmm` places it @@ -39,9 +54,11 @@ This register **must not** have it's value changed. ### `UseScratch` - Xbyak::Reg64 UseScratchGpr(Argument& arg); - Xbyak::Xmm UseScratchXmm(Argument& arg); - void UseScratch(Argument& arg, HostLoc host_loc); +```c++ +Xbyak::Reg64 UseScratchGpr(Argument& arg); +Xbyak::Xmm UseScratchXmm(Argument& arg); +void UseScratch(Argument& arg, HostLoc host_loc); +``` At runtime, the value corresponding to `arg` will be placed a register. The actual register is determined by which one of the above functions is called. `UseScratchGpr` places it in an unused GPR, `UseScratchXmm` places it @@ -55,7 +72,9 @@ You are free to modify the value in the register. The register is discarded at t A `Define` is the defintion of a value. This is the only time when a value may be set. - void DefineValue(IR::Inst* inst, const Xbyak::Reg& reg); +```c++ +void DefineValue(IR::Inst* inst, const Xbyak::Reg& reg); +``` By calling `DefineValue`, you are stating that you wish to define the value for `inst`, and you have written the value to the specified register `reg`. @@ -64,7 +83,9 @@ value to the specified register `reg`. Adding a `Define` to an existing value. - void DefineValue(IR::Inst* inst, Argument& arg); +```c++ +void DefineValue(IR::Inst* inst, Argument& arg); +``` You are declaring that the value for `inst` is the same as the value for `arg`. No host machine instructions are emitted. diff --git a/src/dynarmic/docs/ReturnStackBufferOptimization.md b/src/dynarmic/docs/ReturnStackBufferOptimization.md index 6ffe41bcc6..0e72c3bce8 100644 --- a/src/dynarmic/docs/ReturnStackBufferOptimization.md +++ b/src/dynarmic/docs/ReturnStackBufferOptimization.md @@ -23,15 +23,17 @@ One complication dynarmic has is that a compiled block is not uniquely identifia the PC alone, but bits in the FPSCR and CPSR are also relevant. We resolve this by computing a 64-bit `UniqueHash` that is guaranteed to uniquely identify a block. - u64 LocationDescriptor::UniqueHash() const { - // This value MUST BE UNIQUE. - // This calculation has to match up with EmitX64::EmitTerminalPopRSBHint - u64 pc_u64 = u64(arm_pc) << 32; - u64 fpscr_u64 = u64(fpscr.Value()); - u64 t_u64 = cpsr.T() ? 1 : 0; - u64 e_u64 = cpsr.E() ? 2 : 0; - return pc_u64 | fpscr_u64 | t_u64 | e_u64; - } +```c++ +u64 LocationDescriptor::UniqueHash() const { + // This value MUST BE UNIQUE. + // This calculation has to match up with EmitX64::EmitTerminalPopRSBHint + u64 pc_u64 = u64(arm_pc) << 32; + u64 fpscr_u64 = u64(fpscr.Value()); + u64 t_u64 = cpsr.T() ? 1 : 0; + u64 e_u64 = cpsr.E() ? 2 : 0; + return pc_u64 | fpscr_u64 | t_u64 | e_u64; +} +``` ## Our implementation isn't actually a stack @@ -49,97 +51,107 @@ host addresses for the corresponding the compiled blocks. size of the real RSB in hardware (which has 3 entries). Larger RSBs than 8 showed degraded performance. - struct JitState { - // ... +```c++ +struct JitState { + // ... - static constexpr size_t RSBSize = 8; // MUST be a power of 2. - u32 rsb_ptr = 0; - std::array rsb_location_descriptors; - std::array rsb_codeptrs; - void ResetRSB(); + static constexpr size_t RSBSize = 8; // MUST be a power of 2. + u32 rsb_ptr = 0; + std::array rsb_location_descriptors; + std::array rsb_codeptrs; + void ResetRSB(); - // ... - }; + // ... +}; +``` ### RSB Push We insert our prediction at the insertion point iff the RSB doesn't already contain a prediction with the same `UniqueHash`. - void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) { - using namespace Xbyak::util; +```c++ +void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) { + using namespace Xbyak::util; - ASSERT(inst->GetArg(0).IsImmediate()); - u64 imm64 = inst->GetArg(0).GetU64(); + ASSERT(inst->GetArg(0).IsImmediate()); + u64 imm64 = inst->GetArg(0).GetU64(); - Xbyak::Reg64 code_ptr_reg = reg_alloc.ScratchGpr({HostLoc::RCX}); - Xbyak::Reg64 loc_desc_reg = reg_alloc.ScratchGpr(); - Xbyak::Reg32 index_reg = reg_alloc.ScratchGpr().cvt32(); - u64 code_ptr = unique_hash_to_code_ptr.find(imm64) != unique_hash_to_code_ptr.end() - ? u64(unique_hash_to_code_ptr[imm64]) - : u64(code->GetReturnFromRunCodeAddress()); + Xbyak::Reg64 code_ptr_reg = reg_alloc.ScratchGpr({HostLoc::RCX}); + Xbyak::Reg64 loc_desc_reg = reg_alloc.ScratchGpr(); + Xbyak::Reg32 index_reg = reg_alloc.ScratchGpr().cvt32(); + u64 code_ptr = unique_hash_to_code_ptr.find(imm64) != unique_hash_to_code_ptr.end() + ? u64(unique_hash_to_code_ptr[imm64]) + : u64(code->GetReturnFromRunCodeAddress()); - code->mov(index_reg, dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)]); - code->add(index_reg, 1); - code->and_(index_reg, u32(JitState::RSBSize - 1)); + code->mov(index_reg, dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)]); + code->add(index_reg, 1); + code->and_(index_reg, u32(JitState::RSBSize - 1)); - code->mov(loc_desc_reg, u64(imm64)); - CodePtr patch_location = code->getCurr(); - patch_unique_hash_locations[imm64].emplace_back(patch_location); - code->mov(code_ptr_reg, u64(code_ptr)); // This line has to match up with EmitX64::Patch. - code->EnsurePatchLocationSize(patch_location, 10); + code->mov(loc_desc_reg, u64(imm64)); + CodePtr patch_location = code->getCurr(); + patch_unique_hash_locations[imm64].emplace_back(patch_location); + code->mov(code_ptr_reg, u64(code_ptr)); // This line has to match up with EmitX64::Patch. + code->EnsurePatchLocationSize(patch_location, 10); - Xbyak::Label label; - for (size_t i = 0; i < JitState::RSBSize; ++i) { - code->cmp(loc_desc_reg, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]); - code->je(label, code->T_SHORT); - } - - code->mov(dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)], index_reg); - code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_location_descriptors)], loc_desc_reg); - code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_codeptrs)], code_ptr_reg); - code->L(label); + Xbyak::Label label; + for (size_t i = 0; i < JitState::RSBSize; ++i) { + code->cmp(loc_desc_reg, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]); + code->je(label, code->T_SHORT); } + code->mov(dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)], index_reg); + code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_location_descriptors)], loc_desc_reg); + code->mov(qword[code.ABI_JIT_PTR + index_reg.cvt64() * 8 + offsetof(JitState, rsb_codeptrs)], code_ptr_reg); + code->L(label); +} +``` + In pseudocode: - for (i := 0 .. RSBSize-1) - if (rsb_location_descriptors[i] == imm64) - goto label; - rsb_ptr++; - rsb_ptr %= RSBSize; - rsb_location_desciptors[rsb_ptr] = imm64; //< The UniqueHash - rsb_codeptr[rsb_ptr] = /* codeptr corresponding to the UniqueHash */; - label: +```c++ + for (i := 0 .. RSBSize-1) + if (rsb_location_descriptors[i] == imm64) + goto label; + rsb_ptr++; + rsb_ptr %= RSBSize; + rsb_location_desciptors[rsb_ptr] = imm64; //< The UniqueHash + rsb_codeptr[rsb_ptr] = /* codeptr corresponding to the UniqueHash */; +label: +``` ## RSB Pop To check if a predicition is in the RSB, we linearly scan the RSB. - void EmitX64::EmitTerminalPopRSBHint(IR::Term::PopRSBHint, IR::LocationDescriptor initial_location) { - using namespace Xbyak::util; +```c++ +void EmitX64::EmitTerminalPopRSBHint(IR::Term::PopRSBHint, IR::LocationDescriptor initial_location) { + using namespace Xbyak::util; - // This calculation has to match up with IREmitter::PushRSB - code->mov(ecx, MJitStateReg(Arm::Reg::PC)); - code->shl(rcx, 32); - code->mov(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, FPSCR_mode)]); - code->or_(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, CPSR_et)]); - code->or_(rbx, rcx); + // This calculation has to match up with IREmitter::PushRSB + code->mov(ecx, MJitStateReg(Arm::Reg::PC)); + code->shl(rcx, 32); + code->mov(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, FPSCR_mode)]); + code->or_(ebx, dword[code.ABI_JIT_PTR + offsetof(JitState, CPSR_et)]); + code->or_(rbx, rcx); - code->mov(rax, u64(code->GetReturnFromRunCodeAddress())); - for (size_t i = 0; i < JitState::RSBSize; ++i) { - code->cmp(rbx, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]); - code->cmove(rax, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_codeptrs) + i * sizeof(u64)]); - } - - code->jmp(rax); + code->mov(rax, u64(code->GetReturnFromRunCodeAddress())); + for (size_t i = 0; i < JitState::RSBSize; ++i) { + code->cmp(rbx, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]); + code->cmove(rax, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_codeptrs) + i * sizeof(u64)]); } + code->jmp(rax); +} +``` + In pseudocode: - rbx := ComputeUniqueHash() - rax := ReturnToDispatch - for (i := 0 .. RSBSize-1) - if (rbx == rsb_location_descriptors[i]) - rax = rsb_codeptrs[i] - goto rax \ No newline at end of file +```c++ +rbx := ComputeUniqueHash() +rax := ReturnToDispatch +for (i := 0 .. RSBSize-1) + if (rbx == rsb_location_descriptors[i]) + rax = rsb_codeptrs[i] +goto rax +``` diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index b74626bcd5..e8f8a6a767 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + include(TargetArchitectureSpecificSources) add_library(dynarmic diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp index 7695df57d2..d0653eceab 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp @@ -6,8 +6,13 @@ * SPDX-License-Identifier: 0BSD */ -#include "dynarmic/backend/exception_handler.h" - +#include +#include +#include +#include +#include +#include +#include #ifdef __APPLE__ # include # include @@ -21,17 +26,10 @@ # endif #endif -#include -#include -#include -#include -#include -#include +#include -#include "dynarmic/common/assert.h" -#include +#include "dynarmic/backend/exception_handler.h" #include "dynarmic/common/common_types.h" - #if defined(MCL_ARCHITECTURE_X86_64) # include "dynarmic/backend/x64/block_of_code.h" #elif defined(MCL_ARCHITECTURE_ARM64) @@ -43,42 +41,80 @@ #else # error "Invalid architecture" #endif +#include namespace Dynarmic::Backend { namespace { struct CodeBlockInfo { - u64 code_begin, code_end; + u64 size; std::function cb; }; class SigHandler { -public: - SigHandler(); - ~SigHandler(); - - void AddCodeBlock(CodeBlockInfo info); - void RemoveCodeBlock(u64 host_pc); - - bool SupportsFastmem() const { return supports_fast_mem; } - -private: - auto FindCodeBlockInfo(u64 host_pc) { - return std::find_if(code_block_infos.begin(), code_block_infos.end(), [&](const auto& x) { return x.code_begin <= host_pc && x.code_end > host_pc; }); + auto FindCodeBlockInfo(u64 offset) noexcept { + return std::find_if(code_block_infos.begin(), code_block_infos.end(), [&](auto const& e) { + return e.first <= offset && e.first + e.second.size > offset; + }); } + static void SigAction(int sig, siginfo_t* info, void* raw_context); bool supports_fast_mem = true; - void* signal_stack_memory = nullptr; - - std::vector code_block_infos; - std::mutex code_block_infos_mutex; - + ankerl::unordered_dense::map code_block_infos; + std::shared_mutex code_block_infos_mutex; struct sigaction old_sa_segv; struct sigaction old_sa_bus; + std::size_t signal_stack_size; +public: + SigHandler() noexcept { + signal_stack_size = std::max(SIGSTKSZ, 2 * 1024 * 1024); + signal_stack_memory = mmap(nullptr, signal_stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - static void SigAction(int sig, siginfo_t* info, void* raw_context); + stack_t signal_stack{}; + signal_stack.ss_sp = signal_stack_memory; + signal_stack.ss_size = signal_stack_size; + signal_stack.ss_flags = 0; + if (sigaltstack(&signal_stack, nullptr) != 0) { + fmt::print(stderr, "dynarmic: POSIX SigHandler: init failure at sigaltstack\n"); + supports_fast_mem = false; + return; + } + + struct sigaction sa{}; + sa.sa_handler = nullptr; + sa.sa_sigaction = &SigHandler::SigAction; + sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) { + fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGSEGV handler\n"); + supports_fast_mem = false; + return; + } +#ifdef __APPLE__ + if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) { + fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGBUS handler\n"); + supports_fast_mem = false; + return; + } +#endif + } + + ~SigHandler() noexcept { + munmap(signal_stack_memory, signal_stack_size); + } + + void AddCodeBlock(u64 offset, CodeBlockInfo cbi) noexcept { + std::unique_lock guard(code_block_infos_mutex); + code_block_infos.insert_or_assign(offset, cbi); + } + void RemoveCodeBlock(u64 offset) noexcept { + std::unique_lock guard(code_block_infos_mutex); + code_block_infos.erase(offset); + } + + bool SupportsFastmem() const noexcept { return supports_fast_mem; } }; std::mutex handler_lock; @@ -91,64 +127,8 @@ void RegisterHandler() { } } -SigHandler::SigHandler() { - const size_t signal_stack_size = std::max(SIGSTKSZ, 2 * 1024 * 1024); - - signal_stack_memory = std::malloc(signal_stack_size); - - stack_t signal_stack; - signal_stack.ss_sp = signal_stack_memory; - signal_stack.ss_size = signal_stack_size; - signal_stack.ss_flags = 0; - if (sigaltstack(&signal_stack, nullptr) != 0) { - fmt::print(stderr, "dynarmic: POSIX SigHandler: init failure at sigaltstack\n"); - supports_fast_mem = false; - return; - } - - struct sigaction sa; - sa.sa_handler = nullptr; - sa.sa_sigaction = &SigHandler::SigAction; - sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) { - fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGSEGV handler\n"); - supports_fast_mem = false; - return; - } -#ifdef __APPLE__ - if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) { - fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGBUS handler\n"); - supports_fast_mem = false; - return; - } -#endif -} - -SigHandler::~SigHandler() { - std::free(signal_stack_memory); -} - -void SigHandler::AddCodeBlock(CodeBlockInfo cbi) { - std::lock_guard guard(code_block_infos_mutex); - if (auto iter = FindCodeBlockInfo(cbi.code_begin); iter != code_block_infos.end()) { - code_block_infos.erase(iter); - } - code_block_infos.push_back(cbi); -} - -void SigHandler::RemoveCodeBlock(u64 host_pc) { - std::lock_guard guard(code_block_infos_mutex); - const auto iter = FindCodeBlockInfo(host_pc); - if (iter == code_block_infos.end()) { - return; - } - code_block_infos.erase(iter); -} - void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { - ASSERT(sig == SIGSEGV || sig == SIGBUS); - + DEBUG_ASSERT(sig == SIGSEGV || sig == SIGBUS); #ifndef MCL_ARCHITECTURE_RISCV ucontext_t* ucontext = reinterpret_cast(raw_context); #ifndef __OpenBSD__ @@ -157,7 +137,6 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { #endif #if defined(MCL_ARCHITECTURE_X86_64) - # if defined(__APPLE__) # define CTX_RIP (mctx->__ss.__rip) # define CTX_RSP (mctx->__ss.__rsp) @@ -179,26 +158,18 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { # else # error "Unknown platform" # endif - { - std::lock_guard guard(sig_handler->code_block_infos_mutex); - - const auto iter = sig_handler->FindCodeBlockInfo(CTX_RIP); - if (iter != sig_handler->code_block_infos.end()) { - FakeCall fc = iter->cb(CTX_RIP); - + std::shared_lock guard(sig_handler->code_block_infos_mutex); + if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_RIP); iter != sig_handler->code_block_infos.end()) { + FakeCall fc = iter->second.cb(CTX_RIP); CTX_RSP -= sizeof(u64); *mcl::bit_cast(CTX_RSP) = fc.ret_rip; CTX_RIP = fc.call_rip; - return; } } - fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_RIP); - #elif defined(MCL_ARCHITECTURE_ARM64) - # if defined(__APPLE__) # define CTX_PC (mctx->__ss.__pc) # define CTX_SP (mctx->__ss.__sp) @@ -240,30 +211,19 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { # else # error "Unknown platform" # endif - { - std::lock_guard guard(sig_handler->code_block_infos_mutex); - - const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); - if (iter != sig_handler->code_block_infos.end()) { - FakeCall fc = iter->cb(CTX_PC); - + std::shared_lock guard(sig_handler->code_block_infos_mutex); + if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) { + FakeCall fc = iter->second.cb(CTX_PC); CTX_PC = fc.call_pc; - return; } } - fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC); - #elif defined(MCL_ARCHITECTURE_RISCV) - ASSERT_FALSE("Unimplemented"); - #else - # error "Invalid architecture" - #endif struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus; @@ -284,26 +244,26 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { } // anonymous namespace struct ExceptionHandler::Impl final { - Impl(u64 code_begin_, u64 code_end_) - : code_begin(code_begin_) - , code_end(code_end_) { + Impl(u64 offset_, u64 size_) + : offset(offset_) + , size(size_) { RegisterHandler(); } void SetCallback(std::function cb) { - CodeBlockInfo cbi; - cbi.code_begin = code_begin; - cbi.code_end = code_end; - cbi.cb = cb; - sig_handler->AddCodeBlock(cbi); + sig_handler->AddCodeBlock(offset, CodeBlockInfo{ + .size = size, + .cb = cb + }); } ~Impl() { - sig_handler->RemoveCodeBlock(code_begin); + sig_handler->RemoveCodeBlock(offset); } private: - u64 code_begin, code_end; + u64 offset; + u64 size; }; ExceptionHandler::ExceptionHandler() = default; @@ -311,28 +271,22 @@ ExceptionHandler::~ExceptionHandler() = default; #if defined(MCL_ARCHITECTURE_X86_64) void ExceptionHandler::Register(X64::BlockOfCode& code) { - const u64 code_begin = mcl::bit_cast(code.getCode()); - const u64 code_end = code_begin + code.GetTotalCodeSize(); - impl = std::make_unique(code_begin, code_end); + impl = std::make_unique(mcl::bit_cast(code.getCode()), code.GetTotalCodeSize()); } #elif defined(MCL_ARCHITECTURE_ARM64) void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) { - const u64 code_begin = mcl::bit_cast(mem.ptr()); - const u64 code_end = code_begin + size; - impl = std::make_unique(code_begin, code_end); + impl = std::make_unique(mcl::bit_cast(mem.ptr()), size); } #elif defined(MCL_ARCHITECTURE_RISCV) void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) { - const u64 code_begin = mcl::bit_cast(mem.ptr()); - const u64 code_end = code_begin + size; - impl = std::make_unique(code_begin, code_end); + impl = std::make_unique(mcl::bit_cast(mem.ptr()), size); } #else # error "Invalid architecture" #endif bool ExceptionHandler::SupportsFastmem() const noexcept { - return static_cast(impl) && sig_handler->SupportsFastmem(); + return bool(impl) && sig_handler->SupportsFastmem(); } void ExceptionHandler::SetFastmemCallback(std::function cb) { diff --git a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp index c949ed7de8..da50179de9 100644 --- a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp +++ b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2022 MerryMage * SPDX-License-Identifier: 0BSD diff --git a/src/frontend_common/firmware_manager.h b/src/frontend_common/firmware_manager.h index 20f3b41478..23fce59eb3 100644 --- a/src/frontend_common/firmware_manager.h +++ b/src/frontend_common/firmware_manager.h @@ -7,6 +7,7 @@ #include "common/common_types.h" #include "core/core.h" #include "core/file_sys/nca_metadata.h" +#include "core/file_sys/content_archive.h" #include "core/file_sys/registered_cache.h" #include "core/hle/service/filesystem/filesystem.h" #include @@ -143,6 +144,8 @@ inline std::pair GetFirmwareVersion return {firmware_data, result}; } + +// TODO(crueter): GET AS STRING } -#endif // FIRMWARE_MANAGER_H +#endif diff --git a/src/hid_core/frontend/emulated_controller.cpp b/src/hid_core/frontend/emulated_controller.cpp index 8a6922c49f..e2925c0265 100644 --- a/src/hid_core/frontend/emulated_controller.cpp +++ b/src/hid_core/frontend/emulated_controller.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/hid_core/hidbus/ringcon.cpp b/src/hid_core/hidbus/ringcon.cpp index a2bfd82636..1927a6f856 100644 --- a/src/hid_core/hidbus/ringcon.cpp +++ b/src/hid_core/hidbus/ringcon.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/hid_core/irsensor/image_transfer_processor.cpp b/src/hid_core/irsensor/image_transfer_processor.cpp index 9040390946..fb3e424d91 100644 --- a/src/hid_core/irsensor/image_transfer_processor.cpp +++ b/src/hid_core/irsensor/image_transfer_processor.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp index b3e17b389d..d5f37247e1 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp index e4166b3735..36deb25c94 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp index 4367dcaa56..16ec2257fb 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp index b4375e57f3..813d3d3188 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp index accbfe0def..2b763d8e0f 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp index 7a47786d42..80f5f3ba62 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp index 39906fe33f..d7cf2bba9b 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad_holder.cpp b/src/hid_core/resources/abstracted_pad/abstract_pad_holder.cpp index 80f86459b9..d9b20ecb66 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_pad_holder.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_pad_holder.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp index c10d0c4070..7766bedfd0 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp index 90c46cbe8c..c225670043 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp index 10c00ef95c..a8d2e5b2a0 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp index 07a35b2147..3266422133 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/applet_resource.cpp b/src/hid_core/resources/applet_resource.cpp index a533ca4319..31480a0e90 100644 --- a/src/hid_core/resources/applet_resource.cpp +++ b/src/hid_core/resources/applet_resource.cpp @@ -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-3.0-or-later diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp index f1f5ee5e9f..a0f72ab298 100644 --- a/src/hid_core/resources/npad/npad.cpp +++ b/src/hid_core/resources/npad/npad.cpp @@ -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 diff --git a/src/hid_core/resources/npad/npad_data.cpp b/src/hid_core/resources/npad/npad_data.cpp index fbcc3ef89a..a4b46a1ecf 100644 --- a/src/hid_core/resources/npad/npad_data.cpp +++ b/src/hid_core/resources/npad/npad_data.cpp @@ -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-3.0-or-later diff --git a/src/hid_core/resources/npad/npad_resource.cpp b/src/hid_core/resources/npad/npad_resource.cpp index 21a514dce6..08546f8dc4 100644 --- a/src/hid_core/resources/npad/npad_resource.cpp +++ b/src/hid_core/resources/npad/npad_resource.cpp @@ -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-3.0-or-later diff --git a/src/hid_core/resources/palma/palma.cpp b/src/hid_core/resources/palma/palma.cpp index 9210b456e2..0652455f5f 100644 --- a/src/hid_core/resources/palma/palma.cpp +++ b/src/hid_core/resources/palma/palma.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/hid_core/resources/touch_screen/gesture_handler.cpp b/src/hid_core/resources/touch_screen/gesture_handler.cpp index 6309019796..8e5ed8ff7e 100644 --- a/src/hid_core/resources/touch_screen/gesture_handler.cpp +++ b/src/hid_core/resources/touch_screen/gesture_handler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/hid_core/resources/touch_screen/touch_screen_resource.cpp b/src/hid_core/resources/touch_screen/touch_screen_resource.cpp index 51b94b2466..5d45f861c6 100644 --- a/src/hid_core/resources/touch_screen/touch_screen_resource.cpp +++ b/src/hid_core/resources/touch_screen/touch_screen_resource.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp index 34bf877bf5..0949e1e2ad 100644 --- a/src/input_common/drivers/mouse.cpp +++ b/src/input_common/drivers/mouse.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp index df1819904b..fea33335ae 100644 --- a/src/input_common/drivers/udp_client.cpp +++ b/src/input_common/drivers/udp_client.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2018 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/input_common/helpers/joycon_protocol/calibration.cpp b/src/input_common/helpers/joycon_protocol/calibration.cpp index 057bf29f71..105172c352 100644 --- a/src/input_common/helpers/joycon_protocol/calibration.cpp +++ b/src/input_common/helpers/joycon_protocol/calibration.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/input_common/helpers/joycon_protocol/nfc.cpp b/src/input_common/helpers/joycon_protocol/nfc.cpp index bfdaa74a62..67f789edd8 100644 --- a/src/input_common/helpers/joycon_protocol/nfc.cpp +++ b/src/input_common/helpers/joycon_protocol/nfc.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/input_common/helpers/joycon_protocol/rumble.cpp b/src/input_common/helpers/joycon_protocol/rumble.cpp index db3420dc0b..62ad0fada0 100644 --- a/src/input_common/helpers/joycon_protocol/rumble.cpp +++ b/src/input_common/helpers/joycon_protocol/rumble.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/network/announce_multiplayer_session.h b/src/network/announce_multiplayer_session.h index 9d9673d97a..4e5cd33e1f 100644 --- a/src/network/announce_multiplayer_session.h +++ b/src/network/announce_multiplayer_session.h @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once diff --git a/src/network/network.cpp b/src/network/network.cpp index 0314b51d2c..7d04c2241e 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #include "common/assert.h" #include "common/logging/log.h" diff --git a/src/network/network.h b/src/network/network.h index 1e1a19a3b9..84db8d6d17 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -1,8 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt new file mode 100644 index 0000000000..eb36de4cf2 --- /dev/null +++ b/src/qt_common/CMakeLists.txt @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: Copyright 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 + +find_package(Qt6 REQUIRED COMPONENTS Core) +find_package(Qt6 REQUIRED COMPONENTS Core) + +add_library(qt_common STATIC + qt_common.h + qt_common.cpp + + uisettings.cpp + uisettings.h + + qt_config.cpp + qt_config.h + + shared_translation.cpp + shared_translation.h + qt_path_util.h qt_path_util.cpp + qt_game_util.h qt_game_util.cpp + qt_frontend_util.h qt_frontend_util.cpp + qt_meta.h qt_meta.cpp + qt_content_util.h qt_content_util.cpp + qt_rom_util.h qt_rom_util.cpp + qt_applet_util.h qt_applet_util.cpp + qt_progress_dialog.h qt_progress_dialog.cpp + +) + +create_target_directory_groups(qt_common) + +# TODO(crueter) +if (ENABLE_QT) + target_link_libraries(qt_common PRIVATE Qt6::Widgets) +endif() + +add_subdirectory(externals) + +target_link_libraries(qt_common PRIVATE core Qt6::Core SimpleIni::SimpleIni QuaZip::QuaZip frozen::frozen) + +if (NOT APPLE AND ENABLE_OPENGL) + target_compile_definitions(qt_common PUBLIC HAS_OPENGL) +endif() + +if (NOT WIN32) + target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) +endif() diff --git a/src/yuzu/externals/CMakeLists.txt b/src/qt_common/externals/CMakeLists.txt similarity index 86% rename from src/yuzu/externals/CMakeLists.txt rename to src/qt_common/externals/CMakeLists.txt index 50594a741f..189a52c0a6 100644 --- a/src/yuzu/externals/CMakeLists.txt +++ b/src/qt_common/externals/CMakeLists.txt @@ -14,3 +14,7 @@ set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON) # QuaZip AddJsonPackage(quazip) + +# frozen +# TODO(crueter): Qt String Lookup +AddJsonPackage(frozen) diff --git a/src/yuzu/externals/cpmfile.json b/src/qt_common/externals/cpmfile.json similarity index 55% rename from src/yuzu/externals/cpmfile.json rename to src/qt_common/externals/cpmfile.json index e3590d0f7f..0b464b95b2 100644 --- a/src/yuzu/externals/cpmfile.json +++ b/src/qt_common/externals/cpmfile.json @@ -8,5 +8,12 @@ "options": [ "QUAZIP_INSTALL OFF" ] + }, + "frozen": { + "package": "frozen", + "repo": "serge-sans-paille/frozen", + "sha": "61dce5ae18", + "hash": "1ae3d073e659c1f24b2cdd76379c90d6af9e06bc707d285a4fafce05f7a4c9e592ff208c94a9ae0f0d07620b3c6cec191f126b03d70ad4dfa496a86ed5658a6d", + "bundled": true } } diff --git a/src/qt_common/qt_applet_util.cpp b/src/qt_common/qt_applet_util.cpp new file mode 100644 index 0000000000..1b0189392e --- /dev/null +++ b/src/qt_common/qt_applet_util.cpp @@ -0,0 +1,4 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_applet_util.h" diff --git a/src/qt_common/qt_applet_util.h b/src/qt_common/qt_applet_util.h new file mode 100644 index 0000000000..2b48d16698 --- /dev/null +++ b/src/qt_common/qt_applet_util.h @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef QT_APPLET_UTIL_H +#define QT_APPLET_UTIL_H + +// TODO +namespace QtCommon::Applets { + +} +#endif // QT_APPLET_UTIL_H diff --git a/src/yuzu/qt_common.cpp b/src/qt_common/qt_common.cpp similarity index 55% rename from src/yuzu/qt_common.cpp rename to src/qt_common/qt_common.cpp index 413402165c..6be241c740 100644 --- a/src/yuzu/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -1,12 +1,19 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_common.h" +#include "common/fs/fs.h" #include #include -#include #include "common/logging/log.h" #include "core/frontend/emu_window.h" -#include "yuzu/qt_common.h" + +#include + +#include + +#include #if !defined(WIN32) && !defined(__APPLE__) #include @@ -15,7 +22,19 @@ #endif namespace QtCommon { -Core::Frontend::WindowSystemType GetWindowSystemType() { + +#ifdef YUZU_QT_WIDGETS +QWidget* rootObject = nullptr; +#else +QObject* rootObject = nullptr; +#endif + +std::unique_ptr system = nullptr; +std::shared_ptr vfs = nullptr; +std::unique_ptr provider = nullptr; + +Core::Frontend::WindowSystemType GetWindowSystemType() +{ // Determine WSI type based on Qt platform. QString platform_name = QGuiApplication::platformName(); if (platform_name == QStringLiteral("windows")) @@ -35,7 +54,8 @@ Core::Frontend::WindowSystemType GetWindowSystemType() { return Core::Frontend::WindowSystemType::Windows; } // namespace Core::Frontend::WindowSystemType -Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) { +Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) +{ Core::Frontend::EmuWindow::WindowSystemInfo wsi; wsi.type = GetWindowSystemType(); @@ -43,8 +63,8 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) // Our Win32 Qt external doesn't have the private API. wsi.render_surface = reinterpret_cast(window->winId()); #elif defined(__APPLE__) - wsi.render_surface = reinterpret_cast(objc_msgSend)( - reinterpret_cast(window->winId()), sel_registerName("layer")); + wsi.render_surface = reinterpret_cast( + objc_msgSend)(reinterpret_cast(window->winId()), sel_registerName("layer")); #else QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); wsi.display_connection = pni->nativeResourceForWindow("display", window); @@ -57,4 +77,46 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) return wsi; } + +const QString tr(const char* str) +{ + return QGuiApplication::tr(str); +} + +const QString tr(const std::string& str) +{ + return QGuiApplication::tr(str.c_str()); +} + +#ifdef YUZU_QT_WIDGETS +void Init(QWidget* root) +#else +void Init(QObject* root) +#endif +{ + system = std::make_unique(); + rootObject = root; + vfs = std::make_unique(); + provider = std::make_unique(); +} + +std::filesystem::path GetEdenCommand() { + std::filesystem::path command; + + QString appimage = QString::fromLocal8Bit(getenv("APPIMAGE")); + if (!appimage.isEmpty()) { + command = std::filesystem::path{appimage.toStdString()}; + } else { + const QStringList args = QGuiApplication::arguments(); + command = args[0].toStdString(); + } + + // If relative path, make it an absolute path + if (command.c_str()[0] == '.') { + command = Common::FS::GetCurrentDir() / command; + } + + return command; +} + } // namespace QtCommon diff --git a/src/qt_common/qt_common.h b/src/qt_common/qt_common.h new file mode 100644 index 0000000000..a2700427ab --- /dev/null +++ b/src/qt_common/qt_common.h @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef QT_COMMON_H +#define QT_COMMON_H + +#include +#include "core/core.h" +#include "core/file_sys/registered_cache.h" +#include +#include + +#include + +namespace QtCommon { + +#ifdef YUZU_QT_WIDGETS +extern QWidget *rootObject; +#else +extern QObject *rootObject; +#endif + +extern std::unique_ptr system; +extern std::shared_ptr vfs; +extern std::unique_ptr provider; + +typedef std::function QtProgressCallback; + +Core::Frontend::WindowSystemType GetWindowSystemType(); + +Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window); + +#ifdef YUZU_QT_WIDGETS +void Init(QWidget *root); +#else +void Init(QObject *root); +#endif + +const QString tr(const char *str); +const QString tr(const std::string &str); + +std::filesystem::path GetEdenCommand(); +} // namespace QtCommon +#endif diff --git a/src/yuzu/configuration/qt_config.cpp b/src/qt_common/qt_config.cpp similarity index 99% rename from src/yuzu/configuration/qt_config.cpp rename to src/qt_common/qt_config.cpp index ae5b330e23..f787873cf6 100644 --- a/src/yuzu/configuration/qt_config.cpp +++ b/src/qt_common/qt_config.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 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 diff --git a/src/yuzu/configuration/qt_config.h b/src/qt_common/qt_config.h similarity index 94% rename from src/yuzu/configuration/qt_config.h rename to src/qt_common/qt_config.h index dc2dceb4d7..a8c80dd273 100644 --- a/src/yuzu/configuration/qt_config.h +++ b/src/qt_common/qt_config.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 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 diff --git a/src/qt_common/qt_content_util.cpp b/src/qt_common/qt_content_util.cpp new file mode 100644 index 0000000000..e4625aa423 --- /dev/null +++ b/src/qt_common/qt_content_util.cpp @@ -0,0 +1,313 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_content_util.h" +#include "common/fs/fs.h" +#include "frontend_common/content_manager.h" +#include "frontend_common/firmware_manager.h" +#include "qt_common/qt_common.h" +#include "qt_common/qt_progress_dialog.h" +#include "qt_frontend_util.h" + +#include + +namespace QtCommon::Content { + +bool CheckGameFirmware(u64 program_id, QObject* parent) +{ + if (FirmwareManager::GameRequiresFirmware(program_id) + && !FirmwareManager::CheckFirmwarePresence(*system)) { + auto result = QtCommon::Frontend::ShowMessage( + QMessageBox::Warning, + "Game Requires Firmware", + "The game you are trying to launch requires firmware to boot or to get past the " + "opening menu. Please " + "dump and install firmware, or press \"OK\" to launch anyways.", + QMessageBox::Ok | QMessageBox::Cancel, + parent); + + return result == QMessageBox::Ok; + } + + return true; +} + +void InstallFirmware(const QString& location, bool recursive) +{ + QtCommon::Frontend::QtProgressDialog progress(tr("Installing Firmware..."), + tr("Cancel"), + 0, + 100, + rootObject); + progress.setWindowModality(Qt::WindowModal); + progress.setMinimumDuration(100); + progress.setAutoClose(false); + progress.setAutoReset(false); + progress.show(); + + // Declare progress callback. + auto callback = [&](size_t total_size, size_t processed_size) { + progress.setValue(static_cast((processed_size * 100) / total_size)); + return progress.wasCanceled(); + }; + + static constexpr const char* failedTitle = "Firmware Install Failed"; + static constexpr const char* successTitle = "Firmware Install Succeeded"; + QMessageBox::Icon icon; + FirmwareInstallResult result; + + const auto ShowMessage = [&]() { + QtCommon::Frontend::ShowMessage(icon, + failedTitle, + GetFirmwareInstallResultString(result)); + }; + + LOG_INFO(Frontend, "Installing firmware from {}", location.toStdString()); + + // Check for a reasonable number of .nca files (don't hardcode them, just see if there's some in + // there.) + std::filesystem::path firmware_source_path = location.toStdString(); + if (!Common::FS::IsDir(firmware_source_path)) { + return; + } + + std::vector out; + const Common::FS::DirEntryCallable dir_callback = + [&out](const std::filesystem::directory_entry& entry) { + if (entry.path().has_extension() && entry.path().extension() == ".nca") { + out.emplace_back(entry.path()); + } + + return true; + }; + + callback(100, 10); + + if (recursive) { + Common::FS::IterateDirEntriesRecursively(firmware_source_path, + dir_callback, + Common::FS::DirEntryFilter::File); + } else { + Common::FS::IterateDirEntries(firmware_source_path, + dir_callback, + Common::FS::DirEntryFilter::File); + } + + if (out.size() <= 0) { + result = FirmwareInstallResult::NoNCAs; + icon = QMessageBox::Warning; + ShowMessage(); + return; + } + + // Locate and erase the content of nand/system/Content/registered/*.nca, if any. + auto sysnand_content_vdir = system->GetFileSystemController().GetSystemNANDContentDirectory(); + if (sysnand_content_vdir->IsWritable() + && !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) { + result = FirmwareInstallResult::FailedDelete; + icon = QMessageBox::Critical; + ShowMessage(); + return; + } + + LOG_INFO(Frontend, + "Cleaned nand/system/Content/registered folder in preparation for new firmware."); + + callback(100, 20); + + auto firmware_vdir = sysnand_content_vdir->GetDirectoryRelative("registered"); + + bool success = true; + int i = 0; + for (const auto& firmware_src_path : out) { + i++; + auto firmware_src_vfile = vfs->OpenFile(firmware_src_path.generic_string(), + FileSys::OpenMode::Read); + auto firmware_dst_vfile = firmware_vdir + ->CreateFileRelative(firmware_src_path.filename().string()); + + if (!VfsRawCopy(firmware_src_vfile, firmware_dst_vfile)) { + LOG_ERROR(Frontend, + "Failed to copy firmware file {} to {} in registered folder!", + firmware_src_path.generic_string(), + firmware_src_path.filename().string()); + success = false; + } + + if (callback(100, 20 + static_cast(((i) / static_cast(out.size())) * 70.0))) { + result = FirmwareInstallResult::FailedCorrupted; + icon = QMessageBox::Warning; + ShowMessage(); + return; + } + } + + if (!success) { + result = FirmwareInstallResult::FailedCopy; + icon = QMessageBox::Critical; + ShowMessage(); + return; + } + + // Re-scan VFS for the newly placed firmware files. + system->GetFileSystemController().CreateFactories(*vfs); + + auto VerifyFirmwareCallback = [&](size_t total_size, size_t processed_size) { + progress.setValue(90 + static_cast((processed_size * 10) / total_size)); + return progress.wasCanceled(); + }; + + auto results = ContentManager::VerifyInstalledContents(*QtCommon::system, + *QtCommon::provider, + VerifyFirmwareCallback, + true); + + if (results.size() > 0) { + const auto failed_names = QString::fromStdString( + fmt::format("{}", fmt::join(results, "\n"))); + progress.close(); + QtCommon::Frontend::Critical(tr("Firmware integrity verification failed!"), + tr("Verification failed for the following files:\n\n%1") + .arg(failed_names)); + return; + } + + progress.close(); + + const auto pair = FirmwareManager::GetFirmwareVersion(*system); + const auto firmware_data = pair.first; + const std::string display_version(firmware_data.display_version.data()); + + result = FirmwareInstallResult::Success; + QtCommon::Frontend::Information(rootObject, + tr(successTitle), + tr(GetFirmwareInstallResultString(result)) + .arg(QString::fromStdString(display_version))); +} + +QString UnzipFirmwareToTmp(const QString& location) +{ + namespace fs = std::filesystem; + fs::path tmp{fs::temp_directory_path()}; + + if (!fs::create_directories(tmp / "eden" / "firmware")) { + return ""; + } + + tmp /= "eden"; + tmp /= "firmware"; + + QString qCacheDir = QString::fromStdString(tmp.string()); + + QFile zip(location); + + QStringList result = JlCompress::extractDir(&zip, qCacheDir); + if (result.isEmpty()) { + return ""; + } + + return qCacheDir; +} + +// Content // +void VerifyGameContents(const std::string& game_path) +{ + QtCommon::Frontend::QtProgressDialog progress(tr("Verifying integrity..."), + tr("Cancel"), + 0, + 100, + rootObject); + progress.setWindowModality(Qt::WindowModal); + progress.setMinimumDuration(100); + progress.setAutoClose(false); + progress.setAutoReset(false); + + const auto callback = [&](size_t total_size, size_t processed_size) { + progress.setValue(static_cast((processed_size * 100) / total_size)); + return progress.wasCanceled(); + }; + + const auto result = ContentManager::VerifyGameContents(*system, game_path, callback); + + switch (result) { + case ContentManager::GameVerificationResult::Success: + QtCommon::Frontend::Information(rootObject, + tr("Integrity verification succeeded!"), + tr("The operation completed successfully.")); + break; + case ContentManager::GameVerificationResult::Failed: + QtCommon::Frontend::Critical(rootObject, + tr("Integrity verification failed!"), + tr("File contents may be corrupt or missing.")); + break; + case ContentManager::GameVerificationResult::NotImplemented: + QtCommon::Frontend::Warning( + rootObject, + tr("Integrity verification couldn't be performed"), + tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. " + "File contents could not be checked for validity.")); + } +} + +void InstallKeys() +{ + const QString key_source_location + = QtCommon::Frontend::GetOpenFileName(tr("Select Dumped Keys Location"), + {}, + QStringLiteral("Decryption Keys (*.keys)"), + {}, + QtCommon::Frontend::Option::ReadOnly); + + if (key_source_location.isEmpty()) { + return; + } + + FirmwareManager::KeyInstallResult result = FirmwareManager::InstallKeys(key_source_location + .toStdString(), + "keys"); + + system->GetFileSystemController().CreateFactories(*QtCommon::vfs); + + switch (result) { + case FirmwareManager::KeyInstallResult::Success: + QtCommon::Frontend::Information(tr("Decryption Keys install succeeded"), + tr("Decryption Keys were successfully installed")); + break; + default: + QtCommon::Frontend::Critical(tr("Decryption Keys install failed"), + tr(FirmwareManager::GetKeyInstallResultString(result))); + break; + } +} + +void VerifyInstalledContents() { + // Initialize a progress dialog. + QtCommon::Frontend::QtProgressDialog progress(tr("Verifying integrity..."), tr("Cancel"), 0, 100, QtCommon::rootObject); + progress.setWindowModality(Qt::WindowModal); + progress.setMinimumDuration(100); + progress.setAutoClose(false); + progress.setAutoReset(false); + + // Declare progress callback. + auto QtProgressCallback = [&](size_t total_size, size_t processed_size) { + progress.setValue(static_cast((processed_size * 100) / total_size)); + return progress.wasCanceled(); + }; + + const std::vector result = + ContentManager::VerifyInstalledContents(*QtCommon::system, *QtCommon::provider, QtProgressCallback); + progress.close(); + + if (result.empty()) { + QtCommon::Frontend::Information(tr("Integrity verification succeeded!"), + tr("The operation completed successfully.")); + } else { + const auto failed_names = + QString::fromStdString(fmt::format("{}", fmt::join(result, "\n"))); + QtCommon::Frontend::Critical( + tr("Integrity verification failed!"), + tr("Verification failed for the following files:\n\n%1").arg(failed_names)); + } +} + +} // namespace QtCommon::Content diff --git a/src/qt_common/qt_content_util.h b/src/qt_common/qt_content_util.h new file mode 100644 index 0000000000..b572c1c4a3 --- /dev/null +++ b/src/qt_common/qt_content_util.h @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef QT_CONTENT_UTIL_H +#define QT_CONTENT_UTIL_H + +#include +#include "common/common_types.h" + +namespace QtCommon::Content { + +// +bool CheckGameFirmware(u64 program_id, QObject *parent); + +static constexpr std::array FIRMWARE_RESULTS + = {"Successfully installed firmware version %1", + "", + "Unable to locate potential firmware NCA files", + "Failed to delete one or more firmware files.", + "One or more firmware files failed to copy into NAND.", + "Firmware installation cancelled, firmware may be in a bad state or corrupted." + "Restart Eden or re-install firmware."}; + +enum class FirmwareInstallResult { + Success, + NoOp, + NoNCAs, + FailedDelete, + FailedCopy, + FailedCorrupted, +}; + +inline constexpr const char *GetFirmwareInstallResultString(FirmwareInstallResult result) +{ + return FIRMWARE_RESULTS.at(static_cast(result)); +} + +void InstallFirmware(const QString &location, bool recursive); + +QString UnzipFirmwareToTmp(const QString &location); + +// Keys // +void InstallKeys(); + +// Content // +void VerifyGameContents(const std::string &game_path); +void VerifyInstalledContents(); +} +#endif // QT_CONTENT_UTIL_H diff --git a/src/qt_common/qt_frontend_util.cpp b/src/qt_common/qt_frontend_util.cpp new file mode 100644 index 0000000000..d519669ad5 --- /dev/null +++ b/src/qt_common/qt_frontend_util.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_frontend_util.h" +#include "qt_common/qt_common.h" + +#ifdef YUZU_QT_WIDGETS +#include +#endif + +namespace QtCommon::Frontend { + +StandardButton ShowMessage( + Icon icon, const QString &title, const QString &text, StandardButtons buttons, QObject *parent) +{ +#ifdef YUZU_QT_WIDGETS + QMessageBox *box = new QMessageBox(icon, title, text, buttons, (QWidget *) parent); + return static_cast(box->exec()); +#endif + // TODO(crueter): If Qt Widgets is disabled... + // need a way to reference icon/buttons too +} + +const QString GetOpenFileName(const QString &title, + const QString &dir, + const QString &filter, + QString *selectedFilter, + Options options) +{ +#ifdef YUZU_QT_WIDGETS + return QFileDialog::getOpenFileName((QWidget *) rootObject, title, dir, filter, selectedFilter, options); +#endif +} + +} // namespace QtCommon::Frontend diff --git a/src/qt_common/qt_frontend_util.h b/src/qt_common/qt_frontend_util.h new file mode 100644 index 0000000000..f86b9e1357 --- /dev/null +++ b/src/qt_common/qt_frontend_util.h @@ -0,0 +1,148 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef QT_FRONTEND_UTIL_H +#define QT_FRONTEND_UTIL_H + +#include +#include "qt_common/qt_common.h" + +#ifdef YUZU_QT_WIDGETS +#include +#include +#include +#endif + +/** + * manages common functionality e.g. message boxes and such for Qt/QML + */ +namespace QtCommon::Frontend { + +Q_NAMESPACE + +#ifdef YUZU_QT_WIDGETS +using Options = QFileDialog::Options; +using Option = QFileDialog::Option; + +using StandardButton = QMessageBox::StandardButton; +using StandardButtons = QMessageBox::StandardButtons; + +using Icon = QMessageBox::Icon; +#else +enum Option { + ShowDirsOnly = 0x00000001, + DontResolveSymlinks = 0x00000002, + DontConfirmOverwrite = 0x00000004, + DontUseNativeDialog = 0x00000008, + ReadOnly = 0x00000010, + HideNameFilterDetails = 0x00000020, + DontUseCustomDirectoryIcons = 0x00000040 +}; +Q_ENUM_NS(Option) +Q_DECLARE_FLAGS(Options, Option) +Q_FLAG_NS(Options) + +enum StandardButton { + // keep this in sync with QDialogButtonBox::StandardButton and QPlatformDialogHelper::StandardButton + NoButton = 0x00000000, + Ok = 0x00000400, + Save = 0x00000800, + SaveAll = 0x00001000, + Open = 0x00002000, + Yes = 0x00004000, + YesToAll = 0x00008000, + No = 0x00010000, + NoToAll = 0x00020000, + Abort = 0x00040000, + Retry = 0x00080000, + Ignore = 0x00100000, + Close = 0x00200000, + Cancel = 0x00400000, + Discard = 0x00800000, + Help = 0x01000000, + Apply = 0x02000000, + Reset = 0x04000000, + RestoreDefaults = 0x08000000, + + FirstButton = Ok, // internal + LastButton = RestoreDefaults, // internal + + YesAll = YesToAll, // obsolete + NoAll = NoToAll, // obsolete + + Default = 0x00000100, // obsolete + Escape = 0x00000200, // obsolete + FlagMask = 0x00000300, // obsolete + ButtonMask = ~FlagMask // obsolete +}; +Q_ENUM_NS(StandardButton) + +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +typedef StandardButton Button; +#endif +Q_DECLARE_FLAGS(StandardButtons, StandardButton) +Q_FLAG_NS(StandardButtons) + +enum Icon { + // keep this in sync with QMessageDialogOptions::StandardIcon + NoIcon = 0, + Information = 1, + Warning = 2, + Critical = 3, + Question = 4 +}; +Q_ENUM_NS(Icon) + +#endif + +// TODO(crueter) widgets-less impl, choices et al. +StandardButton ShowMessage(Icon icon, + const QString &title, + const QString &text, + StandardButtons buttons = StandardButton::NoButton, + QObject *parent = nullptr); + +#define UTIL_OVERRIDES(level) \ + inline StandardButton level(QObject *parent, \ + const QString &title, \ + const QString &text, \ + StandardButtons buttons = StandardButton::Ok) \ + { \ + return ShowMessage(Icon::level, title, text, buttons, parent); \ + } \ + inline StandardButton level(QObject *parent, \ + const char *title, \ + const char *text, \ + StandardButtons buttons \ + = StandardButton::Ok) \ + { \ + return ShowMessage(Icon::level, tr(title), tr(text), buttons, parent); \ + } \ + inline StandardButton level(const char *title, \ + const char *text, \ + StandardButtons buttons \ + = StandardButton::Ok) \ + { \ + return ShowMessage(Icon::level, tr(title), tr(text), buttons, rootObject); \ + } \ + inline StandardButton level(const QString title, \ + const QString &text, \ + StandardButtons buttons \ + = StandardButton::Ok) \ + { \ + return ShowMessage(Icon::level, title, text, buttons, rootObject); \ + } + +UTIL_OVERRIDES(Information) +UTIL_OVERRIDES(Warning) +UTIL_OVERRIDES(Critical) +UTIL_OVERRIDES(Question) + +const QString GetOpenFileName(const QString &title, + const QString &dir, + const QString &filter, + QString *selectedFilter = nullptr, + Options options = Options()); + +} // namespace QtCommon::Frontend +#endif // QT_FRONTEND_UTIL_H diff --git a/src/qt_common/qt_game_util.cpp b/src/qt_common/qt_game_util.cpp new file mode 100644 index 0000000000..5d0b4d8ae7 --- /dev/null +++ b/src/qt_common/qt_game_util.cpp @@ -0,0 +1,577 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_game_util.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" +#include "core/file_sys/savedata_factory.h" +#include "core/hle/service/am/am_types.h" +#include "frontend_common/content_manager.h" +#include "qt_common.h" +#include "qt_common/uisettings.h" +#include "qt_frontend_util.h" +#include "yuzu/util/util.h" + +#include +#include +#include + +#ifdef _WIN32 +#include "common/scope_exit.h" +#include "common/string_util.h" +#include +#include +#else +#include "fmt/ostream.h" +#include +#endif + +namespace QtCommon::Game { + +bool CreateShortcutLink(const std::filesystem::path& shortcut_path, + const std::string& comment, + const std::filesystem::path& icon_path, + const std::filesystem::path& command, + const std::string& arguments, + const std::string& categories, + const std::string& keywords, + const std::string& name) +try { +#ifdef _WIN32 // Windows + HRESULT hr = CoInitialize(nullptr); + if (FAILED(hr)) { + LOG_ERROR(Frontend, "CoInitialize failed"); + return false; + } + SCOPE_EXIT + { + CoUninitialize(); + }; + IShellLinkW* ps1 = nullptr; + IPersistFile* persist_file = nullptr; + SCOPE_EXIT + { + if (persist_file != nullptr) { + persist_file->Release(); + } + if (ps1 != nullptr) { + ps1->Release(); + } + }; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IShellLinkW, + reinterpret_cast(&ps1)); + if (FAILED(hres)) { + LOG_ERROR(Frontend, "Failed to create IShellLinkW instance"); + return false; + } + hres = ps1->SetPath(command.c_str()); + if (FAILED(hres)) { + LOG_ERROR(Frontend, "Failed to set path"); + return false; + } + if (!arguments.empty()) { + hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data()); + if (FAILED(hres)) { + LOG_ERROR(Frontend, "Failed to set arguments"); + return false; + } + } + if (!comment.empty()) { + hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data()); + if (FAILED(hres)) { + LOG_ERROR(Frontend, "Failed to set description"); + return false; + } + } + if (std::filesystem::is_regular_file(icon_path)) { + hres = ps1->SetIconLocation(icon_path.c_str(), 0); + if (FAILED(hres)) { + LOG_ERROR(Frontend, "Failed to set icon location"); + return false; + } + } + hres = ps1->QueryInterface(IID_IPersistFile, reinterpret_cast(&persist_file)); + if (FAILED(hres)) { + LOG_ERROR(Frontend, "Failed to get IPersistFile interface"); + return false; + } + hres = persist_file->Save(std::filesystem::path{shortcut_path / (name + ".lnk")}.c_str(), TRUE); + if (FAILED(hres)) { + LOG_ERROR(Frontend, "Failed to save shortcut"); + return false; + } + return true; +#elif defined(__unix__) && !defined(__APPLE__) && !defined(__ANDROID__) // Any desktop NIX + std::filesystem::path shortcut_path_full = shortcut_path / (name + ".desktop"); + std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc); + if (!shortcut_stream.is_open()) { + LOG_ERROR(Frontend, "Failed to create shortcut"); + return false; + } + // TODO: Migrate fmt::print to std::print in futures STD C++ 23. + fmt::print(shortcut_stream, "[Desktop Entry]\n"); + fmt::print(shortcut_stream, "Type=Application\n"); + fmt::print(shortcut_stream, "Version=1.0\n"); + fmt::print(shortcut_stream, "Name={}\n", name); + if (!comment.empty()) { + fmt::print(shortcut_stream, "Comment={}\n", comment); + } + if (std::filesystem::is_regular_file(icon_path)) { + fmt::print(shortcut_stream, "Icon={}\n", icon_path.string()); + } + fmt::print(shortcut_stream, "TryExec={}\n", command.string()); + fmt::print(shortcut_stream, "Exec={} {}\n", command.string(), arguments); + if (!categories.empty()) { + fmt::print(shortcut_stream, "Categories={}\n", categories); + } + if (!keywords.empty()) { + fmt::print(shortcut_stream, "Keywords={}\n", keywords); + } + return true; +#else // Unsupported platform + return false; +#endif +} catch (const std::exception& e) { + LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what()); + return false; +} + +bool MakeShortcutIcoPath(const u64 program_id, + const std::string_view game_file_name, + std::filesystem::path& out_icon_path) +{ + // Get path to Yuzu icons directory & icon extension + std::string ico_extension = "png"; +#if defined(_WIN32) + out_icon_path = Common::FS::GetEdenPath(Common::FS::EdenPath::IconsDir); + ico_extension = "ico"; +#elif defined(__linux__) || defined(__FreeBSD__) + out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256"; +#endif + // Create icons directory if it doesn't exist + if (!Common::FS::CreateDirs(out_icon_path)) { + out_icon_path.clear(); + return false; + } + + // Create icon file path + out_icon_path /= (program_id == 0 ? fmt::format("eden-{}.{}", game_file_name, ico_extension) + : fmt::format("eden-{:016X}.{}", program_id, ico_extension)); + return true; +} + +void OpenEdenFolder(const Common::FS::EdenPath& path) +{ + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(Common::FS::GetEdenPathString(path)))); +} + +void OpenRootDataFolder() +{ + OpenEdenFolder(Common::FS::EdenPath::EdenDir); +} + +void OpenNANDFolder() +{ + OpenEdenFolder(Common::FS::EdenPath::NANDDir); +} + +void OpenSDMCFolder() +{ + OpenEdenFolder(Common::FS::EdenPath::SDMCDir); +} + +void OpenModFolder() +{ + OpenEdenFolder(Common::FS::EdenPath::LoadDir); +} + +void OpenLogFolder() +{ + OpenEdenFolder(Common::FS::EdenPath::LogDir); +} + +static QString GetGameListErrorRemoving(QtCommon::Game::InstalledEntryType type) +{ + switch (type) { + case QtCommon::Game::InstalledEntryType::Game: + return tr("Error Removing Contents"); + case QtCommon::Game::InstalledEntryType::Update: + return tr("Error Removing Update"); + case QtCommon::Game::InstalledEntryType::AddOnContent: + return tr("Error Removing DLC"); + default: + return QStringLiteral("Error Removing