From 4a891bee92d7beea6149a672eab8490f99479671 Mon Sep 17 00:00:00 2001 From: lizzie Date: Mon, 8 Jun 2026 23:30:08 +0000 Subject: [PATCH] initial wasm support --- .ci/wasm/build.sh | 75 ++++++++++++ .patch/openssl-cmake/0005-wasm-support.patch | 55 +++++++++ .patch/openssl/0002-wasm-support.patch | 108 ++++++++++++++++++ CMakeLists.txt | 18 ++- cpmfile.json | 3 +- .../cmake-modules/DetectArchitecture.cmake | 14 ++- externals/cmake-modules/DetectPlatform.cmake | 3 + externals/ffmpeg/CMakeLists.txt | 87 ++++++++++---- externals/tz/tz/tz.cpp | 2 + src/CMakeLists.txt | 26 +++-- src/audio_core/CMakeLists.txt | 2 +- src/common/CMakeLists.txt | 8 +- src/common/fiber.cpp | 97 ++++++++++++++-- src/common/fiber.h | 3 +- src/core/CMakeLists.txt | 19 ++- src/core/arm/dynarmic/arm_dynarmic.h | 6 +- src/core/debugger/debugger.cpp | 27 ++++- src/core/hle/kernel/k_process.cpp | 13 ++- src/hid_core/CMakeLists.txt | 2 +- .../abstracted_pad/abstract_mcu_handler.h | 5 +- src/hid_core/resources/shared_memory_holder.h | 10 +- src/input_common/CMakeLists.txt | 12 +- src/input_common/main.cpp | 22 +++- src/shader_recompiler/CMakeLists.txt | 5 +- src/shader_recompiler/environment.h | 12 +- .../translate/impl/texture_fetch_swizzled.cpp | 11 +- .../translate/impl/texture_load_swizzled.cpp | 11 +- src/video_core/CMakeLists.txt | 2 +- 28 files changed, 554 insertions(+), 104 deletions(-) create mode 100644 .ci/wasm/build.sh create mode 100644 .patch/openssl-cmake/0005-wasm-support.patch create mode 100644 .patch/openssl/0002-wasm-support.patch diff --git a/.ci/wasm/build.sh b/.ci/wasm/build.sh new file mode 100644 index 0000000000..bdaab223e0 --- /dev/null +++ b/.ci/wasm/build.sh @@ -0,0 +1,75 @@ +#!/bin/sh -ex + +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +NUM_JOBS=$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2) + +: "${CCACHE:=false}" +RETURN=0 + +usage() { + cat <&2 + RETURN=1 usage +} + +type() { + [ -z "$1" ] && die "You must specify a valid type." + TYPE="$1" +} + +outdir() { + [ -z "$1" ] && die "You must specify a valid output directory." + OUTDIR="$1" +} + +while true; do + case "$1" in + -r|--release) DEVEL=false ;; + -b|--build-type) type "$2"; shift ;; + -o|--outdir) outdir "$2"; shift ;; + -h|--help) usage ;; + *) break ;; + esac + shift +done + +: "${TYPE:=Release}" +: "${DEVEL:=true}" +: "${OUTDIR:=build}" + +emcmake cmake -B "$OUTDIR" -G "Unix Makefiles" \ + -DCMAKE_BUILD_TYPE=${TYPE} \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DENABLE_OPENGL=OFF \ + -DENABLE_LTO=OFF \ + -DENABLE_QT=OFF \ + -DENABLE_UNITY_BUILD=OFF \ + -DENABLE_QT_TRANSLATION=OFF \ + -DENABLE_CUBEB=OFF \ + -DENABLE_LIBUSB=OFF \ + -DENABLE_UPDATE_CHECKER=OFF \ + -DENABLE_WEB_SERVICE=OFF \ + -DUSE_DISCORD_PRESENCE=OFF \ + -DUSE_FASTER_LINKER=ON \ + -DYUZU_USE_BUNDLED_OPENSSL=OFF \ + -DYUZU_USE_EXTERNAL_FFMPEG=ON \ + -Dzstd_FORCE_BUNDLED=ON \ + -DOpenSSL_FORCE_BUNDLED=ON +cmake --build "$OUTDIR" -- -j$NUM_JOBS diff --git a/.patch/openssl-cmake/0005-wasm-support.patch b/.patch/openssl-cmake/0005-wasm-support.patch new file mode 100644 index 0000000000..8492e3f616 --- /dev/null +++ b/.patch/openssl-cmake/0005-wasm-support.patch @@ -0,0 +1,55 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 1ca57e1..d38c0c6 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -113,9 +113,10 @@ elseif(MINGW) + find_program(MAKE mingw32-make REQUIRED) + set(OPENSSL_BUILD_TOOL ${MAKE}) + else() +- find_program(MAKE make REQUIRED) ++ find_program(MAKE gmake REQUIRED) + set(OPENSSL_BUILD_TOOL ${MAKE}) + endif() ++set(OPENSSL_BUILD_TOOL gmake) + + # Modify configure/build options + if(OPENSSL_TEST AND NOT CMAKE_CROSSCOMPILING) +@@ -140,7 +141,7 @@ if(NUMBER_OF_THREADS GREATER 1) + list(APPEND OPENSSL_CONFIGURE_OPTIONS /FS) + list(APPEND OPENSSL_BUILD_OPTIONS /J ${NUMBER_OF_THREADS}) + else() +- list(APPEND OPENSSL_BUILD_OPTIONS -j ${NUMBER_OF_THREADS}) ++# list(APPEND OPENSSL_BUILD_OPTIONS -j ${NUMBER_OF_THREADS}) + endif() + endif() + +diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake +index 3012e05..9862aa0 100644 +--- a/cmake/ConfigureOpenSSL.cmake ++++ b/cmake/ConfigureOpenSSL.cmake +@@ -134,10 +134,24 @@ function(configure_openssl) + set(VERBOSE_OPTION OUTPUT_QUIET) + endif() + ++ if (CMAKE_SYSTEM_NAME MATCHES "Emscripten") ++ set(EMSCRIPTEN_CMAKE_WRAPPER "emcmake") ++ find_program(EMCC emcc REQUIRED) ++ set(EMSCRIPTEN_LINKER ${EMCC}) ++ list(APPEND CONFIGURE_COMMAND wasm64) ++ else() ++ set(EMSCRIPTEN_CMAKE_WRAPPER "") ++ set(EMSCRIPTEN_LINKER ${CMAKE_LINKER}) ++ endif () ++ + execute_process( +- COMMAND ${CMAKE_COMMAND} -E env ++ COMMAND ${EMSCRIPTEN_CMAKE_WRAPPER} ${CMAKE_COMMAND} -E env + "CFLAGS=${CMAKE_C_FLAGS}" + "CXXFLAGS=${CMAKE_CXX_FLAGS}" ++ "LDFLAGS=${CMAKE_CXX_LINKER_FLAGS}" ++ "CC=${CMAKE_C_COMPILER}" ++ "CXX=${CMAKE_CXX_COMPILER}" ++ "LD=${EMSCRIPTEN_LINKER}" + ${CONFIGURE_COMMAND} + WORKING_DIRECTORY ${CONFIGURE_BUILD_DIR} + ${VERBOSE_OPTION} diff --git a/.patch/openssl/0002-wasm-support.patch b/.patch/openssl/0002-wasm-support.patch new file mode 100644 index 0000000000..ddf2498c08 --- /dev/null +++ b/.patch/openssl/0002-wasm-support.patch @@ -0,0 +1,108 @@ +diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf +index e62721e..6fcea0d 100644 +--- a/Configurations/10-main.conf ++++ b/Configurations/10-main.conf +@@ -1970,6 +1970,26 @@ my %targets = ( + multilib => "64", + }, + ++ "wasm32" => { ++ inherit_from => [ "BASE_unix" ], ++ CC => "emcc", ++ CXX => "emc++", ++ cflags => add("--target=wasm32-unknown-emscripten"), ++ cxxflags => add("--target=wasm32-unknown-emscripten"), ++ lib_cppflags => add("-DL_ENDIAN"), ++ bn_ops => "THIRTY_TWO_BIT", ++ }, ++ "wasm64" => { ++ inherit_from => [ "BASE_unix" ], ++ CC => "emcc", ++ CXX => "emc++", ++ cflags => add("--target=wasm64-unknown-emscripten"), ++ cxxflags => add("--target=wasm64-unknown-emscripten"), ++ lib_cppflags => add("-DL_ENDIAN"), ++ bn_ops => "SIXTY_FOUR_BIT_LONG", ++ }, ++ ++ + #### uClinux + "uClinux-dist" => { + inherit_from => [ "BASE_unix" ], +diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c +index d9e8f02..0bd63b0 100644 +--- a/crypto/rand/rand_lib.c ++++ b/crypto/rand/rand_lib.c +@@ -379,17 +379,25 @@ void RAND_add(const void *buf, int num, double randomness) + #if !defined(OPENSSL_NO_DEPRECATED_1_1_0) + int RAND_pseudo_bytes(unsigned char *buf, int num) + { ++#ifdef __EMSCRIPTEN__ ++ arc4random_buf(buf, num); ++ return 1; ++#else + const RAND_METHOD *meth = RAND_get_rand_method(); + + if (meth != NULL && meth->pseudorand != NULL) + return meth->pseudorand(buf, num); + ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED); + return -1; ++#endif + } + #endif + + int RAND_status(void) + { ++#ifdef __EMSCRIPTEN__ ++ return 1; ++#else + EVP_RAND_CTX *rand; + #ifndef OPENSSL_NO_DEPRECATED_3_0 + const RAND_METHOD *meth = RAND_get_rand_method(); +@@ -401,6 +409,7 @@ int RAND_status(void) + if ((rand = RAND_get0_primary(NULL)) == NULL) + return 0; + return EVP_RAND_get_state(rand) == EVP_RAND_STATE_READY; ++#endif + } + #else /* !FIPS_MODULE */ + +@@ -420,6 +429,10 @@ const RAND_METHOD *RAND_get_rand_method(void) + int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, + unsigned int strength) + { ++#ifdef __EMSCRIPTEN__ ++ arc4random_buf(buf, num); ++ return 1; ++#else + RAND_GLOBAL *dgbl; + EVP_RAND_CTX *rand; + #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE) +@@ -451,6 +464,7 @@ int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, + return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0); + + return 0; ++#endif + } + + int RAND_priv_bytes(unsigned char *buf, int num) +diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c +index 3d21801..e026f8f 100644 +--- a/ssl/ssl_cert.c ++++ b/ssl/ssl_cert.c +@@ -941,6 +941,7 @@ done: + return ret; + } + ++#ifndef OPENSSL_NO_POSIX_IO + int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *dir) + { +@@ -1016,6 +1017,7 @@ err: + + return ret; + } ++#endif + + static int add_uris_recursive(STACK_OF(X509_NAME) *stack, + const char *uri, int depth) diff --git a/CMakeLists.txt b/CMakeLists.txt index 00a3b39281..f69c4a1ac2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundl cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF) option(ENABLE_DEBUG_TOOLS "Enable debugging tools (maxwell disassembler, SPIRV translator, etc)" OFF) +option(ENABLE_WERROR "Enable -Werror diagnostics" OFF) # non-linux bundled qt are static if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX)) @@ -408,7 +409,12 @@ set(BUILD_TESTING OFF) set(ENABLE_TESTING OFF) # boost -set(BOOST_INCLUDE_LIBRARIES algorithm icl pool container heap asio headers process filesystem crc variant) +if (PLATFORM_EMSCRIPTEN) + set(BOOST_INCLUDE_LIBRARIES algorithm icl pool container heap headers filesystem crc variant) + set(BOOST_CONTAINER_HEADER_ONLY ON) +else() + set(BOOST_INCLUDE_LIBRARIES algorithm icl pool container heap asio headers process filesystem crc variant) +endif() AddJsonPackage(boost) @@ -429,10 +435,12 @@ if (Boost_ADDED) target_compile_options(boost_heap INTERFACE $<$:-Wno-shadow>) target_compile_options(boost_icl INTERFACE $<$:-Wno-shadow>) - target_compile_options(boost_asio INTERFACE - $<$:-Wno-conversion> - $<$:-Wno-implicit-fallthrough> - ) + # May not exist (i.e emscripten) + if (TARGET boost_asio) + target_compile_options(boost_asio INTERFACE + $<$:-Wno-conversion> + $<$:-Wno-implicit-fallthrough>) + endif() endif() endif() diff --git a/cpmfile.json b/cpmfile.json index 5bfb7ebb63..f7b2871a94 100644 --- a/cpmfile.json +++ b/cpmfile.json @@ -231,7 +231,8 @@ "0001-cpmutil-compat.patch", "0002-use-ccache.patch", "0003-use-cmake-compiler-flags.patch", - "0004-use-shell-wrapper.patch" + "0004-use-shell-wrapper.patch", + "0005-wasm-support.patch" ], "repo": "jimmy-park/openssl-cmake", "tag": "%VERSION%", diff --git a/externals/cmake-modules/DetectArchitecture.cmake b/externals/cmake-modules/DetectArchitecture.cmake index 105963c8c2..083a255a27 100644 --- a/externals/cmake-modules/DetectArchitecture.cmake +++ b/externals/cmake-modules/DetectArchitecture.cmake @@ -94,6 +94,10 @@ function(detect_architecture_symbols) endfunction() # arches here are put in a sane default order of importance +# EXCEPT FOR WASM, which must be probed for FIRST, because some genius +# decided to also allow the host architecture to be defined when building +# for the emscripten target, absolutely lovely detail. +# # notably, amd64, arm64, and riscv (in order) are BY FAR the most common # mips is pretty popular in embedded # ppc64 is pretty popular in supercomputing @@ -101,6 +105,11 @@ endfunction() # ia64 exists # the rest exist, but are probably less popular than ia64 +detect_architecture_symbols( + ARCH wasm + SYMBOLS + "__EMSCRIPTEN__") + detect_architecture_symbols( ARCH arm64 SYMBOLS @@ -203,11 +212,6 @@ detect_architecture_symbols( "__loongarch__" "__loongarch64") -detect_architecture_symbols( - ARCH wasm - SYMBOLS - "__EMSCRIPTEN__") - # "generic" target # If you have reached this point, you're on some as-of-yet unsupported architecture. # See the docs up above for known unsupported architectures diff --git a/externals/cmake-modules/DetectPlatform.cmake b/externals/cmake-modules/DetectPlatform.cmake index de1a85b793..1867e3d15b 100644 --- a/externals/cmake-modules/DetectPlatform.cmake +++ b/externals/cmake-modules/DetectPlatform.cmake @@ -33,6 +33,9 @@ elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Haiku") set(PLATFORM_HAIKU ON) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(PLATFORM_LINUX ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") + set(PLATFORM_EMSCRIPTEN ON) + message(WARNING "${CMAKE_LIBRARY_ARCHITECTURE} support is highly experimental!!!") endif() # dumb heuristic to detect msys2 diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt index 7908e0a619..ffed6b0e7f 100644 --- a/externals/ffmpeg/CMakeLists.txt +++ b/externals/ffmpeg/CMakeLists.txt @@ -37,26 +37,39 @@ if (NOT YUZU_USE_BUNDLED_FFMPEG) elseif (NOT (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES CMAKE_SYSTEM_PROCESSOR AND CMAKE_HOST_SYSTEM_NAME MATCHES CMAKE_SYSTEM_NAME)) string(TOLOWER "${CMAKE_SYSTEM_NAME}" FFmpeg_SYSTEM_NAME) - if (FFmpeg_SYSTEM_NAME STREQUAL "openorbis" OR FFmpeg_SYSTEM_NAME STREQUAL "managarm") + # All of these platforms are supported by ffmpeg as native build OSes + # anything else (like Redox or Managarm or PS4) is NOT natively supported + # hence, assume the "unix like" is just "none" for the sake of OUR sanity. + # If YOUR OS/platform has actual native support: + # 1. fucking congrats + # 2. feel free to add it on the condition below + if (NOT (PLATFORM_NETBSD OR PLATFORM_SUN OR PLATFORM_FREEBSD + OR PLATFORM_OPENBSD OR PLATFORM_DRAGONFLYBSD OR PLATFORM_HAIKU + OR PLATFORM_LINUX OR PLATFORM_MSYS OR WIN32 OR ANDROID OR APPLE)) set(FFmpeg_SYSTEM_NAME "none") endif() # TODO: Can we really do better? Auto-detection? Something clever? list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --enable-cross-compile --arch="${CMAKE_SYSTEM_PROCESSOR}" - --target-os="${FFmpeg_SYSTEM_NAME}" - --sysroot="${CMAKE_SYSROOT}" - ) + --target-os="${FFmpeg_SYSTEM_NAME}") + if (PLATFORM_EMSCRIPTEN) + # funniest trolling from emscripten, such a classic! + # maybe I should PR so they use CMAKE_SYSROOT... y'know? + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --sysroot="${EMSCRIPTEN_SYSROOT}") + else() + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --sysroot="${CMAKE_SYSROOT}") + endif() if (DEFINED FFmpeg_CROSS_PREFIX) list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --cross-prefix="${FFmpeg_CROSS_PREFIX}") else() - message(WARNING "Please set FFmpeg_CROSS_PREFIX to your cross toolchain prefix, for example: \${CMAKE_STAGING_PREFIX}/bin/${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}-") + message(WARNING "Please set FFmpeg_CROSS_PREFIX to your cross toolchain prefix, for example: ${CMAKE_STAGING_PREFIX}/bin/${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}") endif() set(FFmpeg_IS_CROSS_COMPILING TRUE) endif() endif() -if (PLATFORM_PS4 OR PLATFORM_MANAGARM) +if (PLATFORM_PS4 OR PLATFORM_MANAGARM OR PLATFORM_EMSCRIPTEN) # Doesn't support VA-API, don't go thru the embarrassment of trying to enable it list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi) elseif (UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING AND NOT ANDROID) @@ -159,20 +172,28 @@ if (PLATFORM_PS4) -lSceUserService -lSceSysmodule -lSceNet - -lSceLibcInternal - ) + -lSceLibcInternal) list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --disable-pthreads --extra-cflags=${CMAKE_SYSROOT}/usr/include --extra-cxxflags=${CMAKE_SYSROOT}/usr/include - --extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}" - ) + --extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}") elseif (PLATFORM_MANAGARM) # Required for proper stuff list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --disable-pthreads - --extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}" - ) + --extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}") +endif() + +# Usually used by Emscripten +if (DEFINED CMAKE_AR) + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --ar=${CMAKE_AR}) +endif() +if (DEFINED CMAKE_NM) + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --nm=${CMAKE_NM}) +endif() +if (DEFINED CMAKE_RANLIB) + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --ranlib=${CMAKE_RANLIB}) endif() if (YUZU_USE_BUNDLED_FFMPEG) @@ -202,6 +223,7 @@ else() # Build FFmpeg from externals message(STATUS "Using FFmpeg from externals") + set(FFmpeg_LD ${CMAKE_LINKER}) if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64)") # FFmpeg has source that requires one of nasm or yasm to assemble it. # REQUIRED throws an error if not found here during configuration rather than during compilation. @@ -210,6 +232,12 @@ else() message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.") endif() endif() + if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + # TODO: this is 100% redundant but we need it because CMAKE_LINKER can resolve to ld.lld + # which is NOT compatible + find_program(EMCC NAMES emcc REQUIRED) + set(FFmpeg_LD ${EMCC}) + endif() find_program(AUTOCONF autoconf) if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND") @@ -243,7 +271,13 @@ else() CACHE PATH "Paths to FFmpeg libraries" FORCE) endforeach() - find_program(BASH_PROGRAM bash REQUIRED) + # Some SDKs (especially wasm) require us, actually, WANT us to use their "emconfigure" + # otherwise they will cry a billion tears + if (PLATFORM_EMSCRIPTEN) + find_program(FFmpeg_CONFIGURE_WRAPPER emconfigure REQUIRED) + else() + find_program(FFmpeg_CONFIGURE_WRAPPER bash REQUIRED) + endif() # `configure` parameters builds only exactly what yuzu needs from FFmpeg # `--disable-vdpau` is needed to avoid linking issues @@ -253,7 +287,7 @@ else() OUTPUT ${FFmpeg_MAKEFILE} COMMAND - ${BASH_PROGRAM} ${FFmpeg_PREFIX}/configure + ${FFmpeg_CONFIGURE_WRAPPER} ${FFmpeg_PREFIX}/configure --disable-avdevice --disable-avformat --disable-doc @@ -262,6 +296,10 @@ else() --disable-ffprobe --disable-network --disable-swresample + --disable-autodetect + --disable-runtime-cpudetect + --disable-debug + --disable-programs --enable-decoder=h264 --enable-decoder=vp8 --enable-decoder=vp9 @@ -269,7 +307,7 @@ else() --enable-pic --cc=${FFmpeg_CC} --cxx=${FFmpeg_CXX} - --ld=${CMAKE_LINKER} + --ld=${FFmpeg_LD} --extra-cflags=${CMAKE_C_FLAGS} --extra-cxxflags=${CMAKE_CXX_FLAGS} --extra-ldflags=${CMAKE_C_LINK_FLAGS} @@ -285,18 +323,21 @@ else() # Workaround for Ubuntu 18.04's older version of make not being able to call make as a child # with context of the jobserver. Also helps ninja users. - execute_process( - COMMAND - nproc - OUTPUT_VARIABLE - SYSTEM_THREADS) + cmake_host_system_information(RESULT SYSTEM_THREADS QUERY NUMBER_OF_LOGICAL_CORES) set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES}) - # BSD make or Solaris make don't support ffmpeg make-j8 - if (PLATFORM_LINUX OR ANDROID OR APPLE OR WIN32 OR PLATFORM_FREEBSD) + # Can be found as either "gnumake" or "gmake" + find_program(MAKE gnumake) + if (NOT MAKE_FOUND) + find_program(MAKE gmake) + endif() + if (MAKE_FOUND) + # This version of make (GNU's make) supports subprocess threading jobs set(FFmpeg_MAKE_ARGS -j${SYSTEM_THREADS}) else() + # No GNU make implies that this system may be highly non-GNU + find_program(MAKE make required) set(FFmpeg_MAKE_ARGS "") endif() @@ -304,7 +345,7 @@ else() OUTPUT ${FFmpeg_BUILD_LIBRARIES} COMMAND - gmake ${FFmpeg_MAKE_ARGS} + ${MAKE} ${FFmpeg_MAKE_ARGS} WORKING_DIRECTORY ${FFmpeg_BUILD_DIR} ) diff --git a/externals/tz/tz/tz.cpp b/externals/tz/tz/tz.cpp index 3269d9cc1e..e0b19d8fd5 100644 --- a/externals/tz/tz/tz.cpp +++ b/externals/tz/tz/tz.cpp @@ -14,7 +14,9 @@ namespace Tz { namespace { +#ifndef EINVAL #define EINVAL 22 +#endif static Rule gmtmem{}; static Rule* const gmtptr = &gmtmem; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6d526c5eb..2c6ea4231a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -155,23 +155,25 @@ else() $<$:-fno-rtti>) endif() + if (ENABLE_WERROR) + add_compile_options($<$:-Werror>) + endif() add_compile_options( - $<$:-Werror=all> - $<$:-Werror=extra> - $<$:-Werror=missing-declarations> - $<$:-Werror=shadow> - $<$:-Werror=unused> + $<$:-Wall> + $<$:-Wextra> + $<$:-Wmissing-declarations> + $<$:-Wshadow> + $<$:-Wunused> $<$:-Wno-attributes> $<$:-Wno-invalid-offsetof> $<$:-Wno-unused-parameter> $<$:-Wno-missing-field-initializers>) - if (CXX_CLANG OR CXX_ICC OR CXX_APPLE) # Clang, AppleClang, or Intel C++ if (NOT MSVC) add_compile_options( - $<$:-Werror=shadow-uncaptured-local> - $<$:-Werror=implicit-fallthrough> - $<$:-Werror=type-limits>) + $<$:-Wshadow-uncaptured-local> + $<$:-Wimplicit-fallthrough> + $<$:-Wtype-limits>) endif() add_compile_options( $<$:-Wno-braced-scalar-init> @@ -179,7 +181,11 @@ else() $<$:-Wno-nullability-completeness>) endif() - if (ARCHITECTURE_x86_64) + if (ARCHITECTURE_wasm) + # we are evil but fmt is even more evil + add_compile_options( + $<$:-Wno-shorten-64-to-32>) + elseif (ARCHITECTURE_x86_64) add_compile_options($<$:-mcx16>) if (PLATFORM_LINUX OR PLATFORM_FREEBSD) add_compile_options($<$:-mtls-dialect=gnu2>) diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 4d0b130afc..b186edaab4 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -222,7 +222,7 @@ if (MSVC) ) else() target_compile_options(audio_core PRIVATE - $<$:-Werror=conversion> + $<$:-Wconversion> $<$:-Wno-sign-conversion>) endif() diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 7bb4c3aa4a..f61d4106cf 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -220,7 +220,7 @@ endif() if(CXX_CLANG) target_compile_options(common PRIVATE $<$:-fsized-deallocation> - $<$:-Werror=unreachable-code-aggressive>) + $<$:-Wunreachable-code-aggressive>) target_compile_definitions( common PRIVATE @@ -235,7 +235,11 @@ else() target_link_libraries(common PUBLIC Boost::headers) endif() target_link_libraries(common PRIVATE OpenSSL::SSL) -target_link_libraries(common PUBLIC Boost::filesystem Boost::context httplib::httplib nlohmann_json::nlohmann_json) +target_link_libraries(common PUBLIC Boost::filesystem httplib::httplib nlohmann_json::nlohmann_json) +if (NOT PLATFORM_EMSCRIPTEN) + # Emscripten is: "bring your own implementation", boost doesn't add upstream support sadly + target_link_libraries(common PRIVATE Boost::context) +endif() if (lz4_ADDED) target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib) diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp index 69eca732eb..a2912aa524 100644 --- a/src/common/fiber.cpp +++ b/src/common/fiber.cpp @@ -11,7 +11,12 @@ #include "common/fiber.h" #include "common/virtual_buffer.h" +#ifdef __EMSCRIPTEN__ +#include +#include +#else #include +#endif namespace Common { @@ -22,36 +27,103 @@ constexpr size_t DEFAULT_STACK_SIZE = 512 * 4096; #endif constexpr u32 CANARY_VALUE = 0xDEADBEEF; +#ifdef __EMSCRIPTEN__ struct Fiber::FiberImpl { FiberImpl() {} u32 canary_1 = CANARY_VALUE; std::array stack{}; - std::array rewind_stack{}; + std::array astack{}; u32 canary_2 = CANARY_VALUE; - boost::context::detail::fcontext_t context{}; - boost::context::detail::fcontext_t rewind_context{}; + emscripten_fiber_t* context{nullptr}; std::mutex guard; std::function entry_point; - std::function rewind_point; std::shared_ptr previous_fiber; - - u8* stack_limit = nullptr; - u8* rewind_stack_limit = nullptr; bool is_thread_fiber = false; bool released = false; }; -void Fiber::SetRewindPoint(std::function&& rewind_func) { - impl->rewind_point = std::move(rewind_func); +Fiber::Fiber(std::function&& entry_point_func) : impl{std::make_unique()} { + impl->entry_point = std::move(entry_point_func); + emscripten_fiber_init(impl->context, [](void *user_data) -> void { + auto* fiber = static_cast(user_data); + ASSERT(fiber && fiber->impl && fiber->impl->previous_fiber && fiber->impl->previous_fiber->impl); + ASSERT(fiber->impl->canary_1 == CANARY_VALUE); + ASSERT(fiber->impl->canary_2 == CANARY_VALUE); + fiber->impl->previous_fiber->impl->context = fiber->impl->context; + fiber->impl->previous_fiber->impl->guard.unlock(); + fiber->impl->previous_fiber.reset(); + fiber->impl->entry_point(); + UNREACHABLE(); + }, impl.get(), impl->stack.data(), impl->stack.size(), impl->astack.data(), impl->astack.size()); } +Fiber::Fiber() : impl{std::make_unique()} {} + +Fiber::~Fiber() { + if (!impl->released) { + // Make sure the Fiber is not being used + const bool locked = impl->guard.try_lock(); + ASSERT(locked && "Destroying a fiber that's still running"); + if (locked) { + impl->guard.unlock(); + } + } +} + +void Fiber::Exit() { + ASSERT(impl->is_thread_fiber && "Exiting non main thread fiber"); + if (impl->is_thread_fiber) { + impl->guard.unlock(); + impl->released = true; + } +} + +void Fiber::YieldTo(std::weak_ptr weak_from, Fiber& to) { + to.impl->guard.lock(); + to.impl->previous_fiber = weak_from.lock(); + emscripten_fiber_swap(to.impl->context, to.impl->previous_fiber->impl->context); + // "from" might no longer be valid if the thread was killed + if (auto from = weak_from.lock()) { + if (from->impl->previous_fiber == nullptr) { + ASSERT(false && "previous_fiber is nullptr!"); + } else { + from->impl->previous_fiber->impl->guard.unlock(); + from->impl->previous_fiber.reset(); + } + } +} + +std::shared_ptr Fiber::ThreadToFiber() { + std::shared_ptr fiber = std::shared_ptr{new Fiber()}; + fiber->impl->guard.lock(); + fiber->impl->is_thread_fiber = true; + return fiber; +} +#else +struct Fiber::FiberImpl { + FiberImpl() {} + + u32 canary_1 = CANARY_VALUE; + std::array stack{}; + u32 canary_2 = CANARY_VALUE; + + boost::context::detail::fcontext_t context{}; + + std::mutex guard; + std::function entry_point; + std::shared_ptr previous_fiber; + + u8* stack_limit = nullptr; + bool is_thread_fiber = false; + bool released = false; +}; + Fiber::Fiber(std::function&& entry_point_func) : impl{std::make_unique()} { impl->entry_point = std::move(entry_point_func); impl->stack_limit = impl->stack.data(); - impl->rewind_stack_limit = impl->rewind_stack.data(); u8* stack_base = impl->stack_limit + DEFAULT_STACK_SIZE; impl->context = boost::context::detail::make_fcontext(stack_base, impl->stack.size(), [](boost::context::detail::transfer_t transfer) -> void { auto* fiber = static_cast(transfer.data); @@ -72,7 +144,7 @@ Fiber::~Fiber() { if (!impl->released) { // Make sure the Fiber is not being used const bool locked = impl->guard.try_lock(); - ASSERT_MSG(locked, "Destroying a fiber that's still running"); + ASSERT(locked && "Destroying a fiber that's still running"); if (locked) { impl->guard.unlock(); } @@ -80,7 +152,7 @@ Fiber::~Fiber() { } void Fiber::Exit() { - ASSERT_MSG(impl->is_thread_fiber, "Exiting non main thread fiber"); + ASSERT(impl->is_thread_fiber && "Exiting non main thread fiber"); if (impl->is_thread_fiber) { impl->guard.unlock(); impl->released = true; @@ -110,5 +182,6 @@ std::shared_ptr Fiber::ThreadToFiber() { fiber->impl->is_thread_fiber = true; return fiber; } +#endif } // namespace Common diff --git a/src/common/fiber.h b/src/common/fiber.h index eb128f4bb2..fcaac1d5b8 100644 --- a/src/common/fiber.h +++ b/src/common/fiber.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project @@ -45,7 +45,6 @@ public: /// Fiber 'from' must be the currently running fiber. static void YieldTo(std::weak_ptr weak_from, Fiber& to); [[nodiscard]] static std::shared_ptr ThreadToFiber(); - void SetRewindPoint(std::function&& rewind_func); /// Only call from main thread's fiber void Exit(); private: diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 16806ff0c0..8f1455cb8f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -38,10 +38,6 @@ add_library(core STATIC debugger/debugger.cpp debugger/debugger.h debugger/debugger_interface.h - debugger/gdbstub.cpp - debugger/gdbstub.h - debugger/gdbstub_arch.cpp - debugger/gdbstub_arch.h device_memory.cpp device_memory.h device_memory_manager.h @@ -1170,6 +1166,14 @@ add_library(core STATIC tools/freezer.h tools/renderdoc.cpp tools/renderdoc.h) +if (NOT PLATFORM_EMSCRIPTEN) + # incompatible with wasm's async model + target_sources(core PRIVATE + debugger/gdbstub.cpp + debugger/gdbstub.h + debugger/gdbstub_arch.cpp + debugger/gdbstub_arch.h) +endif() if (ENABLE_WIFI_SCAN) target_sources(core PRIVATE internal_network/wifi_scanner.cpp) @@ -1199,7 +1203,7 @@ if (MSVC) ) else() target_compile_options(core PRIVATE - $<$:-Werror=conversion> + $<$:-Wconversion> $<$:-Wno-sign-conversion> $<$:-Wno-cast-function-type> $<$:-fsized-deallocation>) @@ -1213,7 +1217,10 @@ target_include_directories(core PRIVATE ${OPUS_INCLUDE_DIRS}) target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz) if (BOOST_NO_HEADERS) - target_link_libraries(core PUBLIC Boost::container Boost::heap Boost::asio Boost::process Boost::crc) + target_link_libraries(core PUBLIC Boost::container Boost::heap Boost::crc) + if (NOT PLATFORM_EMSCRIPTEN) + target_link_libraries(core PRIVATE Boost::asio Boost::process) + endif() else() target_link_libraries(core PUBLIC Boost::headers) endif() diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 8e6b1d9766..c8dbf93871 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -6,19 +6,20 @@ #pragma once +#ifndef __EMSCRIPTEN__ #include - +#endif #include "core/arm/arm_interface.h" namespace Core { +#ifndef __EMSCRIPTEN__ constexpr Dynarmic::HaltReason StepThread = Dynarmic::HaltReason::Step; constexpr Dynarmic::HaltReason DataAbort = Dynarmic::HaltReason::MemoryAbort; constexpr Dynarmic::HaltReason BreakLoop = Dynarmic::HaltReason::UserDefined2; constexpr Dynarmic::HaltReason SupervisorCall = Dynarmic::HaltReason::UserDefined3; constexpr Dynarmic::HaltReason InstructionBreakpoint = Dynarmic::HaltReason::UserDefined4; constexpr Dynarmic::HaltReason PrefetchAbort = Dynarmic::HaltReason::UserDefined6; - constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) { static_assert(u64(HaltReason::StepThread) == u64(StepThread)); static_assert(u64(HaltReason::DataAbort) == u64(DataAbort)); @@ -28,5 +29,6 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) { static_assert(u64(HaltReason::PrefetchAbort) == u64(PrefetchAbort)); return HaltReason(hr); } +#endif } // namespace Core diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index d1c767721b..962b60098d 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -6,30 +6,52 @@ #include #include + +#ifdef __EMSCRIPTEN__ +// TODO: gdb stub compat with emscripten? +#else #include #include - #if BOOST_VERSION > 108400 && (!defined(_WINDOWS) && !defined(__ANDROID__)) || defined(YUZU_BOOST_v1) #define USE_BOOST_v1 #endif - #ifdef USE_BOOST_v1 #include #else #include #endif +#endif #include "common/logging.h" #include "common/polyfill_thread.h" #include "common/thread.h" #include "core/core.h" #include "core/debugger/debugger.h" +#ifndef __EMSCRIPTEN__ #include "core/debugger/debugger_interface.h" #include "core/debugger/gdbstub.h" +#endif #include "core/hle/kernel/global_scheduler_context.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" +#ifdef __EMSCRIPTEN__ +namespace Core { +// Dummy +struct DebuggerImpl { + char pad; +}; +Debugger::Debugger(Core::System& system, u16 port) {} +Debugger::~Debugger() = default; +bool Debugger::NotifyThreadStopped(Kernel::KThread* thread) { + return false; +} +bool Debugger::NotifyThreadWatchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& watch) { + return false; +} +void Debugger::NotifyShutdown() {} +} // namespace Core +#else template static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) { static_assert(std::is_trivial_v); @@ -400,3 +422,4 @@ void Debugger::NotifyShutdown() { } } // namespace Core +#endif diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 7308b0ff87..c1b4a7b794 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -7,8 +7,14 @@ #include #include "common/scope_exit.h" #include "common/settings.h" + +#include "core/arm/exclusive_monitor.h" +#ifndef __EMSCRIPTEN__ #include "core/arm/dynarmic/arm_dynarmic.h" #include "core/arm/dynarmic/dynarmic_exclusive_monitor.h" +#include "core/arm/dynarmic/arm_dynarmic_32.h" +#include "core/arm/dynarmic/arm_dynarmic_64.h" +#endif #include "core/core.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scoped_resource_reservation.h" @@ -18,8 +24,6 @@ #include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/k_worker_task_manager.h" -#include "core/arm/dynarmic/arm_dynarmic_32.h" -#include "core/arm/dynarmic/arm_dynarmic_64.h" #ifdef HAS_NCE #include "core/arm/nce/arm_nce.h" #endif @@ -1300,9 +1304,11 @@ void KProcess::LoadModule(KernelCore& kernel, CodeSet code_set, KProcessAddress } void KProcess::InitializeInterfaces(KernelCore& kernel) { +#ifdef __EMSCRIPTEN__ + ASSERT(false && "unimplemented"); +#else m_exclusive_monitor = Core::MakeExclusiveMonitor(this->GetMemory(), Core::Hardware::NUM_CPU_CORES); - #ifdef HAS_NCE if (this->IsApplication() && Settings::IsNceEnabled()) { for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) @@ -1322,6 +1328,7 @@ void KProcess::InitializeInterfaces(KernelCore& kernel) { static_cast(*m_exclusive_monitor), i); } } +#endif } bool KProcess::InsertWatchpoint(KernelCore& kernel, KProcessAddress addr, u64 size, DebugWatchpointType type) { diff --git a/src/hid_core/CMakeLists.txt b/src/hid_core/CMakeLists.txt index c740cdbe7f..e617160834 100644 --- a/src/hid_core/CMakeLists.txt +++ b/src/hid_core/CMakeLists.txt @@ -151,7 +151,7 @@ if (MSVC) ) else() target_compile_options(hid_core PRIVATE - $<$:-Werror=conversion> + $<$:-Wconversion> $<$:-Wno-sign-conversion> $<$:-Wno-cast-function-type> $<$:-fsized-deallocation>) diff --git a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h index 44be82cd43..8df5c30150 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h @@ -28,7 +28,10 @@ enum class NpadMcuState : u32 { struct NpadMcuHolder { NpadMcuState state; INSERT_PADDING_BYTES(0x4); - IAbstractedPad* abstracted_pad; + union { + IAbstractedPad* abstracted_pad; + u64 abstracted_pad_raw; + }; }; static_assert(sizeof(NpadMcuHolder) == 0x10, "NpadMcuHolder is an invalid size"); diff --git a/src/hid_core/resources/shared_memory_holder.h b/src/hid_core/resources/shared_memory_holder.h index 5fcaddecc0..26d5867463 100644 --- a/src/hid_core/resources/shared_memory_holder.h +++ b/src/hid_core/resources/shared_memory_holder.h @@ -33,9 +33,15 @@ public: bool is_created{}; bool is_mapped{}; INSERT_PADDING_BYTES(0x5); - Kernel::KSharedMemory* shared_memory; + union { + Kernel::KSharedMemory* shared_memory = nullptr; + u64 shared_memory_raw; + }; INSERT_PADDING_BYTES(0x38); - SharedMemoryFormat* address = nullptr; + union { + SharedMemoryFormat* address = nullptr; + u64 address_raw; + }; }; // Correct size is 0x50 bytes static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size"); diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 91dd8558ab..01cf6a52f2 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -15,8 +15,6 @@ add_library(input_common STATIC drivers/tas_input.h drivers/touch_screen.cpp drivers/touch_screen.h - drivers/udp_client.cpp - drivers/udp_client.h drivers/virtual_amiibo.cpp drivers/virtual_amiibo.h drivers/virtual_gamepad.cpp @@ -34,8 +32,12 @@ add_library(input_common STATIC input_poller.cpp input_poller.h main.cpp - main.h -) + main.h) +if (NOT PLATFORM_EMSCRIPTEN) + target_sources(input_common PRIVATE + drivers/udp_client.cpp + drivers/udp_client.h) +endif() if (MSVC) target_compile_options(input_common PRIVATE @@ -44,7 +46,7 @@ if (MSVC) /we4800 # Implicit conversion from 'type' to bool. Possible information loss ) else() - target_compile_options(input_common PRIVATE $<$:-Werror=conversion>) + target_compile_options(input_common PRIVATE $<$:-Wconversion>) endif() if (ANDROID) diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index 6c8443ff62..c643400e70 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp @@ -12,7 +12,6 @@ #include "input_common/drivers/mouse.h" #include "input_common/drivers/tas_input.h" #include "input_common/drivers/touch_screen.h" -#include "input_common/drivers/udp_client.h" #include "input_common/drivers/virtual_amiibo.h" #include "input_common/drivers/virtual_gamepad.h" #include "input_common/helpers/stick_from_buttons.h" @@ -21,6 +20,9 @@ #include "input_common/input_mapping.h" #include "input_common/input_poller.h" #include "input_common/main.h" +#ifndef __EMSCRIPTEN__ +#include "input_common/drivers/udp_client.h" +#endif #ifdef ENABLE_LIBUSB #include "input_common/drivers/gc_adapter.h" @@ -82,7 +84,9 @@ struct InputSubsystem::Impl { #ifdef ENABLE_LIBUSB RegisterEngine("gcpad", gcadapter); #endif +#ifndef __EMSCRIPTEN__ RegisterEngine("cemuhookudp", udp_client); +#endif RegisterEngine("tas", tas_input); RegisterEngine("camera", camera); #ifdef __ANDROID__ @@ -116,7 +120,9 @@ struct InputSubsystem::Impl { #ifdef ENABLE_LIBUSB UnregisterEngine(gcadapter); #endif +#ifndef __EMSCRIPTEN__ UnregisterEngine(udp_client); +#endif UnregisterEngine(tas_input); UnregisterEngine(camera); #ifdef __ANDROID__ @@ -152,8 +158,10 @@ struct InputSubsystem::Impl { auto gcadapter_devices = gcadapter->GetInputDevices(); devices.insert(devices.end(), gcadapter_devices.begin(), gcadapter_devices.end()); #endif +#ifndef __EMSCRIPTEN__ auto udp_devices = udp_client->GetInputDevices(); devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); +#endif #ifdef HAVE_SDL3 auto joycon_devices = joycon->GetInputDevices(); devices.insert(devices.end(), joycon_devices.begin(), joycon_devices.end()); @@ -186,9 +194,11 @@ struct InputSubsystem::Impl { return gcadapter; } #endif +#ifndef __EMSCRIPTEN__ if (engine == udp_client->GetEngineName()) { return udp_client; } +#endif #ifdef HAVE_SDL3 if (engine == sdl->GetEngineName()) { return sdl; @@ -271,9 +281,11 @@ struct InputSubsystem::Impl { return true; } #endif +#ifndef __EMSCRIPTEN__ if (engine == udp_client->GetEngineName()) { return true; } +#endif if (engine == tas_input->GetEngineName()) { return true; } @@ -300,7 +312,9 @@ struct InputSubsystem::Impl { #ifdef ENABLE_LIBUSB gcadapter->BeginConfiguration(); #endif +#ifndef __EMSCRIPTEN__ udp_client->BeginConfiguration(); +#endif #ifdef HAVE_SDL3 sdl->BeginConfiguration(); joycon->BeginConfiguration(); @@ -316,7 +330,9 @@ struct InputSubsystem::Impl { #ifdef ENABLE_LIBUSB gcadapter->EndConfiguration(); #endif +#ifndef __EMSCRIPTEN__ udp_client->EndConfiguration(); +#endif #ifdef HAVE_SDL3 sdl->EndConfiguration(); joycon->EndConfiguration(); @@ -341,7 +357,9 @@ struct InputSubsystem::Impl { std::shared_ptr mouse; std::shared_ptr touch_screen; std::shared_ptr tas_input; +#ifndef __EMSCRIPTEN__ std::shared_ptr udp_client; +#endif std::shared_ptr camera; std::shared_ptr virtual_amiibo; std::shared_ptr virtual_gamepad; @@ -470,7 +488,9 @@ bool InputSubsystem::IsStickInverted(const Common::ParamPackage& params) const { } void InputSubsystem::ReloadInputDevices() { +#ifndef __EMSCRIPTEN__ impl->udp_client.get()->ReloadSockets(); +#endif } void InputSubsystem::BeginMapping(Polling::InputType type) { diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index d02ee268f0..7591aeffd8 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt @@ -253,12 +253,11 @@ if (MSVC) ) else() target_compile_options(shader_recompiler PRIVATE - $<$:-Werror=conversion> + $<$:-Wconversion> # Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6. # And this in turns limits the size of a std::array. $<$:-fbracket-depth=1024> - $<$:-fbracket-depth=1024> - ) + $<$:-fbracket-depth=1024>) endif() create_target_directory_groups(shader_recompiler) diff --git a/src/shader_recompiler/environment.h b/src/shader_recompiler/environment.h index 0a6e4bfcaa..f32004a11e 100644 --- a/src/shader_recompiler/environment.h +++ b/src/shader_recompiler/environment.h @@ -31,7 +31,7 @@ struct CbufWordKey { struct CbufWordKeyHash { constexpr size_t operator()(const CbufWordKey& k) const noexcept { - return (size_t(k.index) << 32) ^ k.offset; + return size_t((u64(k.index) << 32) ^ u64(k.offset)); } }; @@ -46,12 +46,12 @@ struct HandleKey { }; struct HandleKeyHash { constexpr size_t operator()(const HandleKey& k) const noexcept { - size_t h = (size_t(k.index) << 32) ^ k.offset; - h ^= (size_t(k.shift_left) << 1); - h ^= (size_t(k.sec_index) << 33) ^ (size_t(k.sec_offset) << 2); - h ^= (size_t(k.sec_shift_left) << 3); + u64 h = (u64(k.index) << 32) ^ k.offset; + h ^= (u64(k.shift_left) << 1); + h ^= (u64(k.sec_index) << 33) ^ (u64(k.sec_offset) << 2); + h ^= (u64(k.sec_shift_left) << 3); h ^= k.has_secondary ? 0x9e3779b97f4a7c15ULL : 0ULL; - return h; + return size_t(h); } }; diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp index 50e618c2f1..d74eb6d46b 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_fetch_swizzled.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -157,16 +160,14 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) { unsigned Swizzle(u64 insn) { const Encoding texs{insn}; - const size_t encoding{texs.swizzle}; + u8 const encoding = u8(texs.swizzle); if (texs.dest_reg_b == IR::Reg::RZ) { - if (encoding >= RG_LUT.size()) { + if (encoding >= RG_LUT.size()) throw NotImplementedException("Illegal RG encoding {}", encoding); - } return RG_LUT[encoding]; } else { - if (encoding >= RGBA_LUT.size()) { + if (encoding >= RGBA_LUT.size()) throw NotImplementedException("Illegal RGBA encoding {}", encoding); - } return RGBA_LUT[encoding]; } } diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp index 0362f076af..1b5313711e 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -142,16 +145,14 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) { unsigned Swizzle(u64 insn) { const Encoding tlds{insn}; - const size_t encoding{tlds.swizzle}; + u8 const encoding = u8(tlds.swizzle); if (tlds.dest_reg_b == IR::Reg::RZ) { - if (encoding >= RG_LUT.size()) { + if (encoding >= RG_LUT.size()) throw NotImplementedException("Illegal RG encoding {}", encoding); - } return RG_LUT[encoding]; } else { - if (encoding >= RGBA_LUT.size()) { + if (encoding >= RGBA_LUT.size()) throw NotImplementedException("Illegal RGBA encoding {}", encoding); - } return RGBA_LUT[encoding]; } } diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 5c02b5ed90..f5186f6648 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -371,7 +371,7 @@ else() $<$:-Wno-shadow> $<$:-Wno-unused-local-typedef>) else() - target_compile_options(video_core PRIVATE $<$:-Werror=conversion>) + target_compile_options(video_core PRIVATE $<$:-Wconversion>) endif() target_compile_options(video_core PRIVATE $<$:-Wno-sign-conversion>)