summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt78
-rw-r--r--externals/CMakeLists.txt49
m---------externals/dynarmic0
-rw-r--r--externals/find-modules/FindDiscordRPC.cmake27
-rw-r--r--externals/find-modules/FindLibUSB.cmake44
-rw-r--r--externals/find-modules/FindOpus.cmake18
-rw-r--r--externals/find-modules/Findenet.cmake18
-rw-r--r--externals/find-modules/Findhttplib.cmake23
-rw-r--r--externals/find-modules/Findinih.cmake18
-rw-r--r--externals/find-modules/Findlibusb.cmake18
-rw-r--r--externals/find-modules/Findlz4.cmake33
-rw-r--r--externals/find-modules/Findzstd.cmake33
-rw-r--r--externals/inih/CMakeLists.txt3
-rw-r--r--externals/libusb/CMakeLists.txt2
-rw-r--r--src/audio_core/CMakeLists.txt10
-rw-r--r--src/common/CMakeLists.txt14
-rw-r--r--src/common/settings.h1
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/arm/arm_interface.cpp8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp21
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp21
-rw-r--r--src/core/frontend/applets/controller.cpp2
-rw-r--r--src/core/frontend/applets/controller.h6
-rw-r--r--src/core/frontend/applets/error.cpp6
-rw-r--r--src/core/frontend/applets/error.h14
-rw-r--r--src/core/frontend/applets/mii_edit.cpp2
-rw-r--r--src/core/frontend/applets/mii_edit.h6
-rw-r--r--src/core/frontend/applets/profile_select.cpp3
-rw-r--r--src/core/frontend/applets/profile_select.h6
-rw-r--r--src/core/frontend/applets/software_keyboard.cpp5
-rw-r--r--src/core/frontend/applets/software_keyboard.h32
-rw-r--r--src/core/frontend/applets/web_browser.cpp11
-rw-r--r--src/core/frontend/applets/web_browser.h24
-rw-r--r--src/core/hid/emulated_console.cpp10
-rw-r--r--src/core/hid/emulated_controller.cpp15
-rw-r--r--src/core/hid/emulated_controller.h2
-rw-r--r--src/core/hle/kernel/k_memory_block.h33
-rw-r--r--src/core/hle/kernel/k_memory_block_manager.h9
-rw-r--r--src/core/hle/kernel/k_shared_memory.h2
-rw-r--r--src/core/hle/kernel/k_thread.h4
-rw-r--r--src/core/hle/kernel/kernel.cpp2
-rw-r--r--src/core/hle/kernel/physical_core.h2
-rw-r--r--src/core/hle/service/nfc/mifare_user.cpp400
-rw-r--r--src/core/hle/service/nfc/mifare_user.h52
-rw-r--r--src/core/hle/service/nfc/nfc.cpp27
-rw-r--r--src/core/hle/service/nfc/nfc_device.cpp84
-rw-r--r--src/core/hle/service/nfc/nfc_device.h13
-rw-r--r--src/core/hle/service/nfc/nfc_result.h8
-rw-r--r--src/core/hle/service/nfc/nfc_user.cpp4
-rw-r--r--src/core/hle/service/nfp/nfp_types.h46
-rw-r--r--src/core/reporter.cpp35
-rw-r--r--src/core/reporter.h16
-rw-r--r--src/input_common/CMakeLists.txt10
-rw-r--r--src/input_common/drivers/virtual_amiibo.cpp38
-rw-r--r--src/input_common/drivers/virtual_amiibo.h7
-rw-r--r--src/network/CMakeLists.txt2
-rw-r--r--src/video_core/CMakeLists.txt7
-rw-r--r--src/video_core/engines/maxwell_3d.cpp68
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp2
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_debug_callback.cpp2
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.cpp8
-rw-r--r--src/web_service/CMakeLists.txt2
-rw-r--r--src/yuzu/CMakeLists.txt12
-rw-r--r--src/yuzu/applets/qt_controller.cpp2
-rw-r--r--src/yuzu/applets/qt_controller.h4
-rw-r--r--src/yuzu/applets/qt_error.cpp6
-rw-r--r--src/yuzu/applets/qt_error.h8
-rw-r--r--src/yuzu/applets/qt_profile_select.cpp3
-rw-r--r--src/yuzu/applets/qt_profile_select.h4
-rw-r--r--src/yuzu/applets/qt_software_keyboard.cpp5
-rw-r--r--src/yuzu/applets/qt_software_keyboard.h16
-rw-r--r--src/yuzu/applets/qt_web_browser.cpp11
-rw-r--r--src/yuzu/applets/qt_web_browser.h13
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp4
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui13
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp2
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp3
-rw-r--r--src/yuzu_cmd/CMakeLists.txt10
-rw-r--r--src/yuzu_cmd/config.cpp3
-rw-r--r--src/yuzu_cmd/default_ini.h4
84 files changed, 1150 insertions, 455 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index facf4ea5f..cd59e7485 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,8 +31,6 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSV
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
-option(YUZU_USE_BUNDLED_LIBUSB "Compile bundled libusb" OFF)
-
option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}")
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
@@ -43,8 +41,6 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
-option(YUZU_USE_BUNDLED_OPUS "Compile bundled opus" ON)
-
option(YUZU_TESTS "Compile tests" ON)
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
@@ -201,24 +197,40 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# System imported libraries
# =======================================================================
-find_package(fmt 8.0.1 REQUIRED CONFIG)
-find_package(nlohmann_json 3.8 REQUIRED CONFIG)
+find_package(enet 1.3)
+find_package(fmt 9 REQUIRED)
+find_package(inih)
+find_package(libusb 1.0.24)
+find_package(lz4 REQUIRED)
+find_package(nlohmann_json 3.8 REQUIRED)
+find_package(Opus 1.3)
+find_package(Vulkan 1.3.213)
find_package(ZLIB 1.2 REQUIRED)
+find_package(zstd 1.5 REQUIRED)
-# Search for config-only package first (for vcpkg), then try non-config
-find_package(zstd 1.5 CONFIG)
-if (NOT zstd_FOUND)
- find_package(zstd 1.5 REQUIRED)
+if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
+ find_package(xbyak 6)
endif()
-# lz4 1.8 is required, but vcpkg's lz4-config.cmake does not have version info
-find_package(lz4 CONFIG)
-if (NOT lz4_FOUND)
- find_package(lz4 1.8 REQUIRED)
+if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
+ find_package(dynarmic 6.4.0)
+endif()
+
+if (ENABLE_CUBEB)
+ find_package(cubeb)
+endif()
+
+if (USE_DISCORD_PRESENCE)
+ find_package(DiscordRPC)
+endif()
+
+if (ENABLE_WEB_SERVICE)
+ find_package(cpp-jwt 1.4)
+ find_package(httplib 0.11)
endif()
if (YUZU_TESTS)
- find_package(Catch2 2.13.7 REQUIRED CONFIG)
+ find_package(Catch2 2.13.7 REQUIRED)
endif()
find_package(Boost 1.73.0 COMPONENTS context)
@@ -420,23 +432,13 @@ if (ENABLE_SDL2)
set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library")
set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll")
- add_library(SDL2 INTERFACE)
- target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
- target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
+ add_library(SDL2::SDL2 INTERFACE IMPORTED)
+ target_link_libraries(SDL2::SDL2 INTERFACE "${SDL2_LIBRARY}")
+ target_include_directories(SDL2::SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
elseif (YUZU_USE_EXTERNAL_SDL2)
message(STATUS "Using SDL2 from externals.")
else()
find_package(SDL2 2.0.18 REQUIRED)
-
- # Some installations don't set SDL2_LIBRARIES
- if("${SDL2_LIBRARIES}" STREQUAL "")
- message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
- set(SDL2_LIBRARIES "SDL2::SDL2")
- endif()
-
- include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
- add_library(SDL2 INTERFACE)
- target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
endif()
endif()
@@ -448,26 +450,6 @@ if (TARGET Boost::boost)
add_library(boost ALIAS Boost::boost)
endif()
-# Ensure libusb is properly configured (based on dolphin libusb include)
-if(NOT YUZU_USE_BUNDLED_LIBUSB)
- find_package(PkgConfig)
- if (PKG_CONFIG_FOUND AND NOT CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD")
- pkg_check_modules(LIBUSB QUIET libusb-1.0>=1.0.24)
- else()
- find_package(LibUSB)
- endif()
-
- if (LIBUSB_FOUND)
- add_library(usb INTERFACE)
- target_include_directories(usb INTERFACE "${LIBUSB_INCLUDEDIR}" "${LIBUSB_INCLUDE_DIRS}")
- target_link_directories(usb INTERFACE "${LIBUSB_LIBRARY_DIRS}")
- target_link_libraries(usb INTERFACE "${LIBUSB_LIBRARIES}")
- else()
- message(WARNING "libusb not found, falling back to externals")
- set(YUZU_USE_BUNDLED_LIBUSB ON)
- endif()
-endif()
-
# List of all FFmpeg components required
set(FFmpeg_COMPONENTS
avcodec
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index eb6cb706d..4ffafd18c 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -6,15 +6,16 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/externals/find-modules")
include(DownloadExternals)
# xbyak
-if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
+if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
add_subdirectory(xbyak EXCLUDE_FROM_ALL)
endif()
# Dynarmic
-if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
+if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic)
set(DYNARMIC_NO_BUNDLED_FMT ON)
set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE)
- add_subdirectory(dynarmic)
+ add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
+ add_library(dynarmic::dynarmic ALIAS dynarmic)
endif()
# getopt
@@ -26,7 +27,9 @@ endif()
add_subdirectory(glad)
# inih
-add_subdirectory(inih)
+if (NOT TARGET inih::INIReader)
+ add_subdirectory(inih)
+endif()
# mbedtls
add_subdirectory(mbedtls EXCLUDE_FROM_ALL)
@@ -42,8 +45,8 @@ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12" AND CMAKE_CXX_COMPILER
endif()
# libusb
-if (NOT LIBUSB_FOUND OR YUZU_USE_BUNDLED_LIBUSB)
- add_subdirectory(libusb)
+if (NOT TARGET libusb::usb)
+ add_subdirectory(libusb EXCLUDE_FROM_ALL)
endif()
# SDL2
@@ -72,25 +75,30 @@ if (YUZU_USE_EXTERNAL_SDL2)
endif()
# ENet
-add_subdirectory(enet)
-target_include_directories(enet INTERFACE ./enet/include)
+if (NOT TARGET enet::enet)
+ add_subdirectory(enet EXCLUDE_FROM_ALL)
+ target_include_directories(enet INTERFACE ./enet/include)
+ add_library(enet::enet ALIAS enet)
+endif()
# Cubeb
-if(ENABLE_CUBEB)
+if (ENABLE_CUBEB AND NOT TARGET cubeb::cubeb)
set(BUILD_TESTS OFF CACHE BOOL "")
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
+ add_library(cubeb::cubeb ALIAS cubeb)
endif()
# DiscordRPC
-if (USE_DISCORD_PRESENCE)
+if (USE_DISCORD_PRESENCE AND NOT TARGET DiscordRPC::discord-rpc)
add_subdirectory(discord-rpc EXCLUDE_FROM_ALL)
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
+ add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
endif()
# Sirit
-add_subdirectory(sirit)
+add_subdirectory(sirit EXCLUDE_FROM_ALL)
-if (ENABLE_WEB_SERVICE)
+if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (NOT WIN32)
find_package(OpenSSL 1.1)
if (OPENSSL_FOUND)
@@ -118,18 +126,20 @@ if (ENABLE_WEB_SERVICE)
if (WIN32)
target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32)
endif()
-
- # cpp-jwt
+ add_library(httplib::httplib ALIAS httplib)
+endif()
+
+# cpp-jwt
+if (ENABLE_WEB_SERVICE AND NOT TARGET cpp-jwt::cpp-jwt)
add_library(cpp-jwt INTERFACE)
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
+ add_library(cpp-jwt::cpp-jwt ALIAS cpp-jwt)
endif()
# Opus
-if (YUZU_USE_BUNDLED_OPUS)
+if (NOT TARGET Opus::opus)
add_subdirectory(opus EXCLUDE_FROM_ALL)
-else()
- find_package(Opus 1.3 REQUIRED)
endif()
# FFMpeg
@@ -140,3 +150,8 @@ if (YUZU_USE_BUNDLED_FFMPEG)
set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE)
set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
endif()
+
+# Vulkan-Headers
+if (NOT TARGET Vulkan::Headers)
+ add_subdirectory(Vulkan-Headers EXCLUDE_FROM_ALL)
+endif()
diff --git a/externals/dynarmic b/externals/dynarmic
-Subproject a76a2fff534b5584c9921bc5c060e910e95b773
+Subproject bd570e093ca1d1206961296b90df65cda7de8e8
diff --git a/externals/find-modules/FindDiscordRPC.cmake b/externals/find-modules/FindDiscordRPC.cmake
new file mode 100644
index 000000000..44ca9904f
--- /dev/null
+++ b/externals/find-modules/FindDiscordRPC.cmake
@@ -0,0 +1,27 @@
+# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+find_path(DiscordRPC_INCLUDE_DIR discord_rpc.h)
+
+find_library(DiscordRPC_LIBRARY discord-rpc)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(DiscordRPC
+ REQUIRED_VARS
+ DiscordRPC_LIBRARY
+ DiscordRPC_INCLUDE_DIR
+)
+
+if (DiscordRPC_FOUND AND NOT TARGET DiscordRPC::discord-rpc)
+ add_library(DiscordRPC::discord-rpc UNKNOWN IMPORTED)
+ set_target_properties(DiscordRPC::discord-rpc PROPERTIES
+ IMPORTED_LOCATION "${DiscordRPC_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${DiscordRPC_INCLUDE_DIR}"
+ )
+endif()
+
+mark_as_advanced(
+ DiscordRPC_INCLUDE_DIR
+ DiscordRPC_LIBRARY
+)
diff --git a/externals/find-modules/FindLibUSB.cmake b/externals/find-modules/FindLibUSB.cmake
deleted file mode 100644
index 617daf9a5..000000000
--- a/externals/find-modules/FindLibUSB.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# SPDX-FileCopyrightText: 2009 Michal Cihar <michal@cihar.com>
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-# - Find libusb-1.0 library
-# This module defines
-# LIBUSB_INCLUDE_DIR, where to find bluetooth.h
-# LIBUSB_LIBRARIES, the libraries needed to use libusb-1.0.
-# LIBUSB_FOUND, If false, do not try to use libusb-1.0.
-#
-# vim: expandtab sw=4 ts=4 sts=4:
-
-if(ANDROID)
- set(LIBUSB_FOUND FALSE CACHE INTERNAL "libusb-1.0 found")
- message(STATUS "libusb-1.0 not found.")
-elseif (NOT LIBUSB_FOUND)
- pkg_check_modules (LIBUSB_PKG libusb-1.0)
-
- find_path(LIBUSB_INCLUDE_DIR NAMES libusb.h
- PATHS
- ${LIBUSB_PKG_INCLUDE_DIRS}
- /usr/include/libusb-1.0
- /usr/include
- /usr/local/include/libusb-1.0
- /usr/local/include
- )
-
- find_library(LIBUSB_LIBRARIES NAMES usb-1.0 usb
- PATHS
- ${LIBUSB_PKG_LIBRARY_DIRS}
- /usr/lib
- /usr/local/lib
- )
-
- if(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
- set(LIBUSB_FOUND TRUE CACHE INTERNAL "libusb-1.0 found")
- message(STATUS "Found libusb-1.0: ${LIBUSB_INCLUDE_DIR}, ${LIBUSB_LIBRARIES}")
- else(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
- set(LIBUSB_FOUND FALSE CACHE INTERNAL "libusb-1.0 found")
- message(STATUS "libusb-1.0 not found.")
- endif(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
-
- mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
-endif ()
-
diff --git a/externals/find-modules/FindOpus.cmake b/externals/find-modules/FindOpus.cmake
index b68a6046b..2ba515352 100644
--- a/externals/find-modules/FindOpus.cmake
+++ b/externals/find-modules/FindOpus.cmake
@@ -1,19 +1,17 @@
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
-find_package(PkgConfig)
-
+find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
- pkg_search_module(opus IMPORTED_TARGET GLOBAL opus)
- if (opus_FOUND)
- add_library(Opus::opus ALIAS PkgConfig::opus)
- endif()
+ pkg_search_module(OPUS QUIET IMPORTED_TARGET opus)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Opus
- REQUIRED_VARS
- opus_LINK_LIBRARIES
- opus_FOUND
- VERSION_VAR opus_VERSION
+ REQUIRED_VARS OPUS_LINK_LIBRARIES
+ VERSION_VAR OPUS_VERSION
)
+
+if (Opus_FOUND AND NOT TARGET Opus::opus)
+ add_library(Opus::opus ALIAS PkgConfig::OPUS)
+endif()
diff --git a/externals/find-modules/Findenet.cmake b/externals/find-modules/Findenet.cmake
new file mode 100644
index 000000000..6dae76f4c
--- /dev/null
+++ b/externals/find-modules/Findenet.cmake
@@ -0,0 +1,18 @@
+# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+find_package(PkgConfig QUIET)
+if (PKG_CONFIG_FOUND)
+ pkg_search_module(ENET QUIET IMPORTED_TARGET libenet)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(enet
+ REQUIRED_VARS ENET_LINK_LIBRARIES
+ VERSION_VAR ENET_VERSION
+)
+
+if (enet_FOUND AND NOT TARGET enet::enet)
+ add_library(enet::enet ALIAS PkgConfig::ENET)
+endif()
diff --git a/externals/find-modules/Findhttplib.cmake b/externals/find-modules/Findhttplib.cmake
new file mode 100644
index 000000000..b72bad076
--- /dev/null
+++ b/externals/find-modules/Findhttplib.cmake
@@ -0,0 +1,23 @@
+# SPDX-FileCopyrightText: 2022 Andrea Pappacoda <andrea@pappacoda.it>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+include(FindPackageHandleStandardArgs)
+
+find_package(httplib QUIET CONFIG)
+if (httplib_FOUND)
+ find_package_handle_standard_args(httplib CONFIG_MODE)
+else()
+ find_package(PkgConfig QUIET)
+ if (PKG_CONFIG_FOUND)
+ pkg_search_module(HTTPLIB QUIET IMPORTED_TARGET cpp-httplib)
+ endif()
+ find_package_handle_standard_args(httplib
+ REQUIRED_VARS HTTPLIB_INCLUDEDIR
+ VERSION_VAR HTTPLIB_VERSION
+ )
+endif()
+
+if (httplib_FOUND AND NOT TARGET httplib::httplib)
+ add_library(httplib::httplib ALIAS PkgConfig::HTTPLIB)
+endif()
diff --git a/externals/find-modules/Findinih.cmake b/externals/find-modules/Findinih.cmake
new file mode 100644
index 000000000..8d1a07243
--- /dev/null
+++ b/externals/find-modules/Findinih.cmake
@@ -0,0 +1,18 @@
+# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+find_package(PkgConfig QUIET)
+if (PKG_CONFIG_FOUND)
+ pkg_search_module(INIREADER QUIET IMPORTED_TARGET INIReader)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(inih
+ REQUIRED_VARS INIREADER_LINK_LIBRARIES
+ VERSION_VAR INIREADER_VERSION
+)
+
+if (inih_FOUND AND NOT TARGET inih::INIReader)
+ add_library(inih::INIReader ALIAS PkgConfig::INIREADER)
+endif()
diff --git a/externals/find-modules/Findlibusb.cmake b/externals/find-modules/Findlibusb.cmake
new file mode 100644
index 000000000..66f61001c
--- /dev/null
+++ b/externals/find-modules/Findlibusb.cmake
@@ -0,0 +1,18 @@
+# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+find_package(PkgConfig QUIET)
+if (PKG_CONFIG_FOUND)
+ pkg_search_module(LIBUSB QUIET IMPORTED_TARGET libusb-1.0)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(libusb
+ REQUIRED_VARS LIBUSB_LINK_LIBRARIES
+ VERSION_VAR LIBUSB_VERSION
+)
+
+if (libusb_FOUND AND NOT TARGET libusb::usb)
+ add_library(libusb::usb ALIAS PkgConfig::LIBUSB)
+endif()
diff --git a/externals/find-modules/Findlz4.cmake b/externals/find-modules/Findlz4.cmake
index 13ca5de66..f4c7005ba 100644
--- a/externals/find-modules/Findlz4.cmake
+++ b/externals/find-modules/Findlz4.cmake
@@ -1,19 +1,28 @@
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
-find_package(PkgConfig)
+include(FindPackageHandleStandardArgs)
-if (PKG_CONFIG_FOUND)
- pkg_search_module(liblz4 IMPORTED_TARGET GLOBAL liblz4)
- if (liblz4_FOUND)
- add_library(lz4::lz4 ALIAS PkgConfig::liblz4)
+find_package(lz4 QUIET CONFIG)
+if (lz4_FOUND)
+ find_package_handle_standard_args(lz4 CONFIG_MODE)
+else()
+ find_package(PkgConfig QUIET)
+ if (PKG_CONFIG_FOUND)
+ pkg_search_module(LZ4 QUIET IMPORTED_TARGET liblz4)
endif()
+ find_package_handle_standard_args(lz4
+ REQUIRED_VARS LZ4_LINK_LIBRARIES
+ VERSION_VAR LZ4_VERSION
+ )
endif()
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(lz4
- REQUIRED_VARS
- liblz4_LINK_LIBRARIES
- liblz4_FOUND
- VERSION_VAR liblz4_VERSION
-)
+if (lz4_FOUND AND NOT TARGET lz4::lz4)
+ if (TARGET LZ4::lz4_shared)
+ add_library(lz4::lz4 ALIAS LZ4::lz4_shared)
+ elseif (TARGET LZ4::lz4_static)
+ add_library(lz4::lz4 ALIAS LZ4::lz4_static)
+ else()
+ add_library(lz4::lz4 ALIAS PkgConfig::LZ4)
+ endif()
+endif()
diff --git a/externals/find-modules/Findzstd.cmake b/externals/find-modules/Findzstd.cmake
index f4031eb70..1aacc41d0 100644
--- a/externals/find-modules/Findzstd.cmake
+++ b/externals/find-modules/Findzstd.cmake
@@ -1,19 +1,28 @@
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
-find_package(PkgConfig)
+include(FindPackageHandleStandardArgs)
-if (PKG_CONFIG_FOUND)
- pkg_search_module(libzstd IMPORTED_TARGET GLOBAL libzstd)
- if (libzstd_FOUND)
- add_library(zstd::zstd ALIAS PkgConfig::libzstd)
+find_package(zstd QUIET CONFIG)
+if (zstd_FOUND)
+ find_package_handle_standard_args(zstd CONFIG_MODE)
+else()
+ find_package(PkgConfig QUIET)
+ if (PKG_CONFIG_FOUND)
+ pkg_search_module(ZSTD QUIET IMPORTED_TARGET libzstd)
endif()
+ find_package_handle_standard_args(zstd
+ REQUIRED_VARS ZSTD_LINK_LIBRARIES
+ VERSION_VAR ZSTD_VERSION
+ )
endif()
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(zstd
- REQUIRED_VARS
- libzstd_LINK_LIBRARIES
- libzstd_FOUND
- VERSION_VAR libzstd_VERSION
-)
+if (zstd_FOUND AND NOT TARGET zstd::zstd)
+ if (TARGET zstd::libzstd_shared)
+ add_library(zstd::zstd ALIAS zstd::libzstd_shared)
+ elseif (TARGET zstd::libzstd_static)
+ add_library(zstd::zstd ALIAS zstd::libzstd_static)
+ else()
+ add_library(zstd::zstd ALIAS PkgConfig::ZSTD)
+ endif()
+endif()
diff --git a/externals/inih/CMakeLists.txt b/externals/inih/CMakeLists.txt
index b686e3cf5..ebb60a976 100644
--- a/externals/inih/CMakeLists.txt
+++ b/externals/inih/CMakeLists.txt
@@ -9,4 +9,5 @@ add_library(inih
)
create_target_directory_groups(inih)
-target_include_directories(inih INTERFACE .)
+target_include_directories(inih INTERFACE inih/cpp)
+add_library(inih::INIReader ALIAS inih)
diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt
index 3cb1b3687..6317ea807 100644
--- a/externals/libusb/CMakeLists.txt
+++ b/externals/libusb/CMakeLists.txt
@@ -273,3 +273,5 @@ else() # MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
configure_file(config.h.in config.h)
endif() # MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+add_library(libusb::usb ALIAS usb)
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index 0a9d9ec29..420ba62e0 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -219,19 +219,15 @@ endif()
target_link_libraries(audio_core PUBLIC common core)
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
- target_link_libraries(audio_core PRIVATE dynarmic)
+ target_link_libraries(audio_core PRIVATE dynarmic::dynarmic)
endif()
if(ENABLE_CUBEB)
- target_link_libraries(audio_core PRIVATE cubeb)
+ target_link_libraries(audio_core PRIVATE cubeb::cubeb)
target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
endif()
if(ENABLE_SDL2)
- if (YUZU_USE_EXTERNAL_SDL2)
- target_link_libraries(audio_core PRIVATE SDL2-static)
- else()
- target_link_libraries(audio_core PRIVATE SDL2)
- endif()
+ target_link_libraries(audio_core PRIVATE SDL2::SDL2)
target_compile_definitions(audio_core PRIVATE HAVE_SDL2)
endif()
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index a12edc584..6bdffcb7a 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -149,7 +149,7 @@ if(ARCHITECTURE_x86_64)
x64/xbyak_abi.h
x64/xbyak_util.h
)
- target_link_libraries(common PRIVATE xbyak)
+ target_link_libraries(common PRIVATE xbyak::xbyak)
endif()
if (MSVC)
@@ -174,17 +174,7 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
-if (TARGET lz4::lz4)
- target_link_libraries(common PRIVATE lz4::lz4)
-else()
- target_link_libraries(common PRIVATE LZ4::lz4_shared)
-endif()
-if (TARGET zstd::zstd)
- target_link_libraries(common PRIVATE zstd::zstd)
-else()
- target_link_libraries(common PRIVATE
- $<IF:$<TARGET_EXISTS:zstd::libzstd_shared>,zstd::libzstd_shared,zstd::libzstd_static>)
-endif()
+target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd)
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(common PRIVATE precompiled_headers.h)
diff --git a/src/common/settings.h b/src/common/settings.h
index c0620066c..29b730cff 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -400,6 +400,7 @@ struct Values {
Setting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"};
Setting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"};
Setting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"};
+ Setting<bool> cpuopt_ignore_memory_aborts{true, "cpuopt_ignore_memory_aborts"};
SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"};
SwitchableSetting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"};
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 6530d3c60..c6b5ac196 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -528,6 +528,8 @@ add_library(core STATIC
hle/service/mnpp/mnpp_app.h
hle/service/ncm/ncm.cpp
hle/service/ncm/ncm.h
+ hle/service/nfc/mifare_user.cpp
+ hle/service/nfc/mifare_user.h
hle/service/nfc/nfc.cpp
hle/service/nfc/nfc.h
hle/service/nfc/nfc_device.cpp
@@ -824,7 +826,7 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
hle/service/jit/jit.cpp
hle/service/jit/jit.h
)
- target_link_libraries(core PRIVATE dynarmic)
+ target_link_libraries(core PRIVATE dynarmic::dynarmic)
endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 29ba562dc..2df7b0ee8 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -145,11 +145,15 @@ void ARM_Interface::Run() {
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
if (Has(hr, breakpoint) || Has(hr, no_execute)) {
- RewindBreakpointInstruction();
+ if (!Has(hr, no_execute)) {
+ RewindBreakpointInstruction();
+ }
if (system.DebuggerEnabled()) {
system.GetDebugger().NotifyThreadStopped(current_thread);
+ } else {
+ LogBacktrace();
}
- current_thread->RequestSuspend(Kernel::SuspendType::Debug);
+ current_thread->RequestSuspend(SuspendType::Debug);
break;
}
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 227e06ea1..947747d36 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -29,7 +29,9 @@ class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks {
public:
explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_)
: parent{parent_},
- memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {}
+ memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
+ check_memory_access{debugger_enabled ||
+ !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
u8 MemoryRead8(u32 vaddr) override {
CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
@@ -154,6 +156,17 @@ public:
}
bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
+ if (!check_memory_access) {
+ return true;
+ }
+
+ if (!memory.IsValidVirtualAddressRange(addr, size)) {
+ LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}",
+ addr);
+ parent.jit.load()->HaltExecution(ARM_Interface::no_execute);
+ return false;
+ }
+
if (!debugger_enabled) {
return true;
}
@@ -181,7 +194,8 @@ public:
ARM_Dynarmic_32& parent;
Core::Memory::Memory& memory;
std::size_t num_interpreted_instructions{};
- bool debugger_enabled{};
+ const bool debugger_enabled{};
+ const bool check_memory_access{};
static constexpr u64 minimum_run_cycles = 10000U;
};
@@ -264,6 +278,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
if (!Settings::values.cpuopt_recompile_exclusives) {
config.recompile_on_exclusive_fastmem_failure = false;
}
+ if (!Settings::values.cpuopt_ignore_memory_aborts) {
+ config.check_halt_on_memory_access = true;
+ }
} else {
// Unsafe optimizations
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index cb53d64ba..3df943df7 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -29,7 +29,9 @@ class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
public:
explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_)
: parent{parent_},
- memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {}
+ memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()},
+ check_memory_access{debugger_enabled ||
+ !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {}
u8 MemoryRead8(u64 vaddr) override {
CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read);
@@ -198,6 +200,17 @@ public:
}
bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) {
+ if (!check_memory_access) {
+ return true;
+ }
+
+ if (!memory.IsValidVirtualAddressRange(addr, size)) {
+ LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}",
+ addr);
+ parent.jit.load()->HaltExecution(ARM_Interface::no_execute);
+ return false;
+ }
+
if (!debugger_enabled) {
return true;
}
@@ -226,7 +239,8 @@ public:
Core::Memory::Memory& memory;
u64 tpidrro_el0 = 0;
u64 tpidr_el0 = 0;
- bool debugger_enabled{};
+ const bool debugger_enabled{};
+ const bool check_memory_access{};
static constexpr u64 minimum_run_cycles = 10000U;
};
@@ -323,6 +337,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
if (!Settings::values.cpuopt_recompile_exclusives) {
config.recompile_on_exclusive_fastmem_failure = false;
}
+ if (!Settings::values.cpuopt_ignore_memory_aborts) {
+ config.check_halt_on_memory_access = true;
+ }
} else {
// Unsafe optimizations
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 6c230f619..52919484e 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -16,7 +16,7 @@ DefaultControllerApplet::DefaultControllerApplet(HID::HIDCore& hid_core_) : hid_
DefaultControllerApplet::~DefaultControllerApplet() = default;
-void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback,
+void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callback,
const ControllerParameters& parameters) const {
LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!");
diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h
index 71698df74..adb2feefd 100644
--- a/src/core/frontend/applets/controller.h
+++ b/src/core/frontend/applets/controller.h
@@ -36,9 +36,11 @@ struct ControllerParameters {
class ControllerApplet {
public:
+ using ReconfigureCallback = std::function<void()>;
+
virtual ~ControllerApplet();
- virtual void ReconfigureControllers(std::function<void()> callback,
+ virtual void ReconfigureControllers(ReconfigureCallback callback,
const ControllerParameters& parameters) const = 0;
};
@@ -47,7 +49,7 @@ public:
explicit DefaultControllerApplet(HID::HIDCore& hid_core_);
~DefaultControllerApplet() override;
- void ReconfigureControllers(std::function<void()> callback,
+ void ReconfigureControllers(ReconfigureCallback callback,
const ControllerParameters& parameters) const override;
private:
diff --git a/src/core/frontend/applets/error.cpp b/src/core/frontend/applets/error.cpp
index f8b961098..69c2b2b4d 100644
--- a/src/core/frontend/applets/error.cpp
+++ b/src/core/frontend/applets/error.cpp
@@ -8,13 +8,13 @@ namespace Core::Frontend {
ErrorApplet::~ErrorApplet() = default;
-void DefaultErrorApplet::ShowError(Result error, std::function<void()> finished) const {
+void DefaultErrorApplet::ShowError(Result error, FinishedCallback finished) const {
LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})",
error.module.Value(), error.description.Value(), error.raw);
}
void DefaultErrorApplet::ShowErrorWithTimestamp(Result error, std::chrono::seconds time,
- std::function<void()> finished) const {
+ FinishedCallback finished) const {
LOG_CRITICAL(
Service_Fatal,
"Application requested error display: {:04X}-{:04X} (raw={:08X}) with timestamp={:016X}",
@@ -23,7 +23,7 @@ void DefaultErrorApplet::ShowErrorWithTimestamp(Result error, std::chrono::secon
void DefaultErrorApplet::ShowCustomErrorText(Result error, std::string main_text,
std::string detail_text,
- std::function<void()> finished) const {
+ FinishedCallback finished) const {
LOG_CRITICAL(Service_Fatal,
"Application requested custom error with error_code={:04X}-{:04X} (raw={:08X})",
error.module.Value(), error.description.Value(), error.raw);
diff --git a/src/core/frontend/applets/error.h b/src/core/frontend/applets/error.h
index f378f8805..884f2f653 100644
--- a/src/core/frontend/applets/error.h
+++ b/src/core/frontend/applets/error.h
@@ -12,25 +12,27 @@ namespace Core::Frontend {
class ErrorApplet {
public:
+ using FinishedCallback = std::function<void()>;
+
virtual ~ErrorApplet();
- virtual void ShowError(Result error, std::function<void()> finished) const = 0;
+ virtual void ShowError(Result error, FinishedCallback finished) const = 0;
virtual void ShowErrorWithTimestamp(Result error, std::chrono::seconds time,
- std::function<void()> finished) const = 0;
+ FinishedCallback finished) const = 0;
virtual void ShowCustomErrorText(Result error, std::string dialog_text,
std::string fullscreen_text,
- std::function<void()> finished) const = 0;
+ FinishedCallback finished) const = 0;
};
class DefaultErrorApplet final : public ErrorApplet {
public:
- void ShowError(Result error, std::function<void()> finished) const override;
+ void ShowError(Result error, FinishedCallback finished) const override;
void ShowErrorWithTimestamp(Result error, std::chrono::seconds time,
- std::function<void()> finished) const override;
+ FinishedCallback finished) const override;
void ShowCustomErrorText(Result error, std::string main_text, std::string detail_text,
- std::function<void()> finished) const override;
+ FinishedCallback finished) const override;
};
} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/mii_edit.cpp b/src/core/frontend/applets/mii_edit.cpp
index d37b5368a..bc8c57067 100644
--- a/src/core/frontend/applets/mii_edit.cpp
+++ b/src/core/frontend/applets/mii_edit.cpp
@@ -8,7 +8,7 @@ namespace Core::Frontend {
MiiEditApplet::~MiiEditApplet() = default;
-void DefaultMiiEditApplet::ShowMiiEdit(const std::function<void()>& callback) const {
+void DefaultMiiEditApplet::ShowMiiEdit(const MiiEditCallback& callback) const {
LOG_WARNING(Service_AM, "(STUBBED) called");
callback();
diff --git a/src/core/frontend/applets/mii_edit.h b/src/core/frontend/applets/mii_edit.h
index 58fa2039b..d828f06ec 100644
--- a/src/core/frontend/applets/mii_edit.h
+++ b/src/core/frontend/applets/mii_edit.h
@@ -9,14 +9,16 @@ namespace Core::Frontend {
class MiiEditApplet {
public:
+ using MiiEditCallback = std::function<void()>;
+
virtual ~MiiEditApplet();
- virtual void ShowMiiEdit(const std::function<void()>& callback) const = 0;
+ virtual void ShowMiiEdit(const MiiEditCallback& callback) const = 0;
};
class DefaultMiiEditApplet final : public MiiEditApplet {
public:
- void ShowMiiEdit(const std::function<void()>& callback) const override;
+ void ShowMiiEdit(const MiiEditCallback& callback) const override;
};
} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/profile_select.cpp b/src/core/frontend/applets/profile_select.cpp
index d11fbce0a..da4cfbf87 100644
--- a/src/core/frontend/applets/profile_select.cpp
+++ b/src/core/frontend/applets/profile_select.cpp
@@ -9,8 +9,7 @@ namespace Core::Frontend {
ProfileSelectApplet::~ProfileSelectApplet() = default;
-void DefaultProfileSelectApplet::SelectProfile(
- std::function<void(std::optional<Common::UUID>)> callback) const {
+void DefaultProfileSelectApplet::SelectProfile(SelectProfileCallback callback) const {
Service::Account::ProfileManager manager;
callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{}));
LOG_INFO(Service_ACC, "called, selecting current user instead of prompting...");
diff --git a/src/core/frontend/applets/profile_select.h b/src/core/frontend/applets/profile_select.h
index 8d6ee5279..138429533 100644
--- a/src/core/frontend/applets/profile_select.h
+++ b/src/core/frontend/applets/profile_select.h
@@ -11,14 +11,16 @@ namespace Core::Frontend {
class ProfileSelectApplet {
public:
+ using SelectProfileCallback = std::function<void(std::optional<Common::UUID>)>;
+
virtual ~ProfileSelectApplet();
- virtual void SelectProfile(std::function<void(std::optional<Common::UUID>)> callback) const = 0;
+ virtual void SelectProfile(SelectProfileCallback callback) const = 0;
};
class DefaultProfileSelectApplet final : public ProfileSelectApplet {
public:
- void SelectProfile(std::function<void(std::optional<Common::UUID>)> callback) const override;
+ void SelectProfile(SelectProfileCallback callback) const override;
};
} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/software_keyboard.cpp b/src/core/frontend/applets/software_keyboard.cpp
index 020c7fa5e..a3720f4d7 100644
--- a/src/core/frontend/applets/software_keyboard.cpp
+++ b/src/core/frontend/applets/software_keyboard.cpp
@@ -15,10 +15,7 @@ DefaultSoftwareKeyboardApplet::~DefaultSoftwareKeyboardApplet() = default;
void DefaultSoftwareKeyboardApplet::InitializeKeyboard(
bool is_inline, KeyboardInitializeParameters initialize_parameters,
- std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback_,
- std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback_) {
+ SubmitNormalCallback submit_normal_callback_, SubmitInlineCallback submit_inline_callback_) {
if (is_inline) {
LOG_WARNING(
Service_AM,
diff --git a/src/core/frontend/applets/software_keyboard.h b/src/core/frontend/applets/software_keyboard.h
index 094d1e713..8aef103d3 100644
--- a/src/core/frontend/applets/software_keyboard.h
+++ b/src/core/frontend/applets/software_keyboard.h
@@ -54,14 +54,17 @@ struct InlineTextParameters {
class SoftwareKeyboardApplet {
public:
+ using SubmitInlineCallback =
+ std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>;
+ using SubmitNormalCallback =
+ std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>;
+
virtual ~SoftwareKeyboardApplet();
- virtual void InitializeKeyboard(
- bool is_inline, KeyboardInitializeParameters initialize_parameters,
- std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback_,
- std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback_) = 0;
+ virtual void InitializeKeyboard(bool is_inline,
+ KeyboardInitializeParameters initialize_parameters,
+ SubmitNormalCallback submit_normal_callback_,
+ SubmitInlineCallback submit_inline_callback_) = 0;
virtual void ShowNormalKeyboard() const = 0;
@@ -81,12 +84,9 @@ class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
public:
~DefaultSoftwareKeyboardApplet() override;
- void InitializeKeyboard(
- bool is_inline, KeyboardInitializeParameters initialize_parameters,
- std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback_,
- std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback_) override;
+ void InitializeKeyboard(bool is_inline, KeyboardInitializeParameters initialize_parameters,
+ SubmitNormalCallback submit_normal_callback_,
+ SubmitInlineCallback submit_inline_callback_) override;
void ShowNormalKeyboard() const override;
@@ -105,12 +105,10 @@ private:
void SubmitNormalText(std::u16string text) const;
void SubmitInlineText(std::u16string_view text) const;
- KeyboardInitializeParameters parameters;
+ KeyboardInitializeParameters parameters{};
- mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback;
- mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback;
+ mutable SubmitNormalCallback submit_normal_callback;
+ mutable SubmitInlineCallback submit_inline_callback;
};
} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/web_browser.cpp b/src/core/frontend/applets/web_browser.cpp
index 27c7086be..b09cb7102 100644
--- a/src/core/frontend/applets/web_browser.cpp
+++ b/src/core/frontend/applets/web_browser.cpp
@@ -10,18 +10,17 @@ WebBrowserApplet::~WebBrowserApplet() = default;
DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default;
-void DefaultWebBrowserApplet::OpenLocalWebPage(
- const std::string& local_url, std::function<void()> extract_romfs_callback,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
+void DefaultWebBrowserApplet::OpenLocalWebPage(const std::string& local_url,
+ ExtractROMFSCallback extract_romfs_callback,
+ OpenWebPageCallback callback) const {
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open local web page at {}",
local_url);
callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/");
}
-void DefaultWebBrowserApplet::OpenExternalWebPage(
- const std::string& external_url,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
+void DefaultWebBrowserApplet::OpenExternalWebPage(const std::string& external_url,
+ OpenWebPageCallback callback) const {
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open external web page at {}",
external_url);
diff --git a/src/core/frontend/applets/web_browser.h b/src/core/frontend/applets/web_browser.h
index 1411274f8..4f72284ad 100644
--- a/src/core/frontend/applets/web_browser.h
+++ b/src/core/frontend/applets/web_browser.h
@@ -11,29 +11,29 @@ namespace Core::Frontend {
class WebBrowserApplet {
public:
+ using ExtractROMFSCallback = std::function<void()>;
+ using OpenWebPageCallback =
+ std::function<void(Service::AM::Applets::WebExitReason, std::string)>;
+
virtual ~WebBrowserApplet();
- virtual void OpenLocalWebPage(
- const std::string& local_url, std::function<void()> extract_romfs_callback,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;
+ virtual void OpenLocalWebPage(const std::string& local_url,
+ ExtractROMFSCallback extract_romfs_callback,
+ OpenWebPageCallback callback) const = 0;
- virtual void OpenExternalWebPage(
- const std::string& external_url,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;
+ virtual void OpenExternalWebPage(const std::string& external_url,
+ OpenWebPageCallback callback) const = 0;
};
class DefaultWebBrowserApplet final : public WebBrowserApplet {
public:
~DefaultWebBrowserApplet() override;
- void OpenLocalWebPage(const std::string& local_url,
- std::function<void()> extract_romfs_callback,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)>
- callback) const override;
+ void OpenLocalWebPage(const std::string& local_url, ExtractROMFSCallback extract_romfs_callback,
+ OpenWebPageCallback callback) const override;
void OpenExternalWebPage(const std::string& external_url,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)>
- callback) const override;
+ OpenWebPageCallback callback) const override;
};
} // namespace Core::Frontend
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index b6c8cc58d..30c2e9d17 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -37,7 +37,7 @@ void EmulatedConsole::SetTouchParams() {
touchscreen_param.Set("axis_x", i * 2);
touchscreen_param.Set("axis_y", (i * 2) + 1);
touchscreen_param.Set("button", i);
- touch_params[index++] = touchscreen_param;
+ touch_params[index++] = std::move(touchscreen_param);
}
const auto button_index =
@@ -59,7 +59,7 @@ void EmulatedConsole::SetTouchParams() {
touch_button_params.Set("button", params.Serialize());
touch_button_params.Set("x", x);
touch_button_params.Set("y", y);
- touch_params[index] = touch_button_params;
+ touch_params[index] = std::move(touch_button_params);
index++;
}
}
@@ -131,7 +131,7 @@ Common::ParamPackage EmulatedConsole::GetMotionParam() const {
}
void EmulatedConsole::SetMotionParam(Common::ParamPackage param) {
- motion_params = param;
+ motion_params = std::move(param);
ReloadInput();
}
@@ -199,7 +199,7 @@ void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, st
if (is_new_input) {
touch_value.pressed.value = true;
- touch_value.id = static_cast<u32>(index);
+ touch_value.id = static_cast<int>(index);
}
touch_value.x = touch_input.x;
@@ -284,7 +284,7 @@ void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) {
std::scoped_lock lock{callback_mutex};
- callback_list.insert_or_assign(last_callback_key, update_callback);
+ callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
return last_callback_key++;
}
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 74c877728..67969e938 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -424,15 +424,14 @@ void EmulatedController::RestoreConfig() {
ReloadFromSettings();
}
-std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices(
- EmulatedDeviceIndex device_index) const {
+std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices() const {
std::vector<Common::ParamPackage> devices;
for (const auto& param : button_params) {
if (!param.Has("engine")) {
continue;
}
const auto devices_it = std::find_if(
- devices.begin(), devices.end(), [param](const Common::ParamPackage param_) {
+ devices.begin(), devices.end(), [&param](const Common::ParamPackage& param_) {
return param.Get("engine", "") == param_.Get("engine", "") &&
param.Get("guid", "") == param_.Get("guid", "") &&
param.Get("port", 0) == param_.Get("port", 0) &&
@@ -441,12 +440,12 @@ std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices(
if (devices_it != devices.end()) {
continue;
}
- Common::ParamPackage device{};
+
+ auto& device = devices.emplace_back();
device.Set("engine", param.Get("engine", ""));
device.Set("guid", param.Get("guid", ""));
device.Set("port", param.Get("port", 0));
device.Set("pad", param.Get("pad", 0));
- devices.push_back(device);
}
for (const auto& param : stick_params) {
@@ -457,7 +456,7 @@ std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices(
continue;
}
const auto devices_it = std::find_if(
- devices.begin(), devices.end(), [param](const Common::ParamPackage param_) {
+ devices.begin(), devices.end(), [&param](const Common::ParamPackage& param_) {
return param.Get("engine", "") == param_.Get("engine", "") &&
param.Get("guid", "") == param_.Get("guid", "") &&
param.Get("port", 0) == param_.Get("port", 0) &&
@@ -466,12 +465,12 @@ std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices(
if (devices_it != devices.end()) {
continue;
}
- Common::ParamPackage device{};
+
+ auto& device = devices.emplace_back();
device.Set("engine", param.Get("engine", ""));
device.Set("guid", param.Get("guid", ""));
device.Set("port", param.Get("port", 0));
device.Set("pad", param.Get("pad", 0));
- devices.push_back(device);
}
return devices;
}
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index 3f83108d3..fa7a34278 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -244,7 +244,7 @@ public:
void RestoreConfig();
/// Returns a vector of mapped devices from the mapped button and stick parameters
- std::vector<Common::ParamPackage> GetMappedDevices(EmulatedDeviceIndex device_index) const;
+ std::vector<Common::ParamPackage> GetMappedDevices() const;
// Returns the current mapped button device
Common::ParamPackage GetButtonParam(std::size_t index) const;
diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h
index 3b6e7baff..87ca65592 100644
--- a/src/core/hle/kernel/k_memory_block.h
+++ b/src/core/hle/kernel/k_memory_block.h
@@ -280,18 +280,19 @@ struct KMemoryInfo {
class KMemoryBlock : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock> {
private:
- u16 m_device_disable_merge_left_count;
- u16 m_device_disable_merge_right_count;
- VAddr m_address;
- size_t m_num_pages;
- KMemoryState m_memory_state;
- u16 m_ipc_lock_count;
- u16 m_device_use_count;
- u16 m_ipc_disable_merge_count;
- KMemoryPermission m_permission;
- KMemoryPermission m_original_permission;
- KMemoryAttribute m_attribute;
- KMemoryBlockDisableMergeAttribute m_disable_merge_attribute;
+ u16 m_device_disable_merge_left_count{};
+ u16 m_device_disable_merge_right_count{};
+ VAddr m_address{};
+ size_t m_num_pages{};
+ KMemoryState m_memory_state{KMemoryState::None};
+ u16 m_ipc_lock_count{};
+ u16 m_device_use_count{};
+ u16 m_ipc_disable_merge_count{};
+ KMemoryPermission m_permission{KMemoryPermission::None};
+ KMemoryPermission m_original_permission{KMemoryPermission::None};
+ KMemoryAttribute m_attribute{KMemoryAttribute::None};
+ KMemoryBlockDisableMergeAttribute m_disable_merge_attribute{
+ KMemoryBlockDisableMergeAttribute::None};
public:
static constexpr int Compare(const KMemoryBlock& lhs, const KMemoryBlock& rhs) {
@@ -367,12 +368,8 @@ public:
constexpr KMemoryBlock(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
KMemoryAttribute attr)
- : Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(),
- m_device_disable_merge_left_count(), m_device_disable_merge_right_count(),
- m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0),
- m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p),
- m_original_permission(KMemoryPermission::None), m_attribute(attr),
- m_disable_merge_attribute() {}
+ : Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(), m_address(addr), m_num_pages(np),
+ m_memory_state(ms), m_permission(p), m_attribute(attr) {}
constexpr void Initialize(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
KMemoryAttribute attr) {
diff --git a/src/core/hle/kernel/k_memory_block_manager.h b/src/core/hle/kernel/k_memory_block_manager.h
index 9b5873883..d382722a6 100644
--- a/src/core/hle/kernel/k_memory_block_manager.h
+++ b/src/core/hle/kernel/k_memory_block_manager.h
@@ -3,6 +3,7 @@
#pragma once
+#include <array>
#include <functional>
#include "common/common_funcs.h"
@@ -17,9 +18,9 @@ public:
static constexpr size_t MaxBlocks = 2;
private:
- KMemoryBlock* m_blocks[MaxBlocks];
- size_t m_index;
- KMemoryBlockSlabManager* m_slab_manager;
+ std::array<KMemoryBlock*, MaxBlocks> m_blocks{};
+ size_t m_index{MaxBlocks};
+ KMemoryBlockSlabManager* m_slab_manager{};
private:
Result Initialize(size_t num_blocks) {
@@ -41,7 +42,7 @@ private:
public:
KMemoryBlockManagerUpdateAllocator(Result* out_result, KMemoryBlockSlabManager* sm,
size_t num_blocks = MaxBlocks)
- : m_blocks(), m_index(MaxBlocks), m_slab_manager(sm) {
+ : m_slab_manager(sm) {
*out_result = this->Initialize(num_blocks);
}
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h
index 5620c3660..a96c55a3e 100644
--- a/src/core/hle/kernel/k_shared_memory.h
+++ b/src/core/hle/kernel/k_shared_memory.h
@@ -74,7 +74,7 @@ public:
static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
private:
- Core::DeviceMemory* device_memory;
+ Core::DeviceMemory* device_memory{};
KProcess* owner_process{};
KPageGroup page_list;
Svc::MemoryPermission owner_permission{};
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index f38c92bff..dc52b4ed3 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -784,8 +784,8 @@ private:
std::vector<KSynchronizationObject*> wait_objects_for_debugging;
VAddr mutex_wait_address_for_debugging{};
ThreadWaitReasonForDebugging wait_reason_for_debugging{};
- uintptr_t argument;
- VAddr stack_top;
+ uintptr_t argument{};
+ VAddr stack_top{};
public:
using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b77723503..288f97df5 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -891,7 +891,7 @@ struct KernelCore::Impl {
Common::ThreadWorker service_threads_manager;
Common::Barrier service_thread_barrier;
- std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads;
+ std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads{};
std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
bool is_multicore{};
diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h
index 2fc8d4be2..fb2ba4c6b 100644
--- a/src/core/hle/kernel/physical_core.h
+++ b/src/core/hle/kernel/physical_core.h
@@ -85,7 +85,7 @@ private:
std::mutex guard;
std::condition_variable on_interrupt;
std::unique_ptr<Core::ARM_Interface> arm_interface;
- bool is_interrupted;
+ bool is_interrupted{};
};
} // namespace Kernel
diff --git a/src/core/hle/service/nfc/mifare_user.cpp b/src/core/hle/service/nfc/mifare_user.cpp
new file mode 100644
index 000000000..51523a3ae
--- /dev/null
+++ b/src/core/hle/service/nfc/mifare_user.cpp
@@ -0,0 +1,400 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/hid/hid_types.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/k_event.h"
+#include "core/hle/service/nfc/mifare_user.h"
+#include "core/hle/service/nfc/nfc_device.h"
+#include "core/hle/service/nfc/nfc_result.h"
+
+namespace Service::NFC {
+
+MFIUser::MFIUser(Core::System& system_)
+ : ServiceFramework{system_, "NFC::MFIUser"}, service_context{system_, service_name} {
+ static const FunctionInfo functions[] = {
+ {0, &MFIUser::Initialize, "Initialize"},
+ {1, &MFIUser::Finalize, "Finalize"},
+ {2, &MFIUser::ListDevices, "ListDevices"},
+ {3, &MFIUser::StartDetection, "StartDetection"},
+ {4, &MFIUser::StopDetection, "StopDetection"},
+ {5, &MFIUser::Read, "Read"},
+ {6, &MFIUser::Write, "Write"},
+ {7, &MFIUser::GetTagInfo, "GetTagInfo"},
+ {8, &MFIUser::GetActivateEventHandle, "GetActivateEventHandle"},
+ {9, &MFIUser::GetDeactivateEventHandle, "GetDeactivateEventHandle"},
+ {10, &MFIUser::GetState, "GetState"},
+ {11, &MFIUser::GetDeviceState, "GetDeviceState"},
+ {12, &MFIUser::GetNpadId, "GetNpadId"},
+ {13, &MFIUser::GetAvailabilityChangeEventHandle, "GetAvailabilityChangeEventHandle"},
+ };
+ RegisterHandlers(functions);
+
+ availability_change_event = service_context.CreateEvent("MFIUser:AvailabilityChangeEvent");
+
+ for (u32 device_index = 0; device_index < 10; device_index++) {
+ devices[device_index] =
+ std::make_shared<NfcDevice>(Core::HID::IndexToNpadIdType(device_index), system,
+ service_context, availability_change_event);
+ }
+}
+
+MFIUser ::~MFIUser() {
+ availability_change_event->Close();
+}
+
+void MFIUser::Initialize(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_NFC, "called");
+
+ state = State::Initialized;
+
+ for (auto& device : devices) {
+ device->Initialize();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 0};
+ rb.Push(ResultSuccess);
+}
+
+void MFIUser::Finalize(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_NFC, "called");
+
+ state = State::NonInitialized;
+
+ for (auto& device : devices) {
+ device->Finalize();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void MFIUser::ListDevices(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_NFC, "called");
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ if (!ctx.CanWriteBuffer()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareInvalidArgument);
+ return;
+ }
+
+ if (ctx.GetWriteBufferSize() == 0) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareInvalidArgument);
+ return;
+ }
+
+ std::vector<u64> nfp_devices;
+ const std::size_t max_allowed_devices = ctx.GetWriteBufferNumElements<u64>();
+
+ for (const auto& device : devices) {
+ if (nfp_devices.size() >= max_allowed_devices) {
+ continue;
+ }
+ if (device->GetCurrentState() != NFP::DeviceState::Unavailable) {
+ nfp_devices.push_back(device->GetHandle());
+ }
+ }
+
+ if (nfp_devices.empty()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ ctx.WriteBuffer(nfp_devices);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(static_cast<s32>(nfp_devices.size()));
+}
+
+void MFIUser::StartDetection(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->StartDetection(NFP::TagProtocol::All);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void MFIUser::StopDetection(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->StopDetection();
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void MFIUser::Read(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto buffer{ctx.ReadBuffer()};
+ const auto number_of_commands{ctx.GetReadBufferNumElements<NFP::MifareReadBlockParameter>()};
+ std::vector<NFP::MifareReadBlockParameter> read_commands(number_of_commands);
+
+ memcpy(read_commands.data(), buffer.data(),
+ number_of_commands * sizeof(NFP::MifareReadBlockParameter));
+
+ LOG_INFO(Service_NFC, "(STUBBED) called, device_handle={}, read_commands_size={}",
+ device_handle, number_of_commands);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ Result result = ResultSuccess;
+ std::vector<NFP::MifareReadBlockData> out_data(number_of_commands);
+ for (std::size_t i = 0; i < number_of_commands; i++) {
+ result = device.value()->MifareRead(read_commands[i], out_data[i]);
+ if (result.IsError()) {
+ break;
+ }
+ }
+
+ ctx.WriteBuffer(out_data);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void MFIUser::Write(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto buffer{ctx.ReadBuffer()};
+ const auto number_of_commands{ctx.GetReadBufferNumElements<NFP::MifareWriteBlockParameter>()};
+ std::vector<NFP::MifareWriteBlockParameter> write_commands(number_of_commands);
+
+ memcpy(write_commands.data(), buffer.data(),
+ number_of_commands * sizeof(NFP::MifareWriteBlockParameter));
+
+ LOG_INFO(Service_NFC, "(STUBBED) called, device_handle={}, write_commands_size={}",
+ device_handle, number_of_commands);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ Result result = ResultSuccess;
+ std::vector<NFP::MifareReadBlockData> out_data(number_of_commands);
+ for (std::size_t i = 0; i < number_of_commands; i++) {
+ result = device.value()->MifareWrite(write_commands[i]);
+ if (result.IsError()) {
+ break;
+ }
+ }
+
+ if (result.IsSuccess()) {
+ result = device.value()->Flush();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void MFIUser::GetTagInfo(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ NFP::TagInfo tag_info{};
+ const auto result = device.value()->GetTagInfo(tag_info, true);
+ ctx.WriteBuffer(tag_info);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void MFIUser::GetActivateEventHandle(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(device.value()->GetActivateEvent());
+}
+
+void MFIUser::GetDeactivateEventHandle(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(device.value()->GetDeactivateEvent());
+}
+
+void MFIUser::GetState(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_NFC, "called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(state);
+}
+
+void MFIUser::GetDeviceState(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(device.value()->GetCurrentState());
+}
+
+void MFIUser::GetNpadId(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ auto device = GetNfcDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareDeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(device.value()->GetNpadId());
+}
+
+void MFIUser::GetAvailabilityChangeEventHandle(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_NFC, "called");
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(MifareNfcDisabled);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(availability_change_event->GetReadableEvent());
+}
+
+std::optional<std::shared_ptr<NfcDevice>> MFIUser::GetNfcDevice(u64 handle) {
+ for (auto& device : devices) {
+ if (device->GetHandle() == handle) {
+ return device;
+ }
+ }
+ return std::nullopt;
+}
+
+} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/mifare_user.h b/src/core/hle/service/nfc/mifare_user.h
new file mode 100644
index 000000000..0e0638cb6
--- /dev/null
+++ b/src/core/hle/service/nfc/mifare_user.h
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <memory>
+#include <optional>
+
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/service.h"
+
+namespace Service::NFC {
+class NfcDevice;
+
+class MFIUser final : public ServiceFramework<MFIUser> {
+public:
+ explicit MFIUser(Core::System& system_);
+ ~MFIUser();
+
+private:
+ enum class State : u32 {
+ NonInitialized,
+ Initialized,
+ };
+
+ void Initialize(Kernel::HLERequestContext& ctx);
+ void Finalize(Kernel::HLERequestContext& ctx);
+ void ListDevices(Kernel::HLERequestContext& ctx);
+ void StartDetection(Kernel::HLERequestContext& ctx);
+ void StopDetection(Kernel::HLERequestContext& ctx);
+ void Read(Kernel::HLERequestContext& ctx);
+ void Write(Kernel::HLERequestContext& ctx);
+ void GetTagInfo(Kernel::HLERequestContext& ctx);
+ void GetActivateEventHandle(Kernel::HLERequestContext& ctx);
+ void GetDeactivateEventHandle(Kernel::HLERequestContext& ctx);
+ void GetState(Kernel::HLERequestContext& ctx);
+ void GetDeviceState(Kernel::HLERequestContext& ctx);
+ void GetNpadId(Kernel::HLERequestContext& ctx);
+ void GetAvailabilityChangeEventHandle(Kernel::HLERequestContext& ctx);
+
+ std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
+
+ KernelHelpers::ServiceContext service_context;
+
+ std::array<std::shared_ptr<NfcDevice>, 10> devices{};
+
+ State state{State::NonInitialized};
+ Kernel::KEvent* availability_change_event;
+};
+
+} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index 2f4bacb3b..b17b18ab9 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -6,6 +6,7 @@
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/service/nfc/mifare_user.h"
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/nfc/nfc_user.h"
#include "core/hle/service/service.h"
@@ -50,32 +51,6 @@ private:
}
};
-class MFIUser final : public ServiceFramework<MFIUser> {
-public:
- explicit MFIUser(Core::System& system_) : ServiceFramework{system_, "NFC::MFIUser"} {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, nullptr, "Initialize"},
- {1, nullptr, "Finalize"},
- {2, nullptr, "ListDevices"},
- {3, nullptr, "StartDetection"},
- {4, nullptr, "StopDetection"},
- {5, nullptr, "Read"},
- {6, nullptr, "Write"},
- {7, nullptr, "GetTagInfo"},
- {8, nullptr, "GetActivateEventHandle"},
- {9, nullptr, "GetDeactivateEventHandle"},
- {10, nullptr, "GetState"},
- {11, nullptr, "GetDeviceState"},
- {12, nullptr, "GetNpadId"},
- {13, nullptr, "GetAvailabilityChangeEventHandle"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
- }
-};
-
class NFC_MF_U final : public ServiceFramework<NFC_MF_U> {
public:
explicit NFC_MF_U(Core::System& system_) : ServiceFramework{system_, "nfc:mf:u"} {
diff --git a/src/core/hle/service/nfc/nfc_device.cpp b/src/core/hle/service/nfc/nfc_device.cpp
index 4d514cf5f..78578f723 100644
--- a/src/core/hle/service/nfc/nfc_device.cpp
+++ b/src/core/hle/service/nfc/nfc_device.cpp
@@ -77,11 +77,13 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) {
return false;
}
- if (data.size() != sizeof(NFP::EncryptedNTAG215File)) {
+ if (data.size() < sizeof(NFP::EncryptedNTAG215File)) {
LOG_ERROR(Service_NFC, "Not an amiibo, size={}", data.size());
return false;
}
+ tag_data.resize(data.size());
+ memcpy(tag_data.data(), data.data(), data.size());
memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
device_state = NFP::DeviceState::TagFound;
@@ -121,7 +123,7 @@ void NfcDevice::Finalize() {
device_state = NFP::DeviceState::Unavailable;
}
-Result NfcDevice::StartDetection(s32 protocol_) {
+Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
if (device_state != NFP::DeviceState::Initialized &&
device_state != NFP::DeviceState::TagRemoved) {
LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
@@ -134,7 +136,7 @@ Result NfcDevice::StartDetection(s32 protocol_) {
}
device_state = NFP::DeviceState::SearchingForTag;
- protocol = protocol_;
+ allowed_protocols = allowed_protocol;
return ResultSuccess;
}
@@ -160,7 +162,7 @@ Result NfcDevice::StopDetection() {
return WrongDeviceState;
}
-Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info) const {
+Result NfcDevice::Flush() {
if (device_state != NFP::DeviceState::TagFound &&
device_state != NFP::DeviceState::TagMounted) {
LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
@@ -170,6 +172,34 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info) const {
return WrongDeviceState;
}
+ if (!npad_device->WriteNfc(tag_data)) {
+ LOG_ERROR(Service_NFP, "Error writing to file");
+ return MifareReadError;
+ }
+
+ return ResultSuccess;
+}
+
+Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const {
+ if (device_state != NFP::DeviceState::TagFound &&
+ device_state != NFP::DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
+ if (device_state == NFP::DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (is_mifare) {
+ tag_info = {
+ .uuid = encrypted_tag_data.uuid.uid,
+ .uuid_length = static_cast<u8>(encrypted_tag_data.uuid.uid.size()),
+ .protocol = NFP::TagProtocol::TypeA,
+ .tag_type = NFP::TagType::Type4,
+ };
+ return ResultSuccess;
+ }
+
// Protocol and tag type may change here
tag_info = {
.uuid = encrypted_tag_data.uuid.uid,
@@ -181,6 +211,52 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info) const {
return ResultSuccess;
}
+Result NfcDevice::MifareRead(const NFP::MifareReadBlockParameter& parameter,
+ NFP::MifareReadBlockData& read_block_data) {
+ const std::size_t sector_index = parameter.sector_number * sizeof(NFP::DataBlock);
+ read_block_data.sector_number = parameter.sector_number;
+
+ if (device_state != NFP::DeviceState::TagFound &&
+ device_state != NFP::DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
+ if (device_state == NFP::DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (tag_data.size() < sector_index + sizeof(NFP::DataBlock)) {
+ return MifareReadError;
+ }
+
+ // TODO: Use parameter.sector_key to read encrypted data
+ memcpy(read_block_data.data.data(), tag_data.data() + sector_index, sizeof(NFP::DataBlock));
+
+ return ResultSuccess;
+}
+
+Result NfcDevice::MifareWrite(const NFP::MifareWriteBlockParameter& parameter) {
+ const std::size_t sector_index = parameter.sector_number * sizeof(NFP::DataBlock);
+
+ if (device_state != NFP::DeviceState::TagFound &&
+ device_state != NFP::DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
+ if (device_state == NFP::DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (tag_data.size() < sector_index + sizeof(NFP::DataBlock)) {
+ return MifareReadError;
+ }
+
+ // TODO: Use parameter.sector_key to encrypt the data
+ memcpy(tag_data.data() + sector_index, parameter.data.data(), sizeof(NFP::DataBlock));
+
+ return ResultSuccess;
+}
+
u64 NfcDevice::GetHandle() const {
// Generate a handle based of the npad id
return static_cast<u64>(npad_id);
diff --git a/src/core/hle/service/nfc/nfc_device.h b/src/core/hle/service/nfc/nfc_device.h
index fa1348f1a..a6e114d36 100644
--- a/src/core/hle/service/nfc/nfc_device.h
+++ b/src/core/hle/service/nfc/nfc_device.h
@@ -34,10 +34,16 @@ public:
void Initialize();
void Finalize();
- Result StartDetection(s32 protocol_);
+ Result StartDetection(NFP::TagProtocol allowed_protocol);
Result StopDetection();
+ Result Flush();
- Result GetTagInfo(NFP::TagInfo& tag_info) const;
+ Result GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const;
+
+ Result MifareRead(const NFP::MifareReadBlockParameter& parameter,
+ NFP::MifareReadBlockData& read_block_data);
+
+ Result MifareWrite(const NFP::MifareWriteBlockParameter& parameter);
u64 GetHandle() const;
NFP::DeviceState GetCurrentState() const;
@@ -61,10 +67,11 @@ private:
Kernel::KEvent* deactivate_event = nullptr;
Kernel::KEvent* availability_change_event = nullptr;
- s32 protocol{};
+ NFP::TagProtocol allowed_protocols{};
NFP::DeviceState device_state{NFP::DeviceState::Unavailable};
NFP::EncryptedNTAG215File encrypted_tag_data{};
+ std::vector<u8> tag_data{};
};
} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc_result.h b/src/core/hle/service/nfc/nfc_result.h
index 537dc15f4..146b8ba61 100644
--- a/src/core/hle/service/nfc/nfc_result.h
+++ b/src/core/hle/service/nfc/nfc_result.h
@@ -12,6 +12,12 @@ constexpr Result InvalidArgument(ErrorModule::NFC, 65);
constexpr Result WrongDeviceState(ErrorModule::NFC, 73);
constexpr Result NfcDisabled(ErrorModule::NFC, 80);
constexpr Result TagRemoved(ErrorModule::NFC, 97);
-constexpr Result CorruptedData(ErrorModule::NFC, 144);
+
+constexpr Result MifareDeviceNotFound(ErrorModule::NFCMifare, 64);
+constexpr Result MifareInvalidArgument(ErrorModule::NFCMifare, 65);
+constexpr Result MifareWrongDeviceState(ErrorModule::NFCMifare, 73);
+constexpr Result MifareNfcDisabled(ErrorModule::NFCMifare, 80);
+constexpr Result MifareTagRemoved(ErrorModule::NFCMifare, 97);
+constexpr Result MifareReadError(ErrorModule::NFCMifare, 288);
} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc_user.cpp b/src/core/hle/service/nfc/nfc_user.cpp
index ced2d560b..4615697e2 100644
--- a/src/core/hle/service/nfc/nfc_user.cpp
+++ b/src/core/hle/service/nfc/nfc_user.cpp
@@ -201,7 +201,7 @@ void IUser::AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) {
void IUser::StartDetection(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto device_handle{rp.Pop<u64>()};
- const auto nfp_protocol{rp.Pop<s32>()};
+ const auto nfp_protocol{rp.PopEnum<NFP::TagProtocol>()};
LOG_INFO(Service_NFC, "called, device_handle={}, nfp_protocol={}", device_handle, nfp_protocol);
if (state == State::NonInitialized) {
@@ -267,7 +267,7 @@ void IUser::GetTagInfo(Kernel::HLERequestContext& ctx) {
}
NFP::TagInfo tag_info{};
- const auto result = device.value()->GetTagInfo(tag_info);
+ const auto result = device.value()->GetTagInfo(tag_info, false);
ctx.WriteBuffer(tag_info);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h
index 69858096a..fc228c2b2 100644
--- a/src/core/hle/service/nfp/nfp_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -106,11 +106,24 @@ enum class CabinetMode : u8 {
StartFormatter,
};
+enum class MifareCmd : u8 {
+ AuthA = 0x60,
+ AuthB = 0x61,
+ Read = 0x30,
+ Write = 0xA0,
+ Transfer = 0xB0,
+ Decrement = 0xC0,
+ Increment = 0xC1,
+ Store = 0xC2
+};
+
using UniqueSerialNumber = std::array<u8, 7>;
using LockBytes = std::array<u8, 2>;
using HashData = std::array<u8, 0x20>;
using ApplicationArea = std::array<u8, 0xD8>;
using AmiiboName = std::array<char, (amiibo_name_length * 4) + 1>;
+using DataBlock = std::array<u8, 0x10>;
+using KeyData = std::array<u8, 0x6>;
struct TagUuid {
UniqueSerialNumber uid;
@@ -323,4 +336,37 @@ struct RegisterInfo {
};
static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size");
+struct SectorKey {
+ MifareCmd command;
+ u8 unknown; // Usually 1
+ INSERT_PADDING_BYTES(0x6);
+ KeyData sector_key;
+ INSERT_PADDING_BYTES(0x2);
+};
+static_assert(sizeof(SectorKey) == 0x10, "SectorKey is an invalid size");
+
+struct MifareReadBlockParameter {
+ u8 sector_number;
+ INSERT_PADDING_BYTES(0x7);
+ SectorKey sector_key;
+};
+static_assert(sizeof(MifareReadBlockParameter) == 0x18,
+ "MifareReadBlockParameter is an invalid size");
+
+struct MifareReadBlockData {
+ DataBlock data;
+ u8 sector_number;
+ INSERT_PADDING_BYTES(0x7);
+};
+static_assert(sizeof(MifareReadBlockData) == 0x18, "MifareReadBlockData is an invalid size");
+
+struct MifareWriteBlockParameter {
+ DataBlock data;
+ u8 sector_number;
+ INSERT_PADDING_BYTES(0x7);
+ SectorKey sector_key;
+};
+static_assert(sizeof(MifareWriteBlockParameter) == 0x28,
+ "MifareWriteBlockParameter is an invalid size");
+
} // namespace Service::NFP
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 6e21296f6..77821e047 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -38,7 +38,7 @@ std::string GetTimestamp() {
using namespace nlohmann;
-void SaveToFile(json json, const std::filesystem::path& filename) {
+void SaveToFile(const json& json, const std::filesystem::path& filename) {
if (!Common::FS::CreateParentDirs(filename)) {
LOG_ERROR(Core, "Failed to create path for '{}' to save report!",
Common::FS::PathToUTF8String(filename));
@@ -81,8 +81,8 @@ json GetReportCommonData(u64 title_id, Result result, const std::string& timesta
}
json GetProcessorStateData(const std::string& architecture, u64 entry_point, u64 sp, u64 pc,
- u64 pstate, std::array<u64, 31> registers,
- std::optional<std::array<u64, 32>> backtrace = {}) {
+ u64 pstate, const std::array<u64, 31>& registers,
+ const std::optional<std::array<u64, 32>>& backtrace = {}) {
auto out = json{
{"entry_point", fmt::format("{:016X}", entry_point)},
{"sp", fmt::format("{:016X}", sp)},
@@ -224,11 +224,11 @@ void Reporter::SaveCrashReport(u64 title_id, Result result, u64 set_flags, u64 e
out["processor_state"] = std::move(proc_out);
- SaveToFile(std::move(out), GetPath("crash_report", title_id, timestamp));
+ SaveToFile(out, GetPath("crash_report", title_id, timestamp));
}
void Reporter::SaveSvcBreakReport(u32 type, bool signal_debugger, u64 info1, u64 info2,
- std::optional<std::vector<u8>> resolved_buffer) const {
+ const std::optional<std::vector<u8>>& resolved_buffer) const {
if (!IsReportingEnabled()) {
return;
}
@@ -250,7 +250,7 @@ void Reporter::SaveSvcBreakReport(u32 type, bool signal_debugger, u64 info1, u64
out["svc_break"] = std::move(break_out);
- SaveToFile(std::move(out), GetPath("svc_break_report", title_id, timestamp));
+ SaveToFile(out, GetPath("svc_break_report", title_id, timestamp));
}
void Reporter::SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u32 command_id,
@@ -271,13 +271,13 @@ void Reporter::SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u
out["function"] = std::move(function_out);
- SaveToFile(std::move(out), GetPath("unimpl_func_report", title_id, timestamp));
+ SaveToFile(out, GetPath("unimpl_func_report", title_id, timestamp));
}
void Reporter::SaveUnimplementedAppletReport(
u32 applet_id, u32 common_args_version, u32 library_version, u32 theme_color,
- bool startup_sound, u64 system_tick, std::vector<std::vector<u8>> normal_channel,
- std::vector<std::vector<u8>> interactive_channel) const {
+ bool startup_sound, u64 system_tick, const std::vector<std::vector<u8>>& normal_channel,
+ const std::vector<std::vector<u8>>& interactive_channel) const {
if (!IsReportingEnabled()) {
return;
}
@@ -308,10 +308,11 @@ void Reporter::SaveUnimplementedAppletReport(
out["applet_normal_data"] = std::move(normal_out);
out["applet_interactive_data"] = std::move(interactive_out);
- SaveToFile(std::move(out), GetPath("unimpl_applet_report", title_id, timestamp));
+ SaveToFile(out, GetPath("unimpl_applet_report", title_id, timestamp));
}
-void Reporter::SavePlayReport(PlayReportType type, u64 title_id, std::vector<std::vector<u8>> data,
+void Reporter::SavePlayReport(PlayReportType type, u64 title_id,
+ const std::vector<std::vector<u8>>& data,
std::optional<u64> process_id, std::optional<u128> user_id) const {
if (!IsReportingEnabled()) {
return;
@@ -335,12 +336,12 @@ void Reporter::SavePlayReport(PlayReportType type, u64 title_id, std::vector<std
out["play_report_type"] = fmt::format("{:02}", static_cast<u8>(type));
out["play_report_data"] = std::move(data_out);
- SaveToFile(std::move(out), GetPath("play_report", title_id, timestamp));
+ SaveToFile(out, GetPath("play_report", title_id, timestamp));
}
void Reporter::SaveErrorReport(u64 title_id, Result result,
- std::optional<std::string> custom_text_main,
- std::optional<std::string> custom_text_detail) const {
+ const std::optional<std::string>& custom_text_main,
+ const std::optional<std::string>& custom_text_detail) const {
if (!IsReportingEnabled()) {
return;
}
@@ -354,11 +355,11 @@ void Reporter::SaveErrorReport(u64 title_id, Result result,
out["backtrace"] = GetBacktraceData(system);
out["error_custom_text"] = {
- {"main", *custom_text_main},
- {"detail", *custom_text_detail},
+ {"main", custom_text_main.value_or("")},
+ {"detail", custom_text_detail.value_or("")},
};
- SaveToFile(std::move(out), GetPath("error_report", title_id, timestamp));
+ SaveToFile(out, GetPath("error_report", title_id, timestamp));
}
void Reporter::SaveFSAccessLog(std::string_view log_message) const {
diff --git a/src/core/reporter.h b/src/core/reporter.h
index 68755cbde..9fdb9d6c1 100644
--- a/src/core/reporter.h
+++ b/src/core/reporter.h
@@ -36,7 +36,7 @@ public:
// Used by syscall svcBreak
void SaveSvcBreakReport(u32 type, bool signal_debugger, u64 info1, u64 info2,
- std::optional<std::vector<u8>> resolved_buffer = {}) const;
+ const std::optional<std::vector<u8>>& resolved_buffer = {}) const;
// Used by HLE service handler
void SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u32 command_id,
@@ -44,10 +44,10 @@ public:
const std::string& service_name) const;
// Used by stub applet implementation
- void SaveUnimplementedAppletReport(u32 applet_id, u32 common_args_version, u32 library_version,
- u32 theme_color, bool startup_sound, u64 system_tick,
- std::vector<std::vector<u8>> normal_channel,
- std::vector<std::vector<u8>> interactive_channel) const;
+ void SaveUnimplementedAppletReport(
+ u32 applet_id, u32 common_args_version, u32 library_version, u32 theme_color,
+ bool startup_sound, u64 system_tick, const std::vector<std::vector<u8>>& normal_channel,
+ const std::vector<std::vector<u8>>& interactive_channel) const;
enum class PlayReportType {
Old,
@@ -56,13 +56,13 @@ public:
System,
};
- void SavePlayReport(PlayReportType type, u64 title_id, std::vector<std::vector<u8>> data,
+ void SavePlayReport(PlayReportType type, u64 title_id, const std::vector<std::vector<u8>>& data,
std::optional<u64> process_id = {}, std::optional<u128> user_id = {}) const;
// Used by error applet
void SaveErrorReport(u64 title_id, Result result,
- std::optional<std::string> custom_text_main = {},
- std::optional<std::string> custom_text_detail = {}) const;
+ const std::optional<std::string>& custom_text_main = {},
+ const std::optional<std::string>& custom_text_detail = {}) const;
void SaveFSAccessLog(std::string_view log_message) const;
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index e41da2726..7932aaab0 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -56,18 +56,12 @@ if (ENABLE_SDL2)
drivers/sdl_driver.cpp
drivers/sdl_driver.h
)
- if (YUZU_USE_EXTERNAL_SDL2)
- target_link_libraries(input_common PRIVATE SDL2-static)
- else()
- target_link_libraries(input_common PRIVATE SDL2)
- endif()
+ target_link_libraries(input_common PRIVATE SDL2::SDL2)
target_compile_definitions(input_common PRIVATE HAVE_SDL2)
endif()
-target_link_libraries(input_common PRIVATE usb)
-
create_target_directory_groups(input_common)
-target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost)
+target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost libusb::usb)
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(input_common PRIVATE precompiled_headers.h)
diff --git a/src/input_common/drivers/virtual_amiibo.cpp b/src/input_common/drivers/virtual_amiibo.cpp
index 564a188e5..63ffaca67 100644
--- a/src/input_common/drivers/virtual_amiibo.cpp
+++ b/src/input_common/drivers/virtual_amiibo.cpp
@@ -47,20 +47,20 @@ Common::Input::NfcState VirtualAmiibo::SupportsNfc(
Common::Input::NfcState VirtualAmiibo::WriteNfcData(
[[maybe_unused]] const PadIdentifier& identifier_, const std::vector<u8>& data) {
- const Common::FS::IOFile amiibo_file{file_path, Common::FS::FileAccessMode::ReadWrite,
- Common::FS::FileType::BinaryFile};
+ const Common::FS::IOFile nfc_file{file_path, Common::FS::FileAccessMode::ReadWrite,
+ Common::FS::FileType::BinaryFile};
- if (!amiibo_file.IsOpen()) {
+ if (!nfc_file.IsOpen()) {
LOG_ERROR(Core, "Amiibo is already on use");
return Common::Input::NfcState::WriteFailed;
}
- if (!amiibo_file.Write(data)) {
+ if (!nfc_file.Write(data)) {
LOG_ERROR(Service_NFP, "Error writting to file");
return Common::Input::NfcState::WriteFailed;
}
- amiibo_data = data;
+ nfc_data = data;
return Common::Input::NfcState::Success;
}
@@ -70,32 +70,44 @@ VirtualAmiibo::State VirtualAmiibo::GetCurrentState() const {
}
VirtualAmiibo::Info VirtualAmiibo::LoadAmiibo(const std::string& filename) {
- const Common::FS::IOFile amiibo_file{filename, Common::FS::FileAccessMode::Read,
- Common::FS::FileType::BinaryFile};
+ const Common::FS::IOFile nfc_file{filename, Common::FS::FileAccessMode::Read,
+ Common::FS::FileType::BinaryFile};
if (state != State::WaitingForAmiibo) {
return Info::WrongDeviceState;
}
- if (!amiibo_file.IsOpen()) {
+ if (!nfc_file.IsOpen()) {
return Info::UnableToLoad;
}
- amiibo_data.resize(amiibo_size);
-
- if (amiibo_file.Read(amiibo_data) < amiibo_size_without_password) {
+ switch (nfc_file.GetSize()) {
+ case AmiiboSize:
+ case AmiiboSizeWithoutPassword:
+ nfc_data.resize(AmiiboSize);
+ if (nfc_file.Read(nfc_data) < AmiiboSizeWithoutPassword) {
+ return Info::NotAnAmiibo;
+ }
+ break;
+ case MifareSize:
+ nfc_data.resize(MifareSize);
+ if (nfc_file.Read(nfc_data) < MifareSize) {
+ return Info::NotAnAmiibo;
+ }
+ break;
+ default:
return Info::NotAnAmiibo;
}
file_path = filename;
state = State::AmiiboIsOpen;
- SetNfc(identifier, {Common::Input::NfcState::NewAmiibo, amiibo_data});
+ SetNfc(identifier, {Common::Input::NfcState::NewAmiibo, nfc_data});
return Info::Success;
}
VirtualAmiibo::Info VirtualAmiibo::ReloadAmiibo() {
if (state == State::AmiiboIsOpen) {
- SetNfc(identifier, {Common::Input::NfcState::NewAmiibo, amiibo_data});
+ SetNfc(identifier, {Common::Input::NfcState::NewAmiibo, nfc_data});
return Info::Success;
}
diff --git a/src/input_common/drivers/virtual_amiibo.h b/src/input_common/drivers/virtual_amiibo.h
index 9baeb3997..0f9dad333 100644
--- a/src/input_common/drivers/virtual_amiibo.h
+++ b/src/input_common/drivers/virtual_amiibo.h
@@ -53,12 +53,13 @@ public:
std::string GetLastFilePath() const;
private:
- static constexpr std::size_t amiibo_size = 0x21C;
- static constexpr std::size_t amiibo_size_without_password = amiibo_size - 0x8;
+ static constexpr std::size_t AmiiboSize = 0x21C;
+ static constexpr std::size_t AmiiboSizeWithoutPassword = AmiiboSize - 0x8;
+ static constexpr std::size_t MifareSize = 0x400;
std::string file_path{};
State state{State::Initialized};
- std::vector<u8> amiibo_data;
+ std::vector<u8> nfc_data;
Common::Input::PollingMode polling_mode{Common::Input::PollingMode::Pasive};
};
} // namespace InputCommon
diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt
index c85c308de..1ab52da59 100644
--- a/src/network/CMakeLists.txt
+++ b/src/network/CMakeLists.txt
@@ -19,7 +19,7 @@ add_library(network STATIC
create_target_directory_groups(network)
-target_link_libraries(network PRIVATE common enet Boost::boost)
+target_link_libraries(network PRIVATE common enet::enet Boost::boost)
if (ENABLE_WEB_SERVICE)
target_compile_definitions(network PRIVATE -DENABLE_WEB_SERVICE)
target_link_libraries(network PRIVATE web_service)
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 33bdae748..06e44d5b5 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -266,8 +266,7 @@ target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})
add_dependencies(video_core host_shaders)
target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})
-target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include)
-target_link_libraries(video_core PRIVATE sirit)
+target_link_libraries(video_core PRIVATE sirit Vulkan::Headers)
if (ENABLE_NSIGHT_AFTERMATH)
if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK})
@@ -307,11 +306,11 @@ if (ARCHITECTURE_x86_64)
macro/macro_jit_x64.cpp
macro/macro_jit_x64.h
)
- target_link_libraries(video_core PUBLIC xbyak)
+ target_link_libraries(video_core PUBLIC xbyak::xbyak)
endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
- target_link_libraries(video_core PRIVATE dynarmic)
+ target_link_libraries(video_core PRIVATE dynarmic::dynarmic)
endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index d4ef8d7c5..9b182b653 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -382,41 +382,51 @@ void Maxwell3D::ProcessQueryGet() {
void Maxwell3D::ProcessQueryCondition() {
const GPUVAddr condition_address{regs.render_enable.Address()};
- switch (regs.render_enable.mode) {
- case Regs::RenderEnable::Mode::True: {
+ switch (regs.render_enable_override) {
+ case Regs::RenderEnable::Override::AlwaysRender:
execute_on = true;
break;
- }
- case Regs::RenderEnable::Mode::False: {
+ case Regs::RenderEnable::Override::NeverRender:
execute_on = false;
break;
- }
- case Regs::RenderEnable::Mode::Conditional: {
- Regs::ReportSemaphore::Compare cmp;
- memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
- execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
- break;
- }
- case Regs::RenderEnable::Mode::IfEqual: {
- Regs::ReportSemaphore::Compare cmp;
- memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
- execute_on =
- cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode;
- break;
- }
- case Regs::RenderEnable::Mode::IfNotEqual: {
- Regs::ReportSemaphore::Compare cmp;
- memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
- execute_on =
- cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode;
- break;
- }
- default: {
- UNIMPLEMENTED_MSG("Uninplemented Condition Mode!");
- execute_on = true;
+ case Regs::RenderEnable::Override::UseRenderEnable:
+ switch (regs.render_enable.mode) {
+ case Regs::RenderEnable::Mode::True: {
+ execute_on = true;
+ break;
+ }
+ case Regs::RenderEnable::Mode::False: {
+ execute_on = false;
+ break;
+ }
+ case Regs::RenderEnable::Mode::Conditional: {
+ Regs::ReportSemaphore::Compare cmp;
+ memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
+ execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
+ break;
+ }
+ case Regs::RenderEnable::Mode::IfEqual: {
+ Regs::ReportSemaphore::Compare cmp;
+ memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
+ execute_on = cmp.initial_sequence == cmp.current_sequence &&
+ cmp.initial_mode == cmp.current_mode;
+ break;
+ }
+ case Regs::RenderEnable::Mode::IfNotEqual: {
+ Regs::ReportSemaphore::Compare cmp;
+ memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
+ execute_on = cmp.initial_sequence != cmp.current_sequence ||
+ cmp.initial_mode != cmp.current_mode;
+ break;
+ }
+ default: {
+ UNIMPLEMENTED_MSG("Uninplemented Condition Mode!");
+ execute_on = true;
+ break;
+ }
+ }
break;
}
- }
}
void Maxwell3D::ProcessCounterReset() {
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 24529c80f..e62b36822 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -95,6 +95,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0);
conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0);
smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0);
+ alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0);
+ alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0);
for (size_t i = 0; i < regs.rt.size(); ++i) {
color_formats[i] = static_cast<u8>(regs.rt[i].format);
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 1afdef329..ab79fb8f3 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -195,6 +195,8 @@ struct FixedPipelineState {
BitField<12, 1, u32> provoking_vertex_last;
BitField<13, 1, u32> conservative_raster_enable;
BitField<14, 1, u32> smooth_lines;
+ BitField<15, 1, u32> alpha_to_coverage_enabled;
+ BitField<16, 1, u32> alpha_to_one_enabled;
};
std::array<u8, Maxwell::NumRenderTargets> color_formats;
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index e77a57a4a..006128638 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -714,8 +714,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.sampleShadingEnable = VK_FALSE,
.minSampleShading = 0.0f,
.pSampleMask = nullptr,
- .alphaToCoverageEnable = VK_FALSE,
- .alphaToOneEnable = VK_FALSE,
+ .alphaToCoverageEnable = key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE,
+ .alphaToOneEnable = key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE,
};
const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
diff --git a/src/video_core/vulkan_common/vulkan_debug_callback.cpp b/src/video_core/vulkan_common/vulkan_debug_callback.cpp
index 736474009..10a001b8f 100644
--- a/src/video_core/vulkan_common/vulkan_debug_callback.cpp
+++ b/src/video_core/vulkan_common/vulkan_debug_callback.cpp
@@ -16,6 +16,8 @@ VkBool32 Callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
case 0x682a878au: // VUID-vkCmdBindVertexBuffers2EXT-pBuffers-parameter
case 0x99fb7dfdu: // UNASSIGNED-RequiredParameter (vkCmdBindVertexBuffers2EXT pBuffers[0])
case 0xe8616bf2u: // Bound VkDescriptorSet 0x0[] was destroyed. Likely push_descriptor related
+ case 0x1608dec0u: // Image layout in vkUpdateDescriptorSet doesn't match descriptor use
+ case 0x55362756u: // Descriptor binding and framebuffer attachment overlap
return VK_FALSE;
default:
break;
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 33856fe59..6a2ad4b1d 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -86,6 +86,8 @@ constexpr std::array REQUIRED_EXTENSIONS{
};
constexpr std::array REQUIRED_EXTENSIONS_BEFORE_1_2{
+ VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
+ VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME,
VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
@@ -1117,7 +1119,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false);
test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false);
test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
- test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
+ test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, true);
test(has_ext_provoking_vertex, VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, false);
test(has_ext_vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME,
false);
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index e4a07813f..bda10ee2f 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -454,6 +454,12 @@ VkResult Free(VkDevice device, VkCommandPool handle, Span<VkCommandBuffer> buffe
Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char*> extensions,
InstanceDispatch& dispatch) {
+#ifdef __APPLE__
+ constexpr VkFlags ci_flags{VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR};
+#else
+ constexpr VkFlags ci_flags{};
+#endif
+
const VkApplicationInfo application_info{
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr,
@@ -466,7 +472,7 @@ Instance Instance::Create(u32 version, Span<const char*> layers, Span<const char
const VkInstanceCreateInfo ci{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
- .flags = 0,
+ .flags = ci_flags,
.pApplicationInfo = &application_info,
.enabledLayerCount = layers.size(),
.ppEnabledLayerNames = layers.data(),
diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt
index 19534b9e4..02582aa04 100644
--- a/src/web_service/CMakeLists.txt
+++ b/src/web_service/CMakeLists.txt
@@ -17,7 +17,7 @@ add_library(web_service STATIC
)
create_target_directory_groups(web_service)
-target_link_libraries(web_service PRIVATE common network nlohmann_json::nlohmann_json httplib cpp-jwt)
+target_link_libraries(web_service PRIVATE common network nlohmann_json::nlohmann_json httplib::httplib cpp-jwt::cpp-jwt)
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(web_service PRIVATE precompiled_headers.h)
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index f192d6329..d23eb2907 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -318,7 +318,7 @@ target_link_libraries(yuzu PRIVATE common core input_common network video_core)
target_link_libraries(yuzu PRIVATE Boost::boost glad Qt${QT_MAJOR_VERSION}::Widgets)
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
-target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include)
+target_link_libraries(yuzu PRIVATE Vulkan::Headers)
if (NOT WIN32)
target_include_directories(yuzu PRIVATE ${Qt${QT_MAJOR_VERSION}Gui_PRIVATE_INCLUDE_DIRS})
endif()
@@ -354,7 +354,7 @@ if (USE_DISCORD_PRESENCE)
discord_impl.cpp
discord_impl.h
)
- target_link_libraries(yuzu PRIVATE discord-rpc)
+ target_link_libraries(yuzu PRIVATE DiscordRPC::discord-rpc)
target_compile_definitions(yuzu PRIVATE -DUSE_DISCORD_PRESENCE)
endif()
@@ -391,11 +391,7 @@ if (YUZU_USE_BUNDLED_QT AND QT_VERSION VERSION_LESS 6)
endif()
if (ENABLE_SDL2)
- if (YUZU_USE_EXTERNAL_SDL2)
- target_link_libraries(yuzu PRIVATE SDL2-static)
- else()
- target_link_libraries(yuzu PRIVATE SDL2)
- endif()
+ target_link_libraries(yuzu PRIVATE SDL2::SDL2)
target_compile_definitions(yuzu PRIVATE HAVE_SDL2)
endif()
@@ -411,7 +407,7 @@ if (NOT APPLE)
endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
- target_link_libraries(yuzu PRIVATE dynarmic)
+ target_link_libraries(yuzu PRIVATE dynarmic::dynarmic)
endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index 12efdc216..c30b54499 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -685,7 +685,7 @@ QtControllerSelector::QtControllerSelector(GMainWindow& parent) {
QtControllerSelector::~QtControllerSelector() = default;
void QtControllerSelector::ReconfigureControllers(
- std::function<void()> callback_, const Core::Frontend::ControllerParameters& parameters) const {
+ ReconfigureCallback callback_, const Core::Frontend::ControllerParameters& parameters) const {
callback = std::move(callback_);
emit MainWindowReconfigureControllers(parameters);
}
diff --git a/src/yuzu/applets/qt_controller.h b/src/yuzu/applets/qt_controller.h
index cf948d2b5..16e99f507 100644
--- a/src/yuzu/applets/qt_controller.h
+++ b/src/yuzu/applets/qt_controller.h
@@ -157,7 +157,7 @@ public:
~QtControllerSelector() override;
void ReconfigureControllers(
- std::function<void()> callback_,
+ ReconfigureCallback callback_,
const Core::Frontend::ControllerParameters& parameters) const override;
signals:
@@ -167,5 +167,5 @@ signals:
private:
void MainWindowReconfigureFinished();
- mutable std::function<void()> callback;
+ mutable ReconfigureCallback callback;
};
diff --git a/src/yuzu/applets/qt_error.cpp b/src/yuzu/applets/qt_error.cpp
index 367d5352d..e0190a979 100644
--- a/src/yuzu/applets/qt_error.cpp
+++ b/src/yuzu/applets/qt_error.cpp
@@ -14,7 +14,7 @@ QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) {
QtErrorDisplay::~QtErrorDisplay() = default;
-void QtErrorDisplay::ShowError(Result error, std::function<void()> finished) const {
+void QtErrorDisplay::ShowError(Result error, FinishedCallback finished) const {
callback = std::move(finished);
emit MainWindowDisplayError(
tr("Error Code: %1-%2 (0x%3)")
@@ -25,7 +25,7 @@ void QtErrorDisplay::ShowError(Result error, std::function<void()> finished) con
}
void QtErrorDisplay::ShowErrorWithTimestamp(Result error, std::chrono::seconds time,
- std::function<void()> finished) const {
+ FinishedCallback finished) const {
callback = std::move(finished);
const QDateTime date_time = QDateTime::fromSecsSinceEpoch(time.count());
@@ -42,7 +42,7 @@ void QtErrorDisplay::ShowErrorWithTimestamp(Result error, std::chrono::seconds t
void QtErrorDisplay::ShowCustomErrorText(Result error, std::string dialog_text,
std::string fullscreen_text,
- std::function<void()> finished) const {
+ FinishedCallback finished) const {
callback = std::move(finished);
emit MainWindowDisplayError(
tr("Error Code: %1-%2 (0x%3)")
diff --git a/src/yuzu/applets/qt_error.h b/src/yuzu/applets/qt_error.h
index eb4107c7e..e4e174721 100644
--- a/src/yuzu/applets/qt_error.h
+++ b/src/yuzu/applets/qt_error.h
@@ -16,11 +16,11 @@ public:
explicit QtErrorDisplay(GMainWindow& parent);
~QtErrorDisplay() override;
- void ShowError(Result error, std::function<void()> finished) const override;
+ void ShowError(Result error, FinishedCallback finished) const override;
void ShowErrorWithTimestamp(Result error, std::chrono::seconds time,
- std::function<void()> finished) const override;
+ FinishedCallback finished) const override;
void ShowCustomErrorText(Result error, std::string dialog_text, std::string fullscreen_text,
- std::function<void()> finished) const override;
+ FinishedCallback finished) const override;
signals:
void MainWindowDisplayError(QString error_code, QString error_text) const;
@@ -28,5 +28,5 @@ signals:
private:
void MainWindowFinishedError();
- mutable std::function<void()> callback;
+ mutable FinishedCallback callback;
};
diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp
index c8bcfb223..4145c5299 100644
--- a/src/yuzu/applets/qt_profile_select.cpp
+++ b/src/yuzu/applets/qt_profile_select.cpp
@@ -163,8 +163,7 @@ QtProfileSelector::QtProfileSelector(GMainWindow& parent) {
QtProfileSelector::~QtProfileSelector() = default;
-void QtProfileSelector::SelectProfile(
- std::function<void(std::optional<Common::UUID>)> callback_) const {
+void QtProfileSelector::SelectProfile(SelectProfileCallback callback_) const {
callback = std::move(callback_);
emit MainWindowSelectProfile();
}
diff --git a/src/yuzu/applets/qt_profile_select.h b/src/yuzu/applets/qt_profile_select.h
index 124f2cdbd..637a3bda2 100644
--- a/src/yuzu/applets/qt_profile_select.h
+++ b/src/yuzu/applets/qt_profile_select.h
@@ -65,7 +65,7 @@ public:
explicit QtProfileSelector(GMainWindow& parent);
~QtProfileSelector() override;
- void SelectProfile(std::function<void(std::optional<Common::UUID>)> callback_) const override;
+ void SelectProfile(SelectProfileCallback callback_) const override;
signals:
void MainWindowSelectProfile() const;
@@ -73,5 +73,5 @@ signals:
private:
void MainWindowFinishedSelection(std::optional<Common::UUID> uuid);
- mutable std::function<void(std::optional<Common::UUID>)> callback;
+ mutable SelectProfileCallback callback;
};
diff --git a/src/yuzu/applets/qt_software_keyboard.cpp b/src/yuzu/applets/qt_software_keyboard.cpp
index e60506197..734b0ea40 100644
--- a/src/yuzu/applets/qt_software_keyboard.cpp
+++ b/src/yuzu/applets/qt_software_keyboard.cpp
@@ -1566,10 +1566,7 @@ QtSoftwareKeyboard::~QtSoftwareKeyboard() = default;
void QtSoftwareKeyboard::InitializeKeyboard(
bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters,
- std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback_,
- std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback_) {
+ SubmitNormalCallback submit_normal_callback_, SubmitInlineCallback submit_inline_callback_) {
if (is_inline) {
submit_inline_callback = std::move(submit_inline_callback_);
} else {
diff --git a/src/yuzu/applets/qt_software_keyboard.h b/src/yuzu/applets/qt_software_keyboard.h
index 35d4ee2ef..30ac8ecf6 100644
--- a/src/yuzu/applets/qt_software_keyboard.h
+++ b/src/yuzu/applets/qt_software_keyboard.h
@@ -233,12 +233,10 @@ public:
explicit QtSoftwareKeyboard(GMainWindow& parent);
~QtSoftwareKeyboard() override;
- void InitializeKeyboard(
- bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters,
- std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback_,
- std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback_) override;
+ void InitializeKeyboard(bool is_inline,
+ Core::Frontend::KeyboardInitializeParameters initialize_parameters,
+ SubmitNormalCallback submit_normal_callback_,
+ SubmitInlineCallback submit_inline_callback_) override;
void ShowNormalKeyboard() const override;
@@ -279,8 +277,6 @@ private:
void SubmitInlineText(Service::AM::Applets::SwkbdReplyType reply_type,
std::u16string submitted_text, s32 cursor_position) const;
- mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string, bool)>
- submit_normal_callback;
- mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
- submit_inline_callback;
+ mutable SubmitNormalCallback submit_normal_callback;
+ mutable SubmitInlineCallback submit_inline_callback;
};
diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp
index 89bd482e0..0a5912326 100644
--- a/src/yuzu/applets/qt_web_browser.cpp
+++ b/src/yuzu/applets/qt_web_browser.cpp
@@ -401,9 +401,9 @@ QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {
QtWebBrowser::~QtWebBrowser() = default;
-void QtWebBrowser::OpenLocalWebPage(
- const std::string& local_url, std::function<void()> extract_romfs_callback_,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const {
+void QtWebBrowser::OpenLocalWebPage(const std::string& local_url,
+ ExtractROMFSCallback extract_romfs_callback_,
+ OpenWebPageCallback callback_) const {
extract_romfs_callback = std::move(extract_romfs_callback_);
callback = std::move(callback_);
@@ -416,9 +416,8 @@ void QtWebBrowser::OpenLocalWebPage(
}
}
-void QtWebBrowser::OpenExternalWebPage(
- const std::string& external_url,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const {
+void QtWebBrowser::OpenExternalWebPage(const std::string& external_url,
+ OpenWebPageCallback callback_) const {
callback = std::move(callback_);
const auto index = external_url.find('?');
diff --git a/src/yuzu/applets/qt_web_browser.h b/src/yuzu/applets/qt_web_browser.h
index 043800853..e8fe511ed 100644
--- a/src/yuzu/applets/qt_web_browser.h
+++ b/src/yuzu/applets/qt_web_browser.h
@@ -197,13 +197,11 @@ public:
~QtWebBrowser() override;
void OpenLocalWebPage(const std::string& local_url,
- std::function<void()> extract_romfs_callback_,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)>
- callback_) const override;
+ ExtractROMFSCallback extract_romfs_callback_,
+ OpenWebPageCallback callback_) const override;
void OpenExternalWebPage(const std::string& external_url,
- std::function<void(Service::AM::Applets::WebExitReason, std::string)>
- callback_) const override;
+ OpenWebPageCallback callback_) const override;
signals:
void MainWindowOpenWebPage(const std::string& main_url, const std::string& additional_args,
@@ -215,7 +213,6 @@ private:
void MainWindowWebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason,
std::string last_url);
- mutable std::function<void()> extract_romfs_callback;
-
- mutable std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback;
+ mutable ExtractROMFSCallback extract_romfs_callback;
+ mutable OpenWebPageCallback callback;
};
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index c11d1c8b3..722fc708e 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -679,6 +679,7 @@ void Config::ReadCpuValues() {
ReadBasicSetting(Settings::values.cpuopt_fastmem);
ReadBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
ReadBasicSetting(Settings::values.cpuopt_recompile_exclusives);
+ ReadBasicSetting(Settings::values.cpuopt_ignore_memory_aborts);
}
qt_config->endGroup();
@@ -1291,6 +1292,7 @@ void Config::SaveCpuValues() {
WriteBasicSetting(Settings::values.cpuopt_fastmem);
WriteBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
WriteBasicSetting(Settings::values.cpuopt_recompile_exclusives);
+ WriteBasicSetting(Settings::values.cpuopt_ignore_memory_aborts);
}
qt_config->endGroup();
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index 3c302ec16..8cfef0cc1 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -45,6 +45,9 @@ void ConfigureCpuDebug::SetConfiguration() {
ui->cpuopt_recompile_exclusives->setEnabled(runtime_lock);
ui->cpuopt_recompile_exclusives->setChecked(
Settings::values.cpuopt_recompile_exclusives.GetValue());
+ ui->cpuopt_ignore_memory_aborts->setEnabled(runtime_lock);
+ ui->cpuopt_ignore_memory_aborts->setChecked(
+ Settings::values.cpuopt_ignore_memory_aborts.GetValue());
}
void ConfigureCpuDebug::ApplyConfiguration() {
@@ -59,6 +62,7 @@ void ConfigureCpuDebug::ApplyConfiguration() {
Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked();
Settings::values.cpuopt_fastmem_exclusives = ui->cpuopt_fastmem_exclusives->isChecked();
Settings::values.cpuopt_recompile_exclusives = ui->cpuopt_recompile_exclusives->isChecked();
+ Settings::values.cpuopt_ignore_memory_aborts = ui->cpuopt_ignore_memory_aborts->isChecked();
}
void ConfigureCpuDebug::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
index 2bc268810..3010f7fad 100644
--- a/src/yuzu/configuration/configure_cpu_debug.ui
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -175,6 +175,19 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_ignore_memory_aborts">
+ <property name="toolTip">
+ <string>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by allowing invalid memory accesses to succeed.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it reduces the overhead of all memory accesses and has no impact on programs that don't access invalid memory.&lt;/div&gt;
+ </string>
+ </property>
+ <property name="text">
+ <string>Enable fallbacks for invalid memory accesses</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 8ca683966..e9388daad 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -31,7 +31,7 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* paren
ui->backend->addItem(QStringLiteral("GLSL"));
ui->backend->addItem(tr("GLASM (Assembly Shaders, NVIDIA Only)"));
- ui->backend->addItem(QStringLiteral("SPIR-V (Experimental, Mesa Only)"));
+ ui->backend->addItem(tr("SPIR-V (Experimental, Mesa Only)"));
SetupPerGameUI();
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index ed21f4b92..b1575b0d3 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -855,8 +855,7 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() {
return;
}
- const auto devices =
- emulated_controller->GetMappedDevices(Core::HID::EmulatedDeviceIndex::AllDevices);
+ const auto devices = emulated_controller->GetMappedDevices();
UpdateInputDevices();
if (devices.empty()) {
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index 1c0c1a9fe..f6eeb9d8d 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -34,7 +34,7 @@ add_executable(yuzu-cmd
create_target_directory_groups(yuzu-cmd)
target_link_libraries(yuzu-cmd PRIVATE common core input_common)
-target_link_libraries(yuzu-cmd PRIVATE inih glad)
+target_link_libraries(yuzu-cmd PRIVATE inih::INIReader glad)
if (MSVC)
target_link_libraries(yuzu-cmd PRIVATE getopt)
endif()
@@ -43,13 +43,7 @@ target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
create_resource("../../dist/yuzu.bmp" "yuzu_cmd/yuzu_icon.h" "yuzu_icon")
target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR})
-target_include_directories(yuzu-cmd PRIVATE ../../externals/Vulkan-Headers/include)
-
-if (YUZU_USE_EXTERNAL_SDL2)
- target_link_libraries(yuzu-cmd PRIVATE SDL2-static)
-else()
- target_link_libraries(yuzu-cmd PRIVATE SDL2)
-endif()
+target_link_libraries(yuzu-cmd PRIVATE SDL2::SDL2 Vulkan::Headers)
if(UNIX AND NOT APPLE)
install(TARGETS yuzu-cmd)
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 59f9c8e09..de9b220da 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -15,7 +15,7 @@
#pragma clang diagnostic pop
#endif
-#include <inih/cpp/INIReader.h>
+#include <INIReader.h>
#include "common/fs/file.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
@@ -286,6 +286,7 @@ void Config::ReadValues() {
ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives);
ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives);
+ ReadSetting("Cpu", Settings::values.cpuopt_ignore_memory_aborts);
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 5bbc3f532..6fcf04e1b 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -208,6 +208,10 @@ cpuopt_fastmem_exclusives =
# 0: Disabled, 1 (default): Enabled
cpuopt_recompile_exclusives =
+# Enable optimization to ignore invalid memory accesses (faster guest memory access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_ignore_memory_aborts =
+
# Enable unfuse FMA (improve performance on CPUs without FMA)
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
# 0: Disabled, 1 (default): Enabled