diff --git a/emulators/Makefile b/emulators/Makefile index 747a87f47d6b..ebf0b36ac050 100644 --- a/emulators/Makefile +++ b/emulators/Makefile @@ -173,6 +173,8 @@ SUBDIR += xen-kernel47 SUBDIR += xhomer SUBDIR += xsystem35 + SUBDIR += yuzu + SUBDIR += yuzu-qt5 SUBDIR += xzx SUBDIR += zsnes diff --git a/emulators/yuzu-qt5/Makefile b/emulators/yuzu-qt5/Makefile new file mode 100644 index 000000000000..456d42c3f25d --- /dev/null +++ b/emulators/yuzu-qt5/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +PORTREVISION= 0 +PKGNAMESUFFIX= -qt5 + +MASTERDIR= ${.CURDIR}/../yuzu + +OPTIONS_SLAVE= QT5 + +.include "${MASTERDIR}/Makefile" diff --git a/emulators/yuzu/Makefile b/emulators/yuzu/Makefile new file mode 100644 index 000000000000..1e4216fe4c36 --- /dev/null +++ b/emulators/yuzu/Makefile @@ -0,0 +1,99 @@ +# $FreeBSD$ + +PORTNAME= yuzu +PORTVERSION= s20190629 +PORTREVISION?= 0 +CATEGORIES= emulators + +MAINTAINER= jbeich@FreeBSD.org +COMMENT= Nintendo Switch emulator/debugger + +LICENSE= APACHE20 BSD2CLAUSE BSD3CLAUSE BSL GPLv2+ ISCL LGPL21+ MIT OpenSSL UNLICENSE +LICENSE_COMB= multi +LICENSE_FILE_BSD2CLAUSE=${WRKSRC}/externals/fmt/LICENSE.rst +LICENSE_FILE_BSD3CLAUSE=${WRKSRC}/externals/inih/inih/LICENSE.txt +LICENSE_FILE_BSL= ${WRKSRC}/externals/catch/LICENSE.txt +LICENSE_FILE_GPLv2+ = ${WRKSRC}/license.txt +LICENSE_FILE_ISCL= ${WRKSRC}/externals/cubeb/LICENSE +LICENSE_FILE_LGPL21+ = ${_LICENSE_STORE}/LGPL21 # soundtouch +LICENSE_FILE_LGPL3+ = ${_LICENSE_STORE}/LGPL3 # sirit +LICENSE_FILE_MIT= ${WRKSRC}/externals/sirit/externals/SPIRV-Headers/LICENSE +LICENSE_FILE_OpenSSL= ${WRKSRC}/externals/libressl/COPYING + +ONLY_FOR_ARCHS= aarch64 amd64 powerpc64 +ONLY_FOR_ARCHS_REASON= requires int128 + +BUILD_DEPENDS= boost-libs>=1.66:devel/boost-libs \ + gmake:devel/gmake + +USE_GITHUB= yes +GH_ACCOUNT= yuzu-emu +GH_TAGNAME= 1ca2b504b +GH_TUPLE= yuzu-emu:unicorn:1.0.1-153-g73f45735:unicorn/externals/unicorn \ + DarkLordZach:mbedtls:a280e60:mbedtls/externals/mbedtls \ + KhronosGroup:SPIRV-Headers:2c51218:SPIRV_Headers/externals/sirit/externals/SPIRV-Headers \ + KhronosGroup:Vulkan-Headers:v1.1.103:Vulkan_Headers/externals/Vulkan-Headers \ + MerryMage:dynarmic:r1-1388-g2683a9a3:dynarmic/externals/dynarmic \ + ReinUsesLisp:sirit:f7c4b07:sirit/externals/sirit \ + arsenm:sanitizers-cmake:aab6948:sanitizers_cmake/externals/cubeb/cmake/sanitizers-cmake \ + catchorg:Catch2:v2.3.0:catch/externals/catch \ + citra-emu:ext-libressl-portable:7d01cb0:libressl/externals/libressl \ + citra-emu:ext-soundtouch:060181e:soundtouch/externals/soundtouch \ + facebook:zstd:v1.3.8:zstd/externals/zstd \ + fmtlib:fmt:5.3.0:fmt/externals/fmt \ + kinetiknz:cubeb:cubeb-0.2-1098-g6f2420d:cubeb/externals/cubeb \ + lz4:lz4:v1.8.0-8-g4db65c1:lz4/externals/lz4 \ + ogniK5377:opus:v1.3-rc-20-g562f8ba5:opus/externals/opus \ + svn2github:inih:603729d:inih/externals/inih/inih \ + weidai11:cryptopp:CRYPTOPP_7_0_0-23-gf320e7d9:cryptopp/externals/cryptopp/cryptopp + +USES= cmake compiler:c++17-lang iconv localbase:ldflags python:2.7,build +USE_SDL= sdl2 +LDFLAGS+= -Wl,--as-needed # Qt5Network +TEST_TARGET= test + +OPTIONS_DEFINE= ALSA PULSEAUDIO JACK SNDIO +OPTIONS_DEFAULT=ALSA PULSEAUDIO JACK +OPTIONS_MULTI= GUI +OPTIONS_MULTI_GUI= QT5 SDL +OPTIONS_SLAVE?= SDL +OPTIONS_EXCLUDE:= ${OPTIONS_MULTI_GUI} + +ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib +ALSA_RUN_DEPENDS= ${LOCALBASE}/lib/alsa-lib/libasound_module_pcm_oss.so:audio/alsa-plugins +ALSA_CMAKE_BOOL= USE_ALSA + +JACK_BUILD_DEPENDS= jackit>0:audio/jack +JACK_CMAKE_BOOL= USE_JACK + +PULSEAUDIO_BUILD_DEPENDS=pulseaudio>0.:audio/pulseaudio +PULSEAUDIO_CMAKE_BOOL= USE_PULSE + +SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio +SNDIO_CMAKE_BOOL= USE_SNDIO + +SDL_CMAKE_BOOL= ENABLE_SDL2 +SDL_PLIST_FILES=bin/${PORTNAME}-cmd \ + bin/${PORTNAME}-tester + +QT5_USES= desktop-file-utils qt:5 shared-mime-info +QT5_USE= QT=qmake_build,buildtools_build,concurrent_build,core,gui,opengl,webengine,widgets +QT5_CMAKE_BOOL= ENABLE_QT YUZU_USE_QT_WEB_ENGINE +QT5_PLIST_FILES=bin/${PORTNAME} \ + share/applications/${PORTNAME}.desktop \ + share/icons/hicolor/scalable/apps/${PORTNAME}.svg \ + share/mime/packages/${PORTNAME}.xml + +post-patch: + @${REINPLACE_CMD} -e 's,share/man,man,' \ + -e '/check_submodules_present()/d' \ + ${WRKSRC}/CMakeLists.txt + @${REINPLACE_CMD} -e 's/@GIT_BRANCH@/master/' \ + -e 's/@GIT_DESC@/${GH_TAGNAME}/' \ + ${WRKSRC}/src/common/scm_rev.cpp.in + +.ifndef QEMU_EMULATING +pre-install: do-test +.endif + +.include diff --git a/emulators/yuzu/distinfo b/emulators/yuzu/distinfo new file mode 100644 index 000000000000..79beaaa7a164 --- /dev/null +++ b/emulators/yuzu/distinfo @@ -0,0 +1,37 @@ +TIMESTAMP = 1561845347 +SHA256 (yuzu-emu-yuzu-s20190629-1ca2b504b_GH0.tar.gz) = 8e1dcc927db37427b30994f1d02bd2d28ac6c8bf4d4e67c91aa1f781a52b97bc +SIZE (yuzu-emu-yuzu-s20190629-1ca2b504b_GH0.tar.gz) = 2672141 +SHA256 (yuzu-emu-unicorn-1.0.1-153-g73f45735_GH0.tar.gz) = 8f7b4d8eb998c2a4c146268d83b44fc22ca8d4d276f26d6af1071e51f4b5bd4f +SIZE (yuzu-emu-unicorn-1.0.1-153-g73f45735_GH0.tar.gz) = 3296254 +SHA256 (DarkLordZach-mbedtls-a280e60_GH0.tar.gz) = 4fc6ddc256bc75b975fd5ad8bb7d31ff79c62d49daafb0108585c9ef80c6c5a7 +SIZE (DarkLordZach-mbedtls-a280e60_GH0.tar.gz) = 2283313 +SHA256 (KhronosGroup-SPIRV-Headers-2c51218_GH0.tar.gz) = 08f70947b69e17c7e322156adcd471cf02b4b3f63e7baf8ee0f02d32603ac5ff +SIZE (KhronosGroup-SPIRV-Headers-2c51218_GH0.tar.gz) = 280829 +SHA256 (KhronosGroup-Vulkan-Headers-v1.1.103_GH0.tar.gz) = bea7adf4b460fec1b8676f88b262beb82fe9a69906e3a9e568ff5fa81ad0539f +SIZE (KhronosGroup-Vulkan-Headers-v1.1.103_GH0.tar.gz) = 559445 +SHA256 (MerryMage-dynarmic-r1-1388-g2683a9a3_GH0.tar.gz) = bbf296c19d3215435582da804948387bfa6bedd16fd8db2b56af4a618400db38 +SIZE (MerryMage-dynarmic-r1-1388-g2683a9a3_GH0.tar.gz) = 1444605 +SHA256 (ReinUsesLisp-sirit-f7c4b07_GH0.tar.gz) = 49d2528404ef1ac89e76f48eb49ec708693ea939d0d07458f936f57f4a04b679 +SIZE (ReinUsesLisp-sirit-f7c4b07_GH0.tar.gz) = 21172 +SHA256 (arsenm-sanitizers-cmake-aab6948_GH0.tar.gz) = d9009e17948aff769a6f6e16b52d4d8752c5cc2cab1e9c381d3a31fd1a680b58 +SIZE (arsenm-sanitizers-cmake-aab6948_GH0.tar.gz) = 7240 +SHA256 (catchorg-Catch2-v2.3.0_GH0.tar.gz) = aaf6bbf81ce8522131bae2ea4d013a77b003bbb2017614f5872d5787687f8f5f +SIZE (catchorg-Catch2-v2.3.0_GH0.tar.gz) = 506374 +SHA256 (citra-emu-ext-libressl-portable-7d01cb0_GH0.tar.gz) = f3fc8c9d4991b05ca1e1c8f5907ecd3ffd9724a8dccf328087b4784cda5c7db3 +SIZE (citra-emu-ext-libressl-portable-7d01cb0_GH0.tar.gz) = 1762942 +SHA256 (citra-emu-ext-soundtouch-060181e_GH0.tar.gz) = a593ab188e4feaeef8376c27b554cc413986efc777c195e44c6d3d223de9a63c +SIZE (citra-emu-ext-soundtouch-060181e_GH0.tar.gz) = 59514 +SHA256 (facebook-zstd-v1.3.8_GH0.tar.gz) = 90d902a1282cc4e197a8023b6d6e8d331c1fd1dfe60f7f8e4ee9da40da886dc3 +SIZE (facebook-zstd-v1.3.8_GH0.tar.gz) = 1875233 +SHA256 (fmtlib-fmt-5.3.0_GH0.tar.gz) = defa24a9af4c622a7134076602070b45721a43c51598c8456ec6f2c4dbb51c89 +SIZE (fmtlib-fmt-5.3.0_GH0.tar.gz) = 662493 +SHA256 (kinetiknz-cubeb-cubeb-0.2-1098-g6f2420d_GH0.tar.gz) = f13de26eb3bdf4bf328ca199e78b242b10f750ce29c064ac650995e62e520e28 +SIZE (kinetiknz-cubeb-cubeb-0.2-1098-g6f2420d_GH0.tar.gz) = 202308 +SHA256 (lz4-lz4-v1.8.0-8-g4db65c1_GH0.tar.gz) = 31a61b29dcb0204c9ac283d24cd53ae4d7e15e6f4e7dd88919d965ff9cf8ced5 +SIZE (lz4-lz4-v1.8.0-8-g4db65c1_GH0.tar.gz) = 222985 +SHA256 (ogniK5377-opus-v1.3-rc-20-g562f8ba5_GH0.tar.gz) = ca2600f52cc4c65f5b99b80c94399d89a43e199ebcd9e4ea6e7159dfc6f25b49 +SIZE (ogniK5377-opus-v1.3-rc-20-g562f8ba5_GH0.tar.gz) = 822137 +SHA256 (svn2github-inih-603729d_GH0.tar.gz) = b4faa364c3e33261707d4b669e1c669ca3818d7b9515c15fe0befd9df3f1f00a +SIZE (svn2github-inih-603729d_GH0.tar.gz) = 8342 +SHA256 (weidai11-cryptopp-CRYPTOPP_7_0_0-23-gf320e7d9_GH0.tar.gz) = 1d6f029b83a230561e75bab26b5aaf98055b8439363a25bf113ac9ff6f9d2ef4 +SIZE (weidai11-cryptopp-CRYPTOPP_7_0_0-23-gf320e7d9_GH0.tar.gz) = 7209489 diff --git a/emulators/yuzu/files/patch-CMakeLists.txt b/emulators/yuzu/files/patch-CMakeLists.txt new file mode 100644 index 000000000000..7b0b8a25ae81 --- /dev/null +++ b/emulators/yuzu/files/patch-CMakeLists.txt @@ -0,0 +1,28 @@ +yuzu (Qt) currently needs SDL for input + +--- CMakeLists.txt.orig 2019-06-28 18:03:38 UTC ++++ CMakeLists.txt +@@ -145,15 +145,15 @@ if (ENABLE_SDL2) + else() + find_package(SDL2 REQUIRED) + endif() +- +- if (SDL2_FOUND) +- # TODO(yuriks): Make FindSDL2.cmake export an IMPORTED library instead +- add_library(SDL2 INTERFACE) +- target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}") +- target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}") +- endif() + else() +- set(SDL2_FOUND NO) ++ find_package(SDL2) ++endif() ++ ++if (SDL2_FOUND) ++ # TODO(yuriks): Make FindSDL2.cmake export an IMPORTED library instead ++ add_library(SDL2 INTERFACE) ++ target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}") ++ target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}") + endif() + + # If unicorn isn't found, msvc -> download bundled unicorn; everyone else -> build external diff --git a/emulators/yuzu/files/patch-externals_unicorn_make.sh b/emulators/yuzu/files/patch-externals_unicorn_make.sh new file mode 100644 index 000000000000..465737e0e63d --- /dev/null +++ b/emulators/yuzu/files/patch-externals_unicorn_make.sh @@ -0,0 +1,35 @@ +- DragonFly also has BSD make as make(1) +- Build verbosely to help debugging *FLAGS +- Ignore -lpthread underlinking (on WITHOUT_LLD_IS_LD) in unused samples + +--- externals/unicorn/make.sh.orig 2018-01-04 00:41:12 UTC ++++ externals/unicorn/make.sh +@@ -112,7 +112,7 @@ if [ "$UNAME" = SunOS ]; then + CC=gcc + fi + +-if [ -n "`echo "$UNAME" | grep BSD`" ]; then ++if [ -n "`echo "$UNAME" | grep -e DragonFly -e BSD`" ]; then + MAKE=gmake + PREFIX="${PREFIX-/usr/local}" + fi +@@ -120,15 +120,15 @@ fi + export CC INSTALL_BIN PREFIX PKGCFGDIR LIBDIRARCH LIBARCHS CFLAGS LDFLAGS + + case "$1" in +- "" ) ${MAKE};; ++ "" ) ${MAKE} V=1 unicorn;; + "asan" ) asan;; + "install" ) install;; + "uninstall" ) uninstall;; +- "macos-universal" ) MACOS_UNIVERSAL=yes ${MAKE};; +- "macos-universal-no" ) MACOS_UNIVERSAL=no ${MAKE};; ++ "macos-universal" ) MACOS_UNIVERSAL=yes ${MAKE} V=1 unicorn;; ++ "macos-universal-no" ) MACOS_UNIVERSAL=no ${MAKE} V=1 unicorn;; + "cross-win32" ) build_cross i686-w64-mingw32;; + "cross-win64" ) build_cross x86_64-w64-mingw32;; +- "cross-android" ) CROSS=arm-linux-androideabi ${MAKE};; ++ "cross-android" ) CROSS=arm-linux-androideabi ${MAKE} V=1 unicorn;; + "ios" ) build_iOS;; + "ios_armv7" ) build_iOS armv7;; + "ios_armv7s" ) build_iOS armv7s;; diff --git a/emulators/yuzu/files/patch-libc++6 b/emulators/yuzu/files/patch-libc++6 new file mode 100644 index 000000000000..b784e6b08688 --- /dev/null +++ b/emulators/yuzu/files/patch-libc++6 @@ -0,0 +1,181 @@ +Drop after FreeBSD 12.0 EOL. See https://reviews.llvm.org/rL332768 + +externals/dynarmic/src/frontend/A64/types.cpp:18:33: fatal error: no viable constructor or deduction guide for deduction of template arguments of 'array' + static constexpr std::array cond_strs = { + ^ +/usr/include/c++/v1/__tuple:223:64: note: candidate function template not viable: requires 0 arguments, but 16 were provided +template struct _LIBCPP_TEMPLATE_VIS array; + ^ +/usr/include/c++/v1/__tuple:223:64: note: candidate function template not viable: requires 1 argument, but 16 were provided + +--- externals/dynarmic/src/frontend/A32/disassembler/disassembler_arm.cpp.orig 2019-05-07 07:17:43 UTC ++++ externals/dynarmic/src/frontend/A32/disassembler/disassembler_arm.cpp +@@ -18,6 +18,16 @@ + #include "frontend/A32/disassembler/disassembler.h" + #include "frontend/A32/types.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace Dynarmic::A32 { + + class DisassemblerVisitor { +--- externals/dynarmic/src/frontend/A32/types.cpp.orig 2019-05-07 07:17:43 UTC ++++ externals/dynarmic/src/frontend/A32/types.cpp +@@ -10,6 +10,16 @@ + #include "common/bit_util.h" + #include "frontend/A32/types.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace Dynarmic::A32 { + + const char* CondToString(Cond cond, bool explicit_al) { +--- externals/dynarmic/src/frontend/A64/types.cpp.orig 2019-05-07 07:17:43 UTC ++++ externals/dynarmic/src/frontend/A64/types.cpp +@@ -12,6 +12,16 @@ + #include "common/bit_util.h" + #include "frontend/A64/types.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace Dynarmic::A64 { + + const char* CondToString(Cond cond) { +--- externals/dynarmic/src/frontend/ir/type.cpp.orig 2019-05-07 07:17:43 UTC ++++ externals/dynarmic/src/frontend/ir/type.cpp +@@ -13,6 +13,16 @@ + + #include "frontend/ir/type.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace Dynarmic::IR { + + std::string GetNameOf(Type type) { +--- src/core/file_sys/card_image.cpp.orig 2019-06-28 18:03:38 UTC ++++ src/core/file_sys/card_image.cpp +@@ -16,6 +16,16 @@ + #include "core/file_sys/vfs_offset.h" + #include "core/loader/loader.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace FileSys { + + constexpr std::array partition_names{ +--- src/video_core/renderer_opengl/gl_shader_decompiler.cpp.orig 2019-06-28 18:03:38 UTC ++++ src/video_core/renderer_opengl/gl_shader_decompiler.cpp +@@ -20,6 +20,16 @@ + #include "video_core/renderer_opengl/gl_shader_decompiler.h" + #include "video_core/shader/shader_ir.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace OpenGL::GLShader { + + namespace { +--- src/video_core/renderer_vulkan/vk_device.cpp.orig 2019-06-28 18:03:38 UTC ++++ src/video_core/renderer_vulkan/vk_device.cpp +@@ -10,6 +10,16 @@ + #include "video_core/renderer_vulkan/declarations.h" + #include "video_core/renderer_vulkan/vk_device.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace Vulkan { + + namespace Alternatives { +--- src/yuzu/configuration/configure_gamelist.cpp.orig 2019-06-28 18:03:38 UTC ++++ src/yuzu/configuration/configure_gamelist.cpp +@@ -11,6 +11,16 @@ + #include "yuzu/configuration/configure_gamelist.h" + #include "yuzu/ui_settings.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + namespace { + constexpr std::array default_icon_sizes{ + std::make_pair(0, QT_TR_NOOP("None")), +--- src/yuzu/util/util.cpp.orig 2019-06-28 18:03:38 UTC ++++ src/yuzu/util/util.cpp +@@ -7,6 +7,16 @@ + #include + #include "yuzu/util/util.h" + ++#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 7000 ++_LIBCPP_BEGIN_NAMESPACE_STD ++template && ...), void>::type ++ > ++array(_Tp, _Args...) ++ -> array<_Tp, 1 + sizeof...(_Args)>; ++_LIBCPP_END_NAMESPACE_STD ++#endif ++ + QFont GetMonospaceFont() { + QFont font(QStringLiteral("monospace")); + // Automatic fallback to a monospace font on on platforms without a font called "monospace" diff --git a/emulators/yuzu/pkg-descr b/emulators/yuzu/pkg-descr new file mode 100644 index 000000000000..67570a0411f3 --- /dev/null +++ b/emulators/yuzu/pkg-descr @@ -0,0 +1,12 @@ +yuzu is an experimental open-source emulator for the Nintendo Switch +from the creators of Citra. + +It is written in C++ with portability in mind, with builds actively +maintained for Windows, Linux and macOS. The emulator is currently +only useful for homebrew development and research purposes. + +yuzu only emulates a subset of Switch hardware and therefore is +generally only useful for running/debugging homebrew +applications. yuzu can boot some games, to varying degrees of success. + +WWW: https://yuzu-emu.org/