diff options
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(), [¶m](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(), [¶m](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> + <div style="white-space: nowrap">This optimization speeds up memory accesses by allowing invalid memory accesses to succeed.</div> + <div style="white-space: nowrap">Enabling it reduces the overhead of all memory accesses and has no impact on programs that don't access invalid memory.</div> + </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 |