diff options
39 files changed, 790 insertions, 285 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index 1200c14bd..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) @@ -202,7 +200,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)  find_package(enet 1.3)  find_package(fmt 9 REQUIRED)  find_package(inih) -find_package(lz4 1.8 REQUIRED) +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) @@ -214,7 +213,7 @@ if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)  endif()  if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) -    find_package(dynarmic 6.2.4) +    find_package(dynarmic 6.4.0)  endif()  if (ENABLE_CUBEB) @@ -433,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() @@ -461,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 fea10d809..4ffafd18c 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -45,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 diff --git a/externals/dynarmic b/externals/dynarmic -Subproject a76a2fff534b5584c9921bc5c060e910e95b773 +Subproject bd570e093ca1d1206961296b90df65cda7de8e8 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 index 663a2592f..6dae76f4c 100644 --- a/externals/find-modules/Findenet.cmake +++ b/externals/find-modules/Findenet.cmake @@ -4,10 +4,7 @@  find_package(PkgConfig QUIET)  if (PKG_CONFIG_FOUND) -    pkg_search_module(ENET QUIET IMPORTED_TARGET GLOBAL libenet) -    if (ENET_FOUND) -        add_library(enet::enet ALIAS PkgConfig::ENET) -    endif() +    pkg_search_module(ENET QUIET IMPORTED_TARGET libenet)  endif()  include(FindPackageHandleStandardArgs) @@ -15,3 +12,7 @@ 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 index 56e92a637..b72bad076 100644 --- a/externals/find-modules/Findhttplib.cmake +++ b/externals/find-modules/Findhttplib.cmake @@ -10,13 +10,14 @@ if (httplib_FOUND)  else()      find_package(PkgConfig QUIET)      if (PKG_CONFIG_FOUND) -        pkg_search_module(HTTPLIB QUIET IMPORTED_TARGET GLOBAL cpp-httplib) -        if (HTTPLIB_FOUND) -            add_library(httplib::httplib ALIAS PkgConfig::HTTPLIB) -        endif() +        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 index 844396471..8d1a07243 100644 --- a/externals/find-modules/Findinih.cmake +++ b/externals/find-modules/Findinih.cmake @@ -4,10 +4,7 @@  find_package(PkgConfig QUIET)  if (PKG_CONFIG_FOUND) -    pkg_search_module(INIREADER QUIET IMPORTED_TARGET GLOBAL INIReader) -    if (INIREADER_FOUND) -        add_library(inih::INIReader ALIAS PkgConfig::INIREADER) -    endif() +    pkg_search_module(INIREADER QUIET IMPORTED_TARGET INIReader)  endif()  include(FindPackageHandleStandardArgs) @@ -15,3 +12,7 @@ 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 a928c4307..f4c7005ba 100644 --- a/externals/find-modules/Findlz4.cmake +++ b/externals/find-modules/Findlz4.cmake @@ -6,25 +6,23 @@ include(FindPackageHandleStandardArgs)  find_package(lz4 QUIET CONFIG)  if (lz4_FOUND)      find_package_handle_standard_args(lz4 CONFIG_MODE) -    if (NOT TARGET lz4::lz4) -        if (TARGET LZ4::lz4_shared) -            set_target_properties(LZ4::lz4_shared PROPERTIES IMPORTED_GLOBAL TRUE) -            add_library(lz4::lz4 ALIAS LZ4::lz4_shared) -        else() -            set_target_properties(LZ4::lz4_static PROPERTIES IMPORTED_GLOBAL TRUE) -            add_library(lz4::lz4 ALIAS LZ4::lz4_static) -        endif() -    endif()  else()      find_package(PkgConfig QUIET)      if (PKG_CONFIG_FOUND) -        pkg_search_module(liblz4 QUIET IMPORTED_TARGET GLOBAL liblz4) -        if (liblz4_FOUND) -            add_library(lz4::lz4 ALIAS PkgConfig::liblz4) -        endif() +        pkg_search_module(LZ4 QUIET IMPORTED_TARGET liblz4)      endif()      find_package_handle_standard_args(lz4 -        REQUIRED_VARS liblz4_LINK_LIBRARIES -        VERSION_VAR liblz4_VERSION +        REQUIRED_VARS LZ4_LINK_LIBRARIES +        VERSION_VAR LZ4_VERSION      )  endif() + +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 1c29f3598..1aacc41d0 100644 --- a/externals/find-modules/Findzstd.cmake +++ b/externals/find-modules/Findzstd.cmake @@ -6,25 +6,23 @@ include(FindPackageHandleStandardArgs)  find_package(zstd QUIET CONFIG)  if (zstd_FOUND)      find_package_handle_standard_args(zstd CONFIG_MODE) -    if (NOT TARGET zstd::zstd) -        if (TARGET zstd::libzstd_shared) -            set_target_properties(zstd::libzstd_shared PROPERTIES IMPORTED_GLOBAL TRUE) -            add_library(zstd::zstd ALIAS zstd::libzstd_shared) -        else() -            set_target_properties(zstd::libzstd_static PROPERTIES IMPORTED_GLOBAL TRUE) -            add_library(zstd::zstd ALIAS zstd::libzstd_static) -        endif() -    endif()  else()      find_package(PkgConfig QUIET)      if (PKG_CONFIG_FOUND) -        pkg_search_module(libzstd QUIET IMPORTED_TARGET GLOBAL libzstd) -        if (libzstd_FOUND) -            add_library(zstd::zstd ALIAS PkgConfig::libzstd) -        endif() +        pkg_search_module(ZSTD QUIET IMPORTED_TARGET libzstd)      endif()      find_package_handle_standard_args(zstd -        REQUIRED_VARS libzstd_LINK_LIBRARIES -        VERSION_VAR libzstd_VERSION +        REQUIRED_VARS ZSTD_LINK_LIBRARIES +        VERSION_VAR ZSTD_VERSION      )  endif() + +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/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 f573a23e6..420ba62e0 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -227,11 +227,7 @@ if(ENABLE_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/core/CMakeLists.txt b/src/core/CMakeLists.txt index ad8b8ef95..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 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/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/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 34bbc72cf..fb9b9b94e 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -493,41 +493,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/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 9971bdfab..d23eb2907 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -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() 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 19b1d258c..f6eeb9d8d 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -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_link_libraries(yuzu-cmd PRIVATE Vulkan::Headers) - -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) | 
