diff --git a/.ci/linux/build.sh b/.ci/linux/build.sh index 093b30a7ea..a92cb3fd91 100755 --- a/.ci/linux/build.sh +++ b/.ci/linux/build.sh @@ -3,7 +3,6 @@ # SPDX-FileCopyrightText: 2025 eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later -export ARCH="$(uname -m)" case "$1" in amd64|"") @@ -11,15 +10,15 @@ case "$1" in ARCH="amd64_v3" ARCH_FLAGS="-march=x86-64-v3" ;; - steamdeck) + steamdeck|zen2) echo "Making Steam Deck (Zen 2) optimized build of Eden" ARCH="steamdeck" ARCH_FLAGS="-march=znver2 -mtune=znver2" ;; - rog-ally|allyx) + rog-ally|allyx|zen4) echo "Making ROG Ally X (Zen 4) optimized build of Eden" ARCH="rog-ally-x" - ARCH_FLAGS="-march=znver3 -mtune=znver4" # GH actions runner is a Zen 3 CPU, so a small workaround + ARCH_FLAGS="-march=znver4 -mtune=znver4" ;; legacy) echo "Making amd64 generic build of Eden" @@ -36,8 +35,13 @@ case "$1" in ARCH=armv9 ARCH_FLAGS="-march=armv9-a -mtune=generic -w" ;; + native) + echo "Making native build of Eden" + ARCH="$(uname -m)" + ARCH_FLAGS="-march=native -mtune=native" + ;; *) - echo "Invalid target $1 specified, must be one of amd64, steamdeck, allyx, rog-ally, legacy, aarch64, armv9" + echo "Invalid target $1 specified, must be one of native, amd64, steamdeck, zen2, allyx, rog-ally, zen4, legacy, aarch64, armv9" exit 1 ;; esac diff --git a/.ci/linux/package.sh b/.ci/linux/package.sh index 21fd72cb08..41e07ea207 100755 --- a/.ci/linux/package.sh +++ b/.ci/linux/package.sh @@ -16,11 +16,11 @@ case "$1" in echo "Packaging amd64-v3 optimized build of Eden" ARCH="amd64_v3" ;; - steamdeck) + steamdeck|zen2) echo "Packaging Steam Deck (Zen 2) optimized build of Eden" ARCH="steamdeck" ;; - rog-ally|allyx) + rog-ally|allyx|zen4) echo "Packaging ROG Ally X (Zen 4) optimized build of Eden" ARCH="rog-ally-x" ;; @@ -36,6 +36,11 @@ case "$1" in echo "Packaging armv9-a build of Eden" ARCH=armv9 ;; + native) + echo "Packaging native build of Eden" + ARCH="$BASE_ARCH" + ;; + esac export BUILDDIR="$2" diff --git a/.ci/patch/0001-quazip-strict.patch b/.ci/patch/0001-quazip-strict.patch deleted file mode 100644 index 8283497230..0000000000 --- a/.ci/patch/0001-quazip-strict.patch +++ /dev/null @@ -1,80 +0,0 @@ -diff --git a/quazip/quazipdir.cpp b/quazip/quazipdir.cpp -index d43f1c1..eb24bf1 100644 ---- a/quazip/quazipdir.cpp -+++ b/quazip/quazipdir.cpp -@@ -293,8 +293,8 @@ bool QuaZipDirComparator::operator()(const QuaZipFileInfo64 &info1, - } - - template --bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters, -- QDir::Filters filter, QDir::SortFlags sort, TFileInfoList &result) const -+bool QuaZipDirPrivate::entryInfoList(QStringList _nameFilters, -+ QDir::Filters _filter, QDir::SortFlags sort, TFileInfoList &result) const - { - QString basePath = simplePath(); - if (!basePath.isEmpty()) -@@ -305,12 +305,12 @@ bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters, - if (!zip->goToFirstFile()) { - return zip->getZipError() == UNZ_OK; - } -- QDir::Filters fltr = filter; -+ QDir::Filters fltr = _filter; - if (fltr == QDir::NoFilter) - fltr = this->filter; - if (fltr == QDir::NoFilter) - fltr = QDir::AllEntries; -- QStringList nmfltr = nameFilters; -+ QStringList nmfltr = _nameFilters; - if (nmfltr.isEmpty()) - nmfltr = this->nameFilters; - QSet dirsFound; -diff --git a/quazip/quazipfile.cpp b/quazip/quazipfile.cpp -index 4a5f2f9..f7865f5 100644 ---- a/quazip/quazipfile.cpp -+++ b/quazip/quazipfile.cpp -@@ -241,14 +241,14 @@ void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs - p->caseSensitivity=cs; - } - --void QuaZipFilePrivate::setZipError(int zipError) const -+void QuaZipFilePrivate::setZipError(int _zipError) const - { - QuaZipFilePrivate *fakeThis = const_cast(this); // non-const -- fakeThis->zipError=zipError; -- if(zipError==UNZ_OK) -+ fakeThis->zipError = _zipError; -+ if(_zipError == UNZ_OK) - q->setErrorString(QString()); - else -- q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError)); -+ q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(_zipError)); - } - - bool QuaZipFile::open(OpenMode mode) -diff --git a/quazip/unzip.c b/quazip/unzip.c -index a39365d..ee7b487 100644 ---- a/quazip/unzip.c -+++ b/quazip/unzip.c -@@ -1054,7 +1054,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, - /* ZIP64 extra fields */ - if (headerId == 0x0001) - { -- uLong uL; -+ uLong _uL; - - if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu) - { -@@ -1078,7 +1078,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, - if(file_info.disk_num_start == 0xFFFFFFFFu) - { - /* Disk Start Number */ -- if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) -+ if (unz64local_getLong(&s->z_filefunc, s->filestream, &_uL) != UNZ_OK) - err=UNZ_ERRNO; - } - -@@ -2151,3 +2151,4 @@ int ZEXPORT unzClearFlags(unzFile file, unsigned flags) - s->flags &= ~flags; - return UNZ_OK; - } -+ diff --git a/.ci/patch/0002-quazip-fetchcontent.patch b/.ci/patch/0002-quazip-fetchcontent.patch deleted file mode 100644 index 3554b7dbb6..0000000000 --- a/.ci/patch/0002-quazip-fetchcontent.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/cmake/clone-repo.cmake b/cmake/clone-repo.cmake -index 2ffb4b2..77974dc 100644 ---- a/cmake/clone-repo.cmake -+++ b/cmake/clone-repo.cmake -@@ -26,7 +26,7 @@ macro(clone_repo name url) - FetchContent_GetProperties(${name} POPULATED ${name_lower}_POPULATED) - - if(NOT ${name_lower}_POPULATED) -- FetchContent_Populate(${name}) -+ FetchContent_MakeAvailable(${name}) - endif() - - set(${name_upper}_SOURCE_DIR ${${name_lower}_SOURCE_DIR}) diff --git a/.ci/windows/cygwin.bat b/.ci/windows/cygwin.bat deleted file mode 100755 index e772780fac..0000000000 --- a/.ci/windows/cygwin.bat +++ /dev/null @@ -1,19 +0,0 @@ -echo off - -call C:\tools\cygwin\cygwinsetup.exe -q -P autoconf,automake,libtool,make,pkg-config - -REM Create wrapper batch files for Cygwin tools in a directory that will be in PATH -REM uncomment this for first-run only -REM call mkdir C:\cygwin-wrappers - -REM Create autoconf.bat wrapper -call echo @echo off > C:\cygwin-wrappers\autoconf.bat -call echo C:\tools\cygwin\bin\bash.exe -l -c "autoconf %%*" >> C:\cygwin-wrappers\autoconf.bat - -REM Add other wrappers if needed for other Cygwin tools -call echo @echo off > C:\cygwin-wrappers\automake.bat -call echo C:\tools\cygwin\bin\bash.exe -l -c "automake %%*" >> C:\cygwin-wrappers\automake.bat - -REM Add the wrappers directory to PATH -call echo C:\cygwin-wrappers>>"%GITHUB_PATH%" -call echo C:\tools\cygwin\bin>>"%GITHUB_PATH%" diff --git a/.ci/windows/install-vulkan-sdk.ps1 b/.ci/windows/install-vulkan-sdk.ps1 index de218d90ad..ca8c64b5cd 100755 --- a/.ci/windows/install-vulkan-sdk.ps1 +++ b/.ci/windows/install-vulkan-sdk.ps1 @@ -3,7 +3,7 @@ $ErrorActionPreference = "Stop" -$VulkanSDKVer = "1.3.250.1" +$VulkanSDKVer = "1.4.321.1" $ExeFile = "VulkanSDK-$VulkanSDKVer-Installer.exe" $Uri = "https://sdk.lunarg.com/sdk/download/$VulkanSDKVer/windows/$ExeFile" $Destination = "./$ExeFile" diff --git a/.ci/windows/qt-envvars.sh b/.ci/windows/qt-envvars.sh deleted file mode 100755 index ec314b863f..0000000000 --- a/.ci/windows/qt-envvars.sh +++ /dev/null @@ -1,7 +0,0 @@ -# This is specific to the CI runner and is unlikely to work on your machine. -QTDIR="/c/Qt/6.9.0/msvc2022_64" - -export QT_ROOT_DIR="$QTDIR" -export QT_PLUGIN_PATH="$QTDIR/plugins" -export QML2_IMPORT_PATH="$QTDIR/qml" -export PATH="${PATH};$QTDIR/bin" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4417d3f132..83881117ac 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # Build directory -[Bb]uild*/ +/[Bb]uild*/ doc-build/ AppDir/ uruntime diff --git a/.gitmodules b/.gitmodules index 1a6e6574a3..371b62a605 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://github.com/KhronosGroup/Vulkan-Headers.git [submodule "xbyak"] path = externals/xbyak - url = https://github.com/herumi/xbyak.git + url = https://github.com/Lizzie841/xbyak.git [submodule "opus"] path = externals/opus url = https://github.com/xiph/opus.git @@ -51,7 +51,7 @@ url = https://github.com/Lizzie841/unordered_dense.git [submodule "externals/dynarmic/externals/xbyak"] path = externals/dynarmic/externals/xbyak - url = https://github.com/herumi/xbyak.git + url = https://github.com/Lizzie841/xbyak.git [submodule "externals/dynarmic/externals/zycore-c"] path = externals/dynarmic/externals/zycore-c url = https://github.com/zyantific/zycore-c.git diff --git a/CMakeLists.txt b/CMakeLists.txt index f8e8516dbc..c90e7b2540 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF) CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF) option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) +option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF) if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" OFF) @@ -60,7 +61,7 @@ endif() if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" OFF) else() - option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON) + option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON) endif() if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") @@ -120,7 +121,7 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead of the bundled one)" OFF "APPLE" OFF) set(DEFAULT_ENABLE_OPENSSL ON) -if (ANDROID OR WIN32 OR APPLE) +if (ANDROID OR WIN32 OR APPLE OR ${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") set(DEFAULT_ENABLE_OPENSSL OFF) endif() option(ENABLE_OPENSSL "Enable OpenSSL backend for ISslConnection" ${DEFAULT_ENABLE_OPENSSL}) @@ -416,6 +417,10 @@ if (UNIX AND NOT APPLE) find_package(gamemode 1.7 MODULE) endif() +if (ENABLE_QT) + find_package(libzip CONFIG REQUIRED) +endif() + # find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package if (ENABLE_SDL2) if (YUZU_USE_BUNDLED_SDL2) @@ -458,19 +463,22 @@ if (ENABLE_QT) if (YUZU_USE_BUNDLED_QT) download_qt(6.8.3) else() - message(STATUS "Using system Qt") if (NOT Qt6_DIR) set(Qt6_DIR "" CACHE PATH "Additional path to search for Qt6 libraries like C:/Qt/6.8.3/msvc2022_64/lib/cmake/Qt6") endif() list(APPEND CMAKE_PREFIX_PATH "${Qt6_DIR}") endif() + find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent) + + if (Qt6_FOUND) + message(STATUS "Found Qt6: ${Qt6_DIR}") + endif() + # QT6 Multimedia pulls in unneeded audio systems (ALSA, Pulseaudio) for FreeBSD # ALSA is the default sound system on Linux, but FreeBSD uses OSS which works well enough - if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") - find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent) - else() - find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent) + if (YUZU_USE_QT_MULTIMEDIA) + find_package(Qt6 REQUIRED COMPONENTS Multimedia) endif() if (UNIX AND NOT APPLE) diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index a82d1d72a3..996cb41cce 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -91,11 +91,11 @@ function(determine_qt_parameters target host_out type_out arch_out arch_path_out set(type "desktop") set(arch "clang_64") set(arch_path "macos") - else() + elseif (LINUX) set(host "linux") set(type "desktop") - set(arch "gcc_64") - set(arch_path "linux") + set(arch "linux_gcc_64") + set(arch_path "gcc_64") endif() set(${host_out} "${host}" PARENT_SCOPE) @@ -129,16 +129,29 @@ function(download_qt_configuration prefix_out target host type arch arch_path ba set(install_args -c "${CURRENT_MODULE_DIR}/aqt_config.ini") if (tool) - set(prefix "${base_path}/Tools") + set(prefix "${base_path}/tools") set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target}) else() set(prefix "${base_path}/${target}/${arch_path}") - set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} -m qt3d qt5compat qtactiveqt qtcharts qtconnectivity qtdatavis3d qtgraphs qtgrpc qthttpserver qtimageformats qtlanguageserver qtlocation qtlottie qtmultimedia qtnetworkauth qtpdf qtpositioning qtquick3d qtquick3dphysics qtquickeffectmaker qtquicktimeline qtremoteobjects qtscxml qtsensors qtserialbus qtserialport qtshadertools qtspeech qtvirtualkeyboard qtwebchannel qtwebengine qtwebsockets qtwebview) + set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} -m qt_base) + + if (YUZU_USE_QT_MULTIMEDIA) + set(install_args ${install_args} qtmultimedia) + endif() + + if (YUZU_USE_QT_WEB_ENGINE) + set(install_args ${install_args} qtpositioning qtwebchannel qtwebengine) + endif() + + if (NOT ${YUZU_QT_MIRROR} STREQUAL "") + message(STATUS "Using Qt mirror ${YUZU_QT_MIRROR}") + set(install_args ${install_args} -b ${YUZU_QT_MIRROR}) + endif() endif() if (NOT EXISTS "${prefix}") message(STATUS "Downloading Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path}") - set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.2.1") + set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.3.0") if (WIN32) set(aqt_path "${base_path}/aqt.exe") if (NOT EXISTS "${aqt_path}") @@ -158,14 +171,28 @@ function(download_qt_configuration prefix_out target host type arch arch_path ba execute_process(COMMAND chmod +x ${aqt_path}) execute_process(COMMAND ${aqt_path} ${install_args} WORKING_DIRECTORY ${base_path}) - else() + elseif (LINUX) set(aqt_install_path "${base_path}/aqt") file(MAKE_DIRECTORY "${aqt_install_path}") - execute_process(COMMAND python3 -m pip install --target=${aqt_install_path} aqtinstall - WORKING_DIRECTORY ${base_path}) - execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args} - WORKING_DIRECTORY ${base_path}) + find_package(Python3 COMPONENTS Interpreter) + execute_process( + COMMAND ${Python3_EXECUTABLE} -m venv .venv + WORKING_DIRECTORY ${base_path} + ) + set(ENV{VIRTUAL_ENV} "${base_path}/.venv") + set(Python3_FIND_VIRTUALENV FIRST) + unset(Python3_EXECUTABLE) + find_package(Python3 COMPONENTS Interpreter) + + execute_process( + COMMAND ${Python3_EXECUTABLE} -m pip install aqtinstall + WORKING_DIRECTORY ${base_path} + ) + execute_process( + COMMAND ${Python3_EXECUTABLE} -m aqt ${install_args} + WORKING_DIRECTORY ${base_path} + ) endif() message(STATUS "Downloaded Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path} to ${prefix}") diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000000..f25ebc6fd3 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,32 @@ +{ + "version": 2, + "configurePresets": [ + { + "name": "linux-amd64", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "environment": { + "CMAKE_C_COMPILER_LAUNCHER": "$env{CCACHE}", + "CMAKE_CXX_COMPILER_LAUNCHER": "$env{CCACHE}" + }, + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", + "YUZU_USE_BUNDLED_VCPKG": "OFF", + "YUZU_USE_BUNDLED_QT": "ON", + "YUZU_TESTS": "OFF", + "YUZU_CHECK_SUBMODULES": "OFF", + "YUZU_USE_FASTER_LD": "ON", + "YUZU_ENABLE_LTO": "ON", + "ENABLE_QT_TRANSLATION": "ON", + "USE_DISCORD_PRESENCE": "OFF", + "YUZU_CMD": "OFF", + "YUZU_ROOM_STANDALONE": "OFF", + "CMAKE_POLICY_VERSION_MINIMUM": "3.5", + "CMAKE_INSTALL_PREFIX": "/usr", + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CMAKE_EXE_LINKER_FLAGS": "-Wl,--as-needed" + } + } + ] +} diff --git a/README.md b/README.md index 3cf94390fb..ce60e9e18f 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,13 @@


- Eden + Eden
Eden

-

Eden is the world's most popular open-source Nintendo Switch emulator, forked from the Yuzu emulator — started by former Citron developer Camille LaVey and the Eden team. +

Eden is a open-source Nintendo Switch emulator, forked from the Yuzu emulator — started by former Citron developer Camille LaVey and the Eden team.
It is written in C++ with portability in mind, and we actively maintain builds for Windows, Linux and Android.

@@ -54,13 +54,15 @@ You can also contact any of the developers on Discord to learn more about the cu ## Building -* **Windows**: [Windows Building Guide](https://git.eden-emu.dev/eden-emu/eden/wiki/Building-for-Windows.-) -* **Linux**: [Linux Building Guide](https://git.eden-emu.dev/eden-emu/eden/wiki/Building-for-Linux.-) -* **Android**: [Android Building Guide](https://git.eden-emu.dev/eden-emu/eden/wiki/Building-for-Android.-) +* **Windows**: [Windows Building Guide](./docs/build/Windows.md) +* **Linux**: [Linux Building Guide](./docs/build/Linux.md) +* **Android**: [Android Building Guide](./docs/build/Android.md) +* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md) +* **macOS**: [macOS Building Guide](./docs/build/macOS.md) ## Download -You will be able to download the latest releases from [here](https://github.com/eden-emulator/Releases/releases). +You can download the latest releases from [here](https://github.com/eden-emulator/Releases/releases). ## Support diff --git a/docs/Development.md b/docs/Development.md new file mode 100644 index 0000000000..4f17bf6977 --- /dev/null +++ b/docs/Development.md @@ -0,0 +1,174 @@ +# Development + +* **Windows**: [Windows Building Guide](./docs/build/Windows.md) +* **Linux**: [Linux Building Guide](./docs/build/Linux.md) +* **Android**: [Android Building Guide](./docs/build/Android.md) +* **Solaris**: [Solaris Building Guide](./docs/build/Solaris.md) +* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md) +* **macOS**: [macOS Building Guide](./docs/build/macOS.md) + +# Building speedup + +If you have an HDD, use ramdisk (build in RAM): +```sh +sudo mkdir /tmp/ramdisk +sudo chmod 777 /tmp/ramdisk +# about 10GB needed +sudo mount -t tmpfs -o size=10G myramdisk /tmp/ramdisk +cmake -B /tmp/ramdisk +cmake --build /tmp/ramdisk -- -j32 +sudo umount /tmp/ramdisk +``` + +# How to test JIT + +## gdb + +Run `./build/bin/eden-cli -c -d -g ` + +Then hook up an aarch64-gdb (use `yay aarch64-gdb` or `sudo pkg in arch64-gdb` to install) +Then type `target remote localhost:1234` and type `c` (for continue) - and then if it crashes just do a `bt` (backtrace) and `layout asm`. + +### gdb cheatsheet + +- `mo `: Monitor commands, `get info`, `get fastmem` and `get mappings` are available. +- `detach`: Detach from remote (i.e restarting the emulator). +- `c`: Continue +- `p `: Print variable, `p/x ` for hexadecimal. +- `r`: Run +- `bt`: Print backtrace +- `info threads`: Print all active threads +- `thread `: Switch to the given thread (see `info threads`) +- `layout asm`: Display in assembly mode (TUI) +- `si`: Step assembly instruction +- `s` or `step`: Step over LINE OF CODE (not assembly) +- `display `: Display variable each step. +- `n`: Next (skips over call frame of a function) +- `frame `: Switches to the given frame (from `bt`) +- `br `: Set breakpoint at ``. +- `delete`: Deletes all breakpoints. +- `catch throw`: Breakpoint at throw. Can also use `br __cxa_throw` + +Expressions can be `variable_names` or `1234` (numbers) or `*var` (dereference of a pointer) or `*(1 + var)` (computed expression). + +For more information type `info gdb` and read [the man page](https://man7.org/linux/man-pages/man1/gdb.1.html). + +## Bisecting older commits + +Since going into the past can be tricky (especially due to the dependencies from the project being lost thru time). This should "restore" the URLs for the respective submodules. + +```sh +#!/bin/sh +cat > .gitmodules < externals/dynarmic/src/dynarmic/common/x64_disassemble.cpp < +#include +#include +namespace Dynarmic::Common { +void DumpDisassembledX64(const void* ptr, size_t size) {} +std::vector DisassembleX64(const void* ptr, size_t size) { return {}; } +} +EOF +``` + +If having issues with older artifacts, then run `rm -r externals/dynarmic/build externals/dynarmic/externals externals/nx_tzdb/tzdb_to_nx/externals externals/sirit/externals`. + +Configuring CMake with `-DSIRIT_USE_SYSTEM_SPIRV_HEADERS=1 -DCMAKE_CXX_FLAGS="-Wno-error" -DCMAKE_C_FLAGS="-Wno-error -Wno-array-parameter -Wno-stringop-overflow"` is also recommended. + diff --git a/docs/Solaris.md b/docs/Solaris.md new file mode 100644 index 0000000000..c7daa2279b --- /dev/null +++ b/docs/Solaris.md @@ -0,0 +1,94 @@ +# Building for Solaris + +## Dependencies. +Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability. + +Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`. + +- **gcc**: `sudo pkg install developer/gcc-14`. +- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. + +Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm`. + +fmtlib is not available on repositories and has to be manually built: +```sh +git clone --recurisve --depth=1 https://github.com/fmtlib/fmt.git +cd fmt +cmake -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +sudo cmake --install build +``` + +pkg lz4 doesn't provide a proper CMakeFile to find the library, has to also be manually built: +```sh +git clone --depth=1 https://github.com/lz4/lz4.git +cd lz4 +gmake +sudo gmake install +``` + +Same goes for zstd: +```sh +git clone --depth=1 https://github.com/facebook/zstd.git +cd zstd +cmake -DCMAKE_BUILD_TYPE=Release -B build0 -S build/cmake +cmake --build build0 +cd build0 +sudo gmake install +``` + +pkg SDL2 is also not nice to work with on CMake, save yourself some pain and compile it yourself: +```sh +git clone --depth=1 --branch=release-2.32.8 https://github.com/libsdl-org/SDL +cmake -DCMAKE_BUILD_TYPE=Release -B build +cmake --build build +sudo cmake --install build +``` + +Audio is broken in OpenIndiana [see this issue](https://github.com/libsdl-org/SDL/issues/13405), go into `SDL/CMakeLists.txt` and comment out lines 1468: +```diff ++# set(SDL_AUDIO_DRIVER_SUNAUDIO 1) ++# file(GLOB SUN_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/sun/*.c) ++# list(APPEND SOURCE_FILES ${SUN_AUDIO_SOURCES}) ++# set(HAVE_SDL_AUDIO TRUE) +``` +For Solaris this issue does not exist - however PulseAudio crashes on Solaris - so use a different backend. + +--- + +### Build preparations: +Run the following command to clone eden with git: +```sh +git clone --recursive https://git.eden-emu.dev/eden-emu/eden +``` +You usually want to add the `--recursive` parameter as it also takes care of the external dependencies for you. + +Now change into the eden directory and create a build directory there: +```sh +cd eden +mkdir build +``` + +Change into that build directory: `cd build` + +Now choose one option either 1 or 2, but not both as one option overwrites the other. + +### Building + +```sh +# Needed for some dependencies that call cc directly (tz) +echo '#!/bin/sh' >cc +echo 'gcc $@' >>cc +chmod +x cc +export PATH="$PATH:$PWD" +``` + +- **Configure**: `cmake -B build -DYUZU_TESTS=OFF -DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF -DYUZU_USE_LLVM_DEMANGLE=OFF -DYUZU_USE_QT_MULTIMEDIA=OFF -DYUZU_USE_QT_WEB_ENGINE=OFF -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_USE_BUNDLED_QT=OFF -DENABLE_QT=OFF -DSDL_AUDIO=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_QT_UPDATE_CHECKER=OFF`. +- **Build**: `cmake --build build`. +- **Installing**: `sudo cmake --install build`. + +### Notes + +- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). +- If using OpenIndiana, due to a bug in SDL2 cmake configuration; Audio driver defaults to SunOS ``, which does not exist on OpenIndiana. +- Enabling OpenSSL requires compiling OpenSSL manually instead of using the provided one from repositores. diff --git a/docs/build/Android.md b/docs/build/Android.md new file mode 100644 index 0000000000..4bb1c868b6 --- /dev/null +++ b/docs/build/Android.md @@ -0,0 +1,42 @@ +# Note: These build instructions are a work-in-progress. + +## Dependencies +* [Android Studio](https://developer.android.com/studio) +* [NDK 25.2.9519653 and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version) +* [Git](https://git-scm.com/download) + +### WINDOWS ONLY - Additional Dependencies + * **[Visual Studio 2022 Community](https://visualstudio.microsoft.com/downloads/)** - **Make sure to select "Desktop development with C++" support in the installer. Make sure to update to the latest version if already installed.** + * **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - **Make sure to select Latest SDK.** + - A convenience script to install the latest SDK is provided in `.ci\windows\install-vulkan-sdk.ps1`. + +## Cloning Eden with Git +``` +git clone --recursive https://git.eden-emu.dev/eden-emu/eden.git +``` +Eden by default will be cloned into - +* `C:\Users\\eden` on Windows +* `~/eden` on Linux +* And wherever on macOS + +## Building +1. Start Android Studio, on the startup dialog select `Open`. +2. Navigate to the `eden/src/android` directory and click on `OK`. +3. In `Build > Select Build Variant`, select `release` or `relWithDebInfo` as the "Active build variant". +4. Build the project with `Build > Make Project` or run it on an Android device with `Run > Run 'app'`. + +## Building with Terminal +1. Download the SDK and NDK from Android Studio. +2. Navigate to SDK and NDK paths. +3. Then set ANDROID_SDK_ROOT and ANDROID_NDK_ROOT in terminal via +`export ANDROID_SDK_ROOT=path/to/sdk` +`export ANDROID_NDK_ROOT=path/to/ndk`. +4. Navigate to `eden/src/android`. +5. Then Build with `./gradlew assemblerelWithDebInfo`. +6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`. + +### Script +A convenience script for building is provided in `.ci/android/build.sh`. The built APK can be put into an `artifacts` directory via `.ci/android/package.sh`. On Windows, these must be done in the Git Bash or MinGW terminal. + +### Additional Resources +https://developer.android.com/studio/intro diff --git a/docs/build/FreeBSD.md b/docs/build/FreeBSD.md new file mode 100644 index 0000000000..9e95a6d143 --- /dev/null +++ b/docs/build/FreeBSD.md @@ -0,0 +1,81 @@ +## One word of caution before proceeding. +This is not the usual or preferred way to build programs on FreeBSD. +As of writing there is no official fresh port available for eden-emu, but it is in the works. +After it is available you can find a link to the eden-emu fresh port here and on Escarys github repo. +See this build as an App Image alternative for FreeBSD. + +## Dependencies. +Before we start we need some dependencies. +These dependencies are generally needed to build eden-emu on FreeBSD. + +``` +devel/cmake +devel/sdl20 +devel/boost-libs +devel/catch2 +devel/libfmt +devel/nlohmann-json +devel/ninja +devel/nasm +devel/autoconf +devel/pkg-config +devel/qt6-base + +multimedia/ffnvcodec-headers +multimedia/ffmpeg + +audio/opus + +archivers/liblz4 + +lang/gcc12 + +graphics/glslang +graphics/vulkan-utility-libraries +``` + +--- + +### Build preparations: +Run the following command to clone eden with git: +```sh +git clone --recursive https://git.eden-emu.dev/eden-emu/eden +``` +You usually want to add the `--recursive` parameter as it also takes care of the external dependencies for you. + +Now change into the eden directory and create a build directory there: +```sh +cd eden +mkdir build +``` + +Change into that build directory: +```sh +cd build +``` + +Now choose one option either 1 or 2, but not both as one option overwrites the other. + +#### 1. Building in Release Mode (usually preferred and the most performant choice): +```sh +cmake .. -GNinja -DYUZU_TESTS=OFF +``` + +#### 2. Building in Release Mode with debugging symbols (useful if you want to debug errors for a eventual fix): +```sh +cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=ON +``` + +Build the emulator locally: +```sh +ninja +``` + +Optional: If you wish to install eden globally onto your system issue the following command: +```sh +sudo ninja install +``` +OR +```sh +doas -- ninja install +``` diff --git a/docs/build/Linux.md b/docs/build/Linux.md new file mode 100644 index 0000000000..4aad874ac2 --- /dev/null +++ b/docs/build/Linux.md @@ -0,0 +1,135 @@ +### Dependencies + +You'll need to download and install the following to build Eden: + + * [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc + * If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling + * [CMake](https://www.cmake.org/) 3.22+ + +The following are handled by Eden's externals: + + * [FFmpeg](https://ffmpeg.org/) + * [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ + * [opus](https://opus-codec.org/downloads/) + +All other dependencies will be downloaded by [vcpkg](https://vcpkg.io/) if needed: + + * [Boost](https://www.boost.org/users/download/) 1.79.0+ + * [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 + * [fmt](https://fmt.dev/) 8.0.1+ + * [lz4](http://www.lz4.org) 1.8+ + * [nlohmann_json](https://github.com/nlohmann/json) 3.8+ + * [OpenSSL](https://www.openssl.org/source/) + * [ZLIB](https://www.zlib.net/) 1.2+ + * [zstd](https://facebook.github.io/zstd/) 1.5+ + +If an ARM64 build is intended, export `VCPKG_FORCE_SYSTEM_BINARIES=1`. + +Dependencies are listed here as commands that can be copied/pasted. Of course, they should be inspected before being run. + +- Arch / Manjaro: + - `sudo pacman -Syu --needed base-devel boost catch2 cmake ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip` + - Building with QT Web Engine requires `qt6-webengine` as well. + - Proper wayland support requires `qt6-wayland` + - GCC 11 or later is required. +- Ubuntu / Linux Mint / Debian: + - `sudo apt-get install autoconf cmake g++-11 gcc-11 git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qtbase6-dev qtbase6-private-dev qtwebengine6-dev qtmultimedia6-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev` + - Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. + - Users need to manually specify building with QT Web Engine enabled. This is done using the parameter `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. + - Users need to manually specify building with GCC 11. This can be done by adding the parameters `-DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11` when running CMake. i.e. + - Users need to manually disable building SDL2 from externals if they intend to use the version provided by their system by adding the parameters `-DYUZU_USE_EXTERNAL_SDL2=OFF` + +``` +git submodule update --init --recursive +cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 +``` + +- Fedora: + - `sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt5-linguist qt5-qtbase{-private,}-devel qt5-qtwebengine-devel qt5-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel` + - Fedora 32 or later is required. + - Due to GCC 12, Fedora 36 or later users need to install `clang`, and configure CMake to use it via `-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang` + - CMake arguments to force system libraries: + - SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` + - FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` + - [RPM Fusion](https://rpmfusion.org/) (free) is required to install `ffmpeg-devel` + +### Cloning Eden with Git + +**Master:** + + ```bash + git clone --recursive https://git.eden-emu.dev/eden-emu/eden + cd eden + ``` + +The `--recursive` option automatically clones the required Git submodules. + +### Building Eden in Release Mode (Optimised) + +If you need to run ctests, you can disable `-DYUZU_TESTS=OFF` and install Catch2. + +```bash +mkdir build && cd build +cmake .. -GNinja -DYUZU_TESTS=OFF +ninja +sudo ninja install +``` +You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..` + +`-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` might be needed if ninja command failed with `undefined reference to symbol 'spvOptimizerOptionsCreate`, reason currently unknown + +Optionally, you can use `cmake-gui ..` to adjust various options (e.g. disable the Qt GUI). + +### Building Eden in Debug Mode (Slow) + +```bash +mkdir build && cd build +cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DYUZU_TESTS=OFF +ninja +``` + +### Building with debug symbols + +```bash +mkdir build && cd build +cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU -DYUZU_TESTS=OFF +ninja +``` + +### Building with Scripts +A convenience script for building is provided in `.ci/linux/build.sh`. You must provide an arch target for optimization, e.g. `.ci/linux/build.sh amd64`. Valid targets: +- `legacy`: x86_64 generic, only needed for CPUs older than 2013 or so +- `amd64`: x86_64-v3, for CPUs newer than 2013 or so +- `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) +- `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) +- `aarch64`: For armv8-a CPUs, older than mid-2021 or so +- `armv9`: For armv9-a CPUs, newer than mid-2021 or so +- `native`: Optimize to your native host architecture + +Extra flags to pass to CMake should be passed after the arch target. + +Additional environment variables can be used to control building: +- `NPROC`: Number of threads to use for compilation (defaults to all) +- `TARGET`: Set to `appimage` to disable standalone `eden-cli` and `eden-room` executables +- `BUILD_TYPE`: Sets the build type to use. Defaults to `Release` + +The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: +- `DEVEL` (default FALSE): Disable Qt update checker +- `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine +- `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia + +After building, an AppImage can be packaged via `.ci/linux/package.sh`. This script takes the same arch targets as the build script. If the build was created in a different directory, you can specify its path relative to the source directory, e.g. `.ci/linux/package.sh amd64 build-appimage`. Additionally, set the `DEVEL` environment variable to `true` to change the app name to `Eden Nightly`. + +### Running without installing + +After building, the binaries `eden` and `eden-cmd` (depending on your build options) will end up in `build/bin/`. + + ```bash + # SDL + cd build/bin/ + ./eden-cmd + + # Qt + cd build/bin/ + ./eden + ``` diff --git a/docs/build/Windows.md b/docs/build/Windows.md new file mode 100644 index 0000000000..117398ea09 --- /dev/null +++ b/docs/build/Windows.md @@ -0,0 +1,195 @@ +# THIS GUIDE IS INTENDED FOR DEVELOPERS ONLY, SUPPORT WILL ONLY BE GIVEN IF YOU'RE A DEVELOPER. + +## Method I: MSVC Build for Windows + +### Minimal Dependencies + +On Windows, all library dependencies are automatically included within the `externals` folder, or can be downloaded on-demand. To build Eden, you need to install: + + * **[Visual Studio 2022 Community](https://visualstudio.microsoft.com/downloads/)** - **Make sure to select C++ support in the installer. Make sure to update to the latest version if already installed.** + * **[CMake](https://cmake.org/download/)** - Used to generate Visual Studio project files. Does not matter if either 32-bit or 64-bit version is installed. + * **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - **Make sure to select Latest SDK.** + - A convenience script to install the latest SDK is provided in `.ci\windows\install-vulkan-sdk.ps1`. + + ![2](https://i.imgur.com/giDwuTm.png) + + * **Git** - We recommend [Git for Windows](https://gitforwindows.org). + + ![3](https://i.imgur.com/UeSzkBw.png) + + * While installing Git Bash, you should tell it to include Git in your system path. (Choose the "Git from the command line and also from 3rd-party software" option.) If you missed that, don't worry, you'll just have to manually tell CMake where your git.exe is, since it's used to include version info into the built executable. + + ![4](https://i.imgur.com/x0rRs1t.png) + +### Cloning Eden with Git + +**Master:** + ```cmd + git clone --recursive https://git.eden-emu.dev/eden-emu/eden + cd eden + ``` + + ![9](https://i.imgur.com/CcxIAht.png) + +* *(Note: eden by default downloads to `C:\Users\\eden` (Master) + +### Building + +* Open the CMake GUI application and point it to the `eden` (Master) + + ![10](https://i.imgur.com/qOslIWv.png) + +* For the build directory, use a `/build` subdirectory inside the source directory or some other directory of your choice. (Tell CMake to create it.) + +* Click the "Configure" button and choose `Visual Studio 17 2022`, with `x64` for the optional platform. + + ![12](https://i.imgur.com/DKiREaK.png) + + * *(Note: If you used GitHub's own app to clone, run `git submodule update --init --recursive` to get the remaining dependencies)* + +* If you get an error about missing packages, enable `YUZU_USE_BUNDLED_VCPKG`, and then click Configure again. + + * *(You may also want to disable `YUZU_TESTS` in this case since Catch2 is not yet supported with this.)* + + ![13](https://user-images.githubusercontent.com/22451773/180585999-07316d6e-9751-4d11-b957-1cf57cd7cd58.png) + +* Click "Generate" to create the project files. + + ![15](https://i.imgur.com/5LKg92k.png) + +* Open the solution file `yuzu.sln` in Visual Studio 2022, which is located in the build folder. + + ![16](https://i.imgur.com/208yMml.png) + +* Depending if you want a graphical user interface or not (`eden` has the graphical user interface, while `eden-cmd` doesn't), select `eden` or `eden-cmd` in the Solution Explorer, right-click and `Set as StartUp Project`. + + ![17](https://i.imgur.com/nPMajnn.png) ![18](https://i.imgur.com/BDMLzRZ.png) + +* Select the appropriate build type, Debug for debug purposes or Release for performance (in case of doubt choose Release). + + ![19](https://i.imgur.com/qxg4roC.png) + +* Right-click the project you want to build and press Build in the submenu or press F5. + + ![20](https://i.imgur.com/CkQgOFW.png) + +## Method II: MinGW-w64 Build with MSYS2 + +### Prerequisites to install + +* [MSYS2](https://www.msys2.org) +* [Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows) - **Make sure to select Latest SDK.** +* Make sure to follow the instructions and update to the latest version by running `pacman -Syu` as many times as needed. + +### Install eden dependencies for MinGW-w64 + +* Open the `MSYS2 MinGW 64-bit` (mingw64.exe) shell +* Download and install all dependencies using: `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` +* Add MinGW binaries to the PATH: `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` +* Add glslangValidator to the PATH: `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` + +### Clone the eden repository with Git + + ```bash + git clone --recursive https://git.eden-emu.dev/eden-emu/eden + cd eden + ``` + +### Run the following commands to build eden (dynamically linked build) + +```bash +mkdir build && cd build +cmake -G "MSYS Makefiles" -DYUZU_USE_BUNDLED_VCPKG=ON -DYUZU_TESTS=OFF .. +make -j$(nproc) +# test eden out with +./bin/eden.exe +``` + +* *(Note: This build is not a static build meaning that you need to include all of the DLLs with the .exe in order to use it!)* + +e.g. +```Bash +cp externals/ffmpeg-*/bin/*.dll bin/ +``` + +Bonus Note: Running programs from inside `MSYS2 MinGW x64` shell has a different %PATH% than directly from explorer. This different %PATH% has the locations of the other DLLs required. +![image](https://user-images.githubusercontent.com/190571/165000848-005e8428-8a82-41b1-bb4d-4ce7797cdac8.png) + + +### Building without Qt (Optional) + +Doesn't require the rather large Qt dependency, but you will lack a GUI frontend: + + * Pass the `-DENABLE_QT=no` flag to cmake + +## Method III: CLion Environment Setup + +### Minimal Dependencies + +To build eden, you need to install the following: + +* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I +* [Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows) - Make sure to select the Latest SDK. + +### Cloning eden with CLion + +* Clone the Repository: + +![1](https://user-images.githubusercontent.com/42481638/216899046-0d41d7d6-8e4d-4ed2-9587-b57088af5214.png) +![2](https://user-images.githubusercontent.com/42481638/216899061-b2ea274a-e88c-40ae-bf0b-4450b46e9fea.png) +![3](https://user-images.githubusercontent.com/42481638/216899076-0e5988c4-d431-4284-a5ff-9ecff973db76.png) + + + +### Building & Setup + +* Once Cloned, You will be taken to a prompt like the image below: + +![4](https://user-images.githubusercontent.com/42481638/216899092-3fe4cec6-a540-44e3-9e1e-3de9c2fffc2f.png) + +* Set the settings to the image below: +* Change `Build type: Release` +* Change `Name: Release` +* Change `Toolchain Visual Studio` +* Change `Generator: Let CMake decide` +* Change `Build directory: build` + +![5](https://user-images.githubusercontent.com/42481638/216899164-6cee8482-3d59-428f-b1bc-e6dc793c9b20.png) + +* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. +* Once this process has been completed (No loading bar bottom right), you can now build eden +* In the top right, click on the drop-down menu, select all configurations, then select eden + +![6](https://user-images.githubusercontent.com/42481638/216899226-975048e9-bc6d-4ec1-bc2d-bd8a1e15ed04.png) + +* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. + +![7](https://user-images.githubusercontent.com/42481638/216899275-d514ec6a-e563-470e-81e2-3e04f0429b68.png) + +## Building from the command line with MSVC + +```cmd +git clone --recursive https://git.eden-emu.dev/eden-emu/eden +cd eden +mkdir build +cd build +cmake .. -G "Visual Studio 17 2022" -A x64 +cmake --build . --config Release +``` + +### Building with Scripts +A convenience script for building is provided in `.ci/windows/build.sh`. You must run this with Bash, e.g. Git Bash or MinGW TTY. To use this script, you must have windeployqt installed (usually bundled with Qt) and set the `WINDEPLOYQT` environment variable to its canonical Bash location, e.g. `WINDEPLOYQT="/c/Qt/6.9.1/msvc2022_64/bin/windeployqt6.exe" .ci/windows/build.sh`. + +Extra CMake flags should be placed in the arguments of the script. + +Additional environment variables can be used to control building: +- `BUILD_TYPE`: Sets the build type to use. Defaults to `Release` + +The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: +- `DEVEL` (default FALSE): Disable Qt update checker +- `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine +- `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia +- `BUNDLE_QT` (default FALSE): Use bundled Qt + * Note that using system Qt requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH`, e.g. `.ci/windows/build.sh -DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` + +After building, a zip can be packaged via `.ci/windows/package.sh`. Note that you must have 7-zip installed and in your PATH. The resulting zip will be placed into `artifacts` in the source directory. diff --git a/docs/build/macOS.md b/docs/build/macOS.md new file mode 100644 index 0000000000..6cb62273cb --- /dev/null +++ b/docs/build/macOS.md @@ -0,0 +1,105 @@ +Please note this article is intended for development, and eden on macOS is not currently ready for regular use. + +This article was written for developers. eden support for macOS is not ready for casual use. + +## Method I: ninja +--- +If you are compiling on Intel Mac or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` to `/usr/local`. + +Install dependencies from Homebrew: +```sh +brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zlib zstd cmake Catch2 molten-vk vulkan-loader +``` + +Clone the repo +```sh +git clone --recursive https://git.eden-emu.dev/eden-emu/eden + +cd eden +``` + +Build for release +```sh +mkdir build && cd build + +export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" + +export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib + +cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON + +ninja +``` + +You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..` + +Build with debug symbols (vcpkg is not currently used due to broken boost-context library): +```sh +mkdir build && cd build +export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" +cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF +ninja +``` + +Run the output: +``` +bin/eden.app/Contents/MacOS/eden +``` + +## Method II: Xcode + +--- +If you are compiling on Intel Mac or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` to `/usr/local`. + +Install dependencies from Homebrew: +```sh +brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zlib zstd cmake Catch2 molten-vk vulkan-loader +``` + +Clone the repo +```sh +git clone --recursive https://git.eden-emu.dev/eden-emu/eden + +cd eden +``` + +Build for release +```sh +mkdir build && cd build + +export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" + +export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib + +cmake .. -GXcode -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON + +xcodebuild build -project eden.xcodeproj -scheme "eden" -configuration "RelWithDebInfo" +``` + +You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..` + +Build with debug symbols (vcpkg is not currently used due to broken boost-context library): +```sh +mkdir build && cd build +export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" +cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_USE_BUNDLED_VCPKG=OFF -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF +ninja +``` + +Run the output: +``` +bin/eden.app/Contents/MacOS/eden +``` + +--- + +To run with MoltenVK, install additional dependencies: +```sh +brew install molten-vk vulkan-loader +``` + +Run with Vulkan loader path: +```sh +export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib +bin/eden.app/Contents/MacOS/eden +``` \ No newline at end of file diff --git a/externals/dynarmic/externals/catch b/externals/dynarmic/externals/catch index 74fcff6e5b..5aa8d11321 160000 --- a/externals/dynarmic/externals/catch +++ b/externals/dynarmic/externals/catch @@ -1 +1 @@ -Subproject commit 74fcff6e5b190fb833a231b7f7c1829e3c3ac54d +Subproject commit 5aa8d113215bd9a97ecc1a2f3fc9506947a2fa57 diff --git a/externals/dynarmic/externals/fmt b/externals/dynarmic/externals/fmt index 02de29e003..35dcc58263 160000 --- a/externals/dynarmic/externals/fmt +++ b/externals/dynarmic/externals/fmt @@ -1 +1 @@ -Subproject commit 02de29e00321787fa515ca60f0f5911e61892dc6 +Subproject commit 35dcc58263d6b55419a5932bd6b0b3029a0a8c00 diff --git a/externals/dynarmic/externals/xbyak b/externals/dynarmic/externals/xbyak index 44a72f3692..12557954c6 160000 --- a/externals/dynarmic/externals/xbyak +++ b/externals/dynarmic/externals/xbyak @@ -1 +1 @@ -Subproject commit 44a72f369268f7d552650891b296693e91db86bb +Subproject commit 12557954c68a780563f9ab9fc24a3a156c96cba1 diff --git a/externals/dynarmic/externals/zycore-c b/externals/dynarmic/externals/zycore-c index 7ad36e5211..75a36c45ae 160000 --- a/externals/dynarmic/externals/zycore-c +++ b/externals/dynarmic/externals/zycore-c @@ -1 +1 @@ -Subproject commit 7ad36e52110b39cfb62b47bfdb6def94ac531309 +Subproject commit 75a36c45ae1ad382b0f4e0ede0af84c11ee69928 diff --git a/externals/dynarmic/externals/zydis b/externals/dynarmic/externals/zydis index 6372690e30..c2d2bab025 160000 --- a/externals/dynarmic/externals/zydis +++ b/externals/dynarmic/externals/zydis @@ -1 +1 @@ -Subproject commit 6372690e30389a94db65ece2d8a1f0a2310475ed +Subproject commit c2d2bab0255e53a7c3e9b615f4eb69449eb942df diff --git a/externals/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp b/externals/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp index 2d6d6ea6d8..8a523267e5 100644 --- a/externals/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp +++ b/externals/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2019 MerryMage * SPDX-License-Identifier: 0BSD @@ -13,6 +16,9 @@ # ifndef __OpenBSD__ # include # endif +# ifdef __sun__ +# include +# endif #endif #include @@ -145,9 +151,9 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { #ifndef MCL_ARCHITECTURE_RISCV ucontext_t* ucontext = reinterpret_cast(raw_context); -# ifndef __OpenBSD__ +#ifndef __OpenBSD__ auto& mctx = ucontext->uc_mcontext; -# endif +#endif #endif #if defined(MCL_ARCHITECTURE_X86_64) @@ -167,6 +173,9 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { # elif defined(__OpenBSD__) # define CTX_RIP (ucontext->sc_rip) # define CTX_RSP (ucontext->sc_rsp) +# elif defined(__sun__) +# define CTX_RIP (mctx.gregs[REG_RIP]) +# define CTX_RSP (mctx.gregs[REG_RSP]) # else # error "Unknown platform" # endif diff --git a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp index a0ee8ae9ed..db7c692f07 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp @@ -415,21 +415,54 @@ void RegAlloc::ReleaseStackSpace(const size_t stack_space) noexcept { } HostLoc RegAlloc::SelectARegister(const boost::container::static_vector& desired_locations) const noexcept { - boost::container::static_vector candidates = desired_locations; //Who let someone copy an ENTIRE VECTOR here? - - // Find all locations that have not been allocated.. - const auto allocated_locs = std::partition(candidates.begin(), candidates.end(), [this](auto loc) noexcept { - return !this->LocInfo(loc).IsLocked(); - }); - candidates.erase(allocated_locs, candidates.end()); - ASSERT_MSG(!candidates.empty(), "All candidate registers have already been allocated"); + // TODO(lizzie): Overspill causes issues (reads to 0 and such) on some games, I need to make a testbench + // to later track this down - however I just modified the LRU algo so it prefers empty registers first + // we need to test high register pressure (and spills, maybe 32 regs?) // Selects the best location out of the available locations. + // NOTE: Using last is BAD because new REX prefix for each insn using the last regs // TODO: Actually do LRU or something. Currently we just try to pick something without a value if possible. - auto const it = std::find_if(candidates.begin(), candidates.end(), [this](auto const loc) noexcept { - return this->LocInfo(loc).IsEmpty(); - }); - return it != candidates.end() ? *it : candidates.front(); + auto min_lru_counter = size_t(-1); + auto it_candidate = desired_locations.cend(); //default fallback if everything fails + auto it_rex_candidate = desired_locations.cend(); + auto it_empty_candidate = desired_locations.cend(); + for (auto it = desired_locations.cbegin(); it != desired_locations.cend(); it++) { + auto const& loc_info = LocInfo(*it); + // Abstain from using upper registers unless absolutely nescesary + if (loc_info.IsLocked()) { + // skip, not suitable for allocation + } else { + if (loc_info.lru_counter < min_lru_counter) { + if (loc_info.IsEmpty()) + it_empty_candidate = it; + // Otherwise a "quasi"-LRU + min_lru_counter = loc_info.lru_counter; + if (*it >= HostLoc::R8 && *it <= HostLoc::R15) { + it_rex_candidate = it; + } else { + it_candidate = it; + } + if (min_lru_counter == 0) + break; //early exit + } + // only if not assigned (i.e for failcase of all LRU=0) + if (it_empty_candidate == desired_locations.cend() && loc_info.IsEmpty()) + it_empty_candidate = it; + } + } + // Final resolution goes as follows: + // 1 => Try an empty candidate + // 2 => Try normal candidate (no REX prefix) + // 3 => Try using a REX prefixed one + // We avoid using REX-addressable registers because they add +1 REX prefix which + // do we really need? The trade-off may not be worth it. + auto const it_final = it_empty_candidate != desired_locations.cend() + ? it_empty_candidate : it_candidate != desired_locations.cend() + ? it_candidate : it_rex_candidate; + ASSERT_MSG(it_final != desired_locations.cend(), "All candidate registers have already been allocated"); + // Evil magic - increment LRU counter (will wrap at 256) + const_cast(this)->LocInfo(*it_final).lru_counter++; + return *it_final; } void RegAlloc::DefineValueImpl(IR::Inst* def_inst, HostLoc host_loc) noexcept { diff --git a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h index 599aab12a8..64f7c1ec40 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h +++ b/externals/dynarmic/src/dynarmic/backend/x64/reg_alloc.h @@ -92,8 +92,8 @@ private: uint8_t max_bit_width = 0; //Valid values: 1,2,4,8,16,32,128 bool is_scratch : 1 = false; //1 bool is_set_last_use : 1 = false; //1 - - alignas(16) char padding; + alignas(16) uint8_t lru_counter = 0; //1 + friend class RegAlloc; }; static_assert(sizeof(HostLocInfo) == 64); diff --git a/externals/dynarmic/src/dynarmic/common/memory_pool.h b/externals/dynarmic/src/dynarmic/common/memory_pool.h index c99316e107..ea3f3d84d6 100644 --- a/externals/dynarmic/src/dynarmic/common/memory_pool.h +++ b/externals/dynarmic/src/dynarmic/common/memory_pool.h @@ -47,7 +47,7 @@ private: /// Used when an entirely new slab is needed /// due the current one running out of usable space. void AllocateNewSlab() noexcept { - current_slab = static_cast(std::malloc(object_size * slab_size)); + current_slab = static_cast(std::aligned_alloc(object_size, object_size * slab_size)); current_ptr = current_slab; remaining = slab_size; } diff --git a/externals/dynarmic/src/dynarmic/ir/basic_block.cpp b/externals/dynarmic/src/dynarmic/ir/basic_block.cpp index c818fe0b17..9c039a6694 100644 --- a/externals/dynarmic/src/dynarmic/ir/basic_block.cpp +++ b/externals/dynarmic/src/dynarmic/ir/basic_block.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -22,12 +21,7 @@ namespace Dynarmic::IR { Block::Block(const LocationDescriptor& location) - : location{location}, - end_location{location}, - cond{Cond::AL}, - instruction_alloc_pool{std::make_unique>()} -{ - + : location{location}, end_location{location}, cond{Cond::AL}, instruction_alloc_pool{std::make_unique()} { } /// Prepends a new instruction to this basic block before the insertion point, diff --git a/externals/dynarmic/src/dynarmic/ir/basic_block.h b/externals/dynarmic/src/dynarmic/ir/basic_block.h index 6608f0e3a2..ad81727ef2 100644 --- a/externals/dynarmic/src/dynarmic/ir/basic_block.h +++ b/externals/dynarmic/src/dynarmic/ir/basic_block.h @@ -17,7 +17,6 @@ #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/terminal.h" #include "dynarmic/ir/value.h" -#include "dynarmic/ir/dense_list.h" #include "dynarmic/common/memory_pool.h" namespace Dynarmic::IR { @@ -171,8 +170,9 @@ private: LocationDescriptor end_location; /// Conditional to pass in order to execute this block Cond cond; + using InstPool = Common::Pool; /// Memory pool for instruction list - std::unique_ptr> instruction_alloc_pool; + std::unique_ptr instruction_alloc_pool; /// Terminal instruction of this block. Terminal terminal = Term::Invalid{}; /// Number of cycles this block takes to execute if the conditional fails. diff --git a/externals/dynarmic/src/dynarmic/ir/microinstruction.h b/externals/dynarmic/src/dynarmic/ir/microinstruction.h index a26a9d80b3..ab44b490d6 100644 --- a/externals/dynarmic/src/dynarmic/ir/microinstruction.h +++ b/externals/dynarmic/src/dynarmic/ir/microinstruction.h @@ -23,7 +23,7 @@ constexpr size_t max_arg_count = 4; /// A representation of a microinstruction. A single ARM/Thumb instruction may be /// converted into zero or more microinstructions. //class Inst final { -class Inst final : public mcl::intrusive_list_node { +class alignas(64) Inst final : public mcl::intrusive_list_node { public: explicit Inst(Opcode op) : op(op) {} @@ -74,12 +74,12 @@ private: void UndoUse(const Value& value); // TODO: so much padding wasted with mcl::intrusive_node - // 16 + 1, 24 - Opcode op; //2 (6) + // 17 + Opcode op; // 20(4) // Linked list of pseudooperations associated with this instruction. - Inst* next_pseudoop = nullptr; //8 (14) - unsigned use_count = 0; //4 (0) - unsigned name = 0; //4 (4) + Inst* next_pseudoop = nullptr; // 24(8) + unsigned use_count = 0; // 32(4) + unsigned name = 0; // 36(4) alignas(64) std::array args; //16 * 4 = 64 (1 cache line) }; static_assert(sizeof(Inst) == 128); diff --git a/externals/dynarmic/tests/A32/test_arm_instructions.cpp b/externals/dynarmic/tests/A32/test_arm_instructions.cpp index 3232f1a8f1..598f9d2248 100644 --- a/externals/dynarmic/tests/A32/test_arm_instructions.cpp +++ b/externals/dynarmic/tests/A32/test_arm_instructions.cpp @@ -539,7 +539,8 @@ TEST_CASE("arm: Memory access (fastmem)", "[arm][A32]") { char* backing_memory = reinterpret_cast(std::align(page_size, memory_size, buffer_ptr, buffer_size_nconst)); A32FastmemTestEnv env{backing_memory}; - Dynarmic::A32::UserConfig config{&env}; + Dynarmic::A32::UserConfig config{}; + config.callbacks = &env; config.fastmem_pointer = reinterpret_cast(backing_memory); config.recompile_on_fastmem_failure = false; config.processor_id = 0; diff --git a/externals/dynarmic/tests/A64/a64.cpp b/externals/dynarmic/tests/A64/a64.cpp index 246e61e122..801b01d555 100644 --- a/externals/dynarmic/tests/A64/a64.cpp +++ b/externals/dynarmic/tests/A64/a64.cpp @@ -15,7 +15,9 @@ using namespace oaknut::util; TEST_CASE("A64: ADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x8b020020); // ADD X0, X1, X2 env.code_mem.emplace_back(0x14000000); // B . @@ -36,7 +38,9 @@ TEST_CASE("A64: ADD", "[a64]") { TEST_CASE("A64: ADD{V,P}", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0E31B801); // ADDV b1, v0.8b env.code_mem.emplace_back(0x4E31B802); // ADDV b2, v0.16b @@ -62,7 +66,9 @@ TEST_CASE("A64: ADD{V,P}", "[a64]") { TEST_CASE("A64: CLZ", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.CLZ(V3.B16(), V0.B16()); @@ -84,7 +90,9 @@ TEST_CASE("A64: CLZ", "[a64]") { TEST_CASE("A64: UADDL{V,P}", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x2E303801); // UADDLV h1, v0.8b env.code_mem.emplace_back(0x6E303802); // UADDLV h2, v0.16b @@ -110,7 +118,9 @@ TEST_CASE("A64: UADDL{V,P}", "[a64]") { TEST_CASE("A64: SADDL{V,P}", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0E303801); // SADDLV h1, v0.8b env.code_mem.emplace_back(0x4E303802); // SADDLV h2, v0.16b @@ -136,7 +146,9 @@ TEST_CASE("A64: SADDL{V,P}", "[a64]") { TEST_CASE("A64: VQADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6e210c02); // UQADD v2.16b, v0.16b, v1.16b env.code_mem.emplace_back(0x4e210c03); // SQADD v3.16b, v0.16b, v1.16b @@ -167,7 +179,9 @@ TEST_CASE("A64: VQADD", "[a64]") { TEST_CASE("A64: VQSUB", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6e212c02); // UQSUB v2.16b, v0.16b, v1.16b env.code_mem.emplace_back(0x4e212c03); // SQSUB v3.16b, v0.16b, v1.16b @@ -198,7 +212,9 @@ TEST_CASE("A64: VQSUB", "[a64]") { TEST_CASE("A64: REV", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xdac00c00); // REV X0, X0 env.code_mem.emplace_back(0x5ac00821); // REV W1, W1 @@ -218,7 +234,9 @@ TEST_CASE("A64: REV", "[a64]") { TEST_CASE("A64: REV32", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xdac00800); // REV32 X0, X0 env.code_mem.emplace_back(0x14000000); // B . @@ -234,7 +252,9 @@ TEST_CASE("A64: REV32", "[a64]") { TEST_CASE("A64: REV16", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xdac00400); // REV16 X0, X0 env.code_mem.emplace_back(0x5ac00421); // REV16 W1, W1 @@ -254,7 +274,9 @@ TEST_CASE("A64: REV16", "[a64]") { TEST_CASE("A64: SSHL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SSHL(V4.B16(), V4.B16(), V0.B16()); @@ -288,7 +310,9 @@ TEST_CASE("A64: SSHL", "[a64]") { TEST_CASE("A64: USHL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.USHL(V4.B16(), V4.B16(), V0.B16()); @@ -334,7 +358,9 @@ TEST_CASE("A64: USHL", "[a64]") { TEST_CASE("A64: URSHL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.URSHL(V0.S4(), V1.S4(), V2.S4()); @@ -365,7 +391,9 @@ TEST_CASE("A64: URSHL", "[a64]") { TEST_CASE("A64: XTN", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0e212803); // XTN v3.8b, v0.8h env.code_mem.emplace_back(0x0e612824); // XTN v4.4h, v1.4s @@ -387,7 +415,9 @@ TEST_CASE("A64: XTN", "[a64]") { TEST_CASE("A64: TBL", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0e000100); // TBL v0.8b, { v8.16b }, v0.8b env.code_mem.emplace_back(0x4e010101); // TBL v1.16b, { v8.16b }, v1.16b @@ -433,7 +463,9 @@ TEST_CASE("A64: TBL", "[a64]") { TEST_CASE("A64: TBX", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0e001100); // TBX v0.8b, { v8.16b }, v0.8b env.code_mem.emplace_back(0x4e011101); // TBX v1.16b, { v8.16b }, v1.16b @@ -479,7 +511,9 @@ TEST_CASE("A64: TBX", "[a64]") { TEST_CASE("A64: AND", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x8a020020); // AND X0, X1, X2 env.code_mem.emplace_back(0x14000000); // B . @@ -500,7 +534,9 @@ TEST_CASE("A64: AND", "[a64]") { TEST_CASE("A64: Bitmasks", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x3200c3e0); // ORR W0, WZR, #0x01010101 env.code_mem.emplace_back(0x320c8fe1); // ORR W1, WZR, #0x00F000F0 @@ -520,7 +556,9 @@ TEST_CASE("A64: Bitmasks", "[a64]") { TEST_CASE("A64: ANDS NZCV", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6a020020); // ANDS W0, W1, W2 env.code_mem.emplace_back(0x14000000); // B . @@ -575,7 +613,9 @@ TEST_CASE("A64: ANDS NZCV", "[a64]") { TEST_CASE("A64: CBZ", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x34000060); // 0x00 : CBZ X0, label env.code_mem.emplace_back(0x320003e2); // 0x04 : MOV X2, 1 @@ -608,7 +648,9 @@ TEST_CASE("A64: CBZ", "[a64]") { TEST_CASE("A64: TBZ", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x36180060); // 0x00 : TBZ X0, 3, label env.code_mem.emplace_back(0x320003e2); // 0x04 : MOV X2, 1 @@ -652,7 +694,9 @@ TEST_CASE("A64: TBZ", "[a64]") { TEST_CASE("A64: FABD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x6eb5d556); // FABD.4S V22, V10, V21 env.code_mem.emplace_back(0x14000000); // B . @@ -669,7 +713,9 @@ TEST_CASE("A64: FABD", "[a64]") { TEST_CASE("A64: FABS", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ef8f804); // FABS v4.8h, v0.8h env.code_mem.emplace_back(0x4ea0f825); // FABS v5.4s, v1.4s @@ -691,7 +737,9 @@ TEST_CASE("A64: FABS", "[a64]") { TEST_CASE("A64: FMIN (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ea1f400); // FMIN.4S V0, V0, V1 env.code_mem.emplace_back(0x4ee3f442); // FMIN.2D V2, V2, V3 @@ -713,7 +761,9 @@ TEST_CASE("A64: FMIN (example)", "[a64]") { TEST_CASE("A64: FMAX (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e21f400); // FMAX.4S V0, V0, V1 env.code_mem.emplace_back(0x4e63f442); // FMAX.2D V2, V2, V3 @@ -735,7 +785,9 @@ TEST_CASE("A64: FMAX (example)", "[a64]") { TEST_CASE("A64: FMINNM (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ea1c400); // FMINNM.4S V0, V0, V1 env.code_mem.emplace_back(0x4ee3c442); // FMINNM.2D V2, V2, V3 @@ -757,7 +809,9 @@ TEST_CASE("A64: FMINNM (example)", "[a64]") { TEST_CASE("A64: FMAXNM (example)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e21c400); // FMAXNM.4S V0, V0, V1 env.code_mem.emplace_back(0x4e63c442); // FMAXNM.2D V2, V2, V3 @@ -779,7 +833,9 @@ TEST_CASE("A64: FMAXNM (example)", "[a64]") { TEST_CASE("A64: FMAXNM (example 2)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e3bc6fd); // FMAXNM.4S V29, V23, V27 env.code_mem.emplace_back(0x14000000); // B . @@ -831,7 +887,9 @@ TEST_CASE("A64: 128-bit exclusive read/write", "[a64]") { TEST_CASE("A64: CNTPCT_EL0", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xd53be021); // MRS X1, CNTPCT_EL0 env.code_mem.emplace_back(0xd503201f); // NOP @@ -852,7 +910,9 @@ TEST_CASE("A64: CNTPCT_EL0", "[a64]") { TEST_CASE("A64: FNMSUB 1", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f618a9c); // FNMSUB D28, D20, D1, D2 env.code_mem.emplace_back(0x14000000); // B . @@ -870,7 +930,9 @@ TEST_CASE("A64: FNMSUB 1", "[a64]") { TEST_CASE("A64: FNMSUB 2", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f2ab88e); // FNMSUB S14, S4, S10, S14 env.code_mem.emplace_back(0x14000000); // B . @@ -889,7 +951,9 @@ TEST_CASE("A64: FNMSUB 2", "[a64]") { TEST_CASE("A64: FMADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f5e0e4a); // FMADD D10, D18, D30, D3 env.code_mem.emplace_back(0x14000000); // B . @@ -908,7 +972,9 @@ TEST_CASE("A64: FMADD", "[a64]") { TEST_CASE("A64: FMLA.4S(lane)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4f8f11c0); // FMLA.4S V0, V14, V15[0] env.code_mem.emplace_back(0x4faf11c1); // FMLA.4S V1, V14, V15[1] @@ -936,7 +1002,9 @@ TEST_CASE("A64: FMLA.4S(lane)", "[a64]") { TEST_CASE("A64: FMUL.4S(lane)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4f8f91c0); // FMUL.4S V0, V14, V15[0] env.code_mem.emplace_back(0x4faf91c1); // FMUL.4S V1, V14, V15[1] @@ -959,7 +1027,9 @@ TEST_CASE("A64: FMUL.4S(lane)", "[a64]") { TEST_CASE("A64: FMLA.4S (denormal)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e2fcccc); // FMLA.4S V12, V6, V15 env.code_mem.emplace_back(0x14000000); // B . @@ -978,7 +1048,9 @@ TEST_CASE("A64: FMLA.4S (denormal)", "[a64]") { TEST_CASE("A64: FMLA.4S (0x80800000)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e38cc2b); // FMLA.4S V11, V1, V24 env.code_mem.emplace_back(0x14000000); // B . @@ -1000,7 +1072,9 @@ TEST_CASE("A64: FMLA.4S (0x80800000)", "[a64]") { // x64 performs rounding before flushing-to-zero. TEST_CASE("A64: FMADD (0x80800000)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x1f0f7319); // FMADD S25, S24, S15, S28 env.code_mem.emplace_back(0x14000000); // B . @@ -1019,7 +1093,9 @@ TEST_CASE("A64: FMADD (0x80800000)", "[a64]") { TEST_CASE("A64: FNEG failed to zero upper", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x2ea0fb50); // FNEG.2S V16, V26 env.code_mem.emplace_back(0x2e207a1c); // SQNEG.8B V28, V16 @@ -1038,7 +1114,9 @@ TEST_CASE("A64: FNEG failed to zero upper", "[a64]") { TEST_CASE("A64: FRSQRTS", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x5eb8fcad); // FRSQRTS S13, S5, S24 env.code_mem.emplace_back(0x14000000); // B . @@ -1060,7 +1138,9 @@ TEST_CASE("A64: FRSQRTS", "[a64]") { TEST_CASE("A64: SQDMULH.8H (saturate)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4e62b420); // SQDMULH.8H V0, V1, V2 env.code_mem.emplace_back(0x14000000); // B . @@ -1081,7 +1161,9 @@ TEST_CASE("A64: SQDMULH.8H (saturate)", "[a64]") { TEST_CASE("A64: SQDMULH.4S (saturate)", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x4ea2b420); // SQDMULH.4S V0, V1, V2 env.code_mem.emplace_back(0x14000000); // B . @@ -1102,7 +1184,8 @@ TEST_CASE("A64: SQDMULH.4S (saturate)", "[a64]") { TEST_CASE("A64: This is an infinite loop if fast dispatch is enabled", "[a64]") { A64TestEnv env; - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; conf.optimizations &= ~OptimizationFlag::FastDispatch; A64::Jit jit{conf}; @@ -1119,7 +1202,9 @@ TEST_CASE("A64: This is an infinite loop if fast dispatch is enabled", "[a64]") TEST_CASE("A64: EXTR", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x93d8fef7); // EXTR X23, X23, X24, #63 env.code_mem.emplace_back(0x14000000); // B . @@ -1136,7 +1221,9 @@ TEST_CASE("A64: EXTR", "[a64]") { TEST_CASE("A64: Isolated GetNZCVFromOp", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xaa1f03f5); // MOV X21, XZR env.code_mem.emplace_back(0x912a02da); // ADD X26, X22, #0xa80 @@ -1167,7 +1254,9 @@ TEST_CASE("A64: Isolated GetNZCVFromOp", "[a64]") { TEST_CASE("A64: Optimization failure when folding ADD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0xbc4f84be); // LDR S30, [X5], #248 env.code_mem.emplace_back(0x9a0c00ea); // ADC X10, X7, X12 @@ -1263,7 +1352,8 @@ TEST_CASE("A64: Cache Maintenance Instructions", "[a64]") { }; CacheMaintenanceTestEnv env; - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; conf.hook_data_cache_operations = true; A64::Jit jit{conf}; @@ -1290,7 +1380,8 @@ TEST_CASE("A64: Memory access (fastmem)", "[a64]") { char* backing_memory = reinterpret_cast(std::align(page_size, memory_size, buffer_ptr, buffer_size_nconst)); A64FastmemTestEnv env{backing_memory}; - Dynarmic::A64::UserConfig config{&env}; + Dynarmic::A64::UserConfig config{}; + config.callbacks = &env; config.fastmem_pointer = reinterpret_cast(backing_memory); config.fastmem_address_space_bits = address_width; config.recompile_on_fastmem_failure = false; @@ -1323,7 +1414,9 @@ TEST_CASE("A64: Memory access (fastmem)", "[a64]") { TEST_CASE("A64: SQRDMULH QC flag when output invalidated", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x0fbcd38b); // SQRDMULH.2S V11, V28, V28[1] env.code_mem.emplace_back(0x7ef0f8eb); // FMINP.2D D11, V7 @@ -1343,7 +1436,9 @@ TEST_CASE("A64: SQRDMULH QC flag when output invalidated", "[a64]") { TEST_CASE("A64: SDIV maximally", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(0x9ac00c22); // SDIV X2, X1, X0 env.code_mem.emplace_back(0x14000000); // B . @@ -1367,7 +1462,9 @@ TEST_CASE("A64: SDIV maximally", "[a64]") { // const HostLocList any_xmm = { HostLoc::XMM1, HostLoc::XMM2, HostLoc::XMM3, HostLoc::XMM4, HostLoc::XMM5, HostLoc::XMM6 }; TEST_CASE("A64: rand1", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem = {0x2ea2e69a, 0x6f7168e7, 0x7eb0f816, 0x6ebd369d, 0x1e65c302, 0x1e63011c, 0x1e67c349, 0x0f861bd6, 0x9e59cbbc, 0x5e61cb8b, 0x6e218b01, 0x4eb2409f, 0x7f7c2452, 0x7e207a8d, 0xd503369f}; env.code_mem.emplace_back(0x14000000); // B . @@ -1480,7 +1577,10 @@ TEST_CASE("A64: rand1", "[a64]") { TEST_CASE("A64: rand2", "[a64][.]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{.callbacks = &env, .fastmem_pointer = 0xffffffff00000000}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + jit_user_config.fastmem_pointer = 0xffffffff00000000; + A64::Jit jit{jit_user_config}; env.code_mem = {0xea80f352, 0x6e65e59d, 0x1e20c343, 0x2e3a7192, 0x2e267249, 0xd500405f, 0x6f01f461, 0x6eb684fc, 0x58028edd, 0x0ea5f5b6, 0x0ea069fb, 0x2e769517, 0x5e066063, 0x1e65c3f5, 0x4f00ff52, 0x93401cf6, 0x1e274248, 0x6f67aaf5, 0x5e0c0782, 0x5ef43f3c, 0x2e6595b7, 0x4e20590f, 0xb35aa451, 0x6ee2c5ed, 0x4e32bf46, 0x2ea1ba8f, 0x2f68a85e, 0x9237d90a, 0x5e23dd10, 0x0e762e32, 0x4e31a8cf, 0xce1f3360, 0x781a4ac0, 0x13834066, 0x5fa8101c, 0x6f7c5594, 0x0e71bb68, 0xbc0b3e8f, 0x785dbbda, 0x6f51e794, 0xce50af75, 0x1ad728ec, 0x6ee0da4c, 0xb84efa14, 0x2eb3f613, 0x4e287ade, 0x4eb8c734, 0x2e83f4e8, 0x0e397c80, 0xd08f93f8, 0xce718e48, 0x0f672a0d, 0x2e9edd40, 0x0e14128b, 0x6f5942e6, 0x8b3a0f03, 0x3c5d16b9, 0x7f7e3743, 0x4f4c54e4, 0x0ea0a9e9, 0x9e59dbe6, 0x6e7ddcd3, 0xcec08377, 0x9ba759f8, 0x2ea5046e, 0x0e24c569, 0xb8979780, 0x4e31b98c, 0x4efe4f46, 0x4ea7c762, 0x7e61c9c6, 0x6e30c880, 0x1ada0c25, 0x4e603a2f, 0xda9d7218, 0x0d40c5d9, 0x5e214b05, 0x9ba9efc5, 0x5e61b81e, 0x6e7bc31c, 0x0e61a163, 0x9e5832d2, 0x4e772248, 0x4e3d17c8, 0x92624f60, 0x7a1a02dc, 0x79891f65, 0x6eb45036, 0x0e321ee8, 0x4e2566f0, 0x4ea02b9b, 0x0f9dcb3d, 0x2e21b9f9, 0x0e21a8c3, 0xda1700bd, 0x6ea0fb38, 0x7e607a0b, 0x72845817, 0x7f61068e, 0x0d60e529, 0x4ea0ca5c, 0x1a94b20f, 0x8b87419d, 0x7ea9ed71, 0x2ea1a86e, 0x4d40c4da, 0x5ea0eada, 0x784ba96e, 0x7eb6ee02, 0x3db1c710, 0x0e217836, 0x7ee0bb96, 0x4e786c08, 0x4e976a08, 0x489ffe86, 0x4e79fc9b, 0x0e21cbce, 0x5ef7fc65, 0x4ea1286d, 0xd29c771e, 0x6f5c2839, 0x0ea00a9d, 0x6ee44c06, 0x5ee1d858, 0x5ef2fda6, 0x7eb0c9fe, 0x7f762791, 0x2e212ae6, 0x4e61c9db, 0x13003c57, 0x5ee1b8f8, 0x0f2396d2, 0x6ea0db1e, 0x0e71ba82, 0xab29c807, 0x6ef8f8b3, 0x1f18d4a1, 0x0e261d15, 0x1e290081, 0x1b0c7d12, 0x4e7771c3, 0xf845f1e4, 0x4d40c9e8, 0xce778452, 0x6eb9879d, 0x6e21c93d, 0xcec0829f, 0x52a0969f, 0x1e772b4f, 0x7ee1da88, 0x5f52fe0a, 0x7f3387b1, 0x5e214850, 0x1e65c025, 0x0e2ca294, 0x2e614829, 0x1e640077, 0x9e240048, 0x4ebe9537, 0x9bb7925e, 0x38b669c5, 0x2840d089, 0x6f43e648, 0x2e662d28, 0x4eabaff3, 0x6e734cc7, 0x0e31baee, 0x7ee0d93c, 0x5e282bde, 0x7e21bba4, 0x4e6c75fa, 0x5ac01217, 0x7f4304af, 0x1e7878ed, 0x1ada2196, 0x7ee1aba3, 0x93407f3c, 0x4f6c34eb, 0x6e3447a9, 0x7e7ae545, 0x5e0802bb, 0x6eeae63a, 0x7ee1da62, 0x5e280bb3, 0xf81d4009, 0x1e603b21, 0x5e281a14, 0x6eb0a99b, 0x1e266a25, 0x0d60cafe, 0x0e0b6194, 0x7a4ed2c5, 0x92b762ec, 0x4e6b5749, 0x3c16a6e5, 0x4ea0a92b, 0x0fa58b6a, 0x5f76148c, 0x6e30c95f, 0x1e6540fd, 0x5e28e40f, 0x0d403fd4, 0x7e30da36, 0x7fda9b51, 0x2ea04bde, 0x1e25c3d2, 0x1ee0434c, 0x5e21d8e7, 0x5ee1ba51, 0x5e61aba9, 0x4e2849fb, 0x5ee098ea, 0x4e60f63d, 0x0f280443, 0x5ee0da27, 0x2e78a6ce, 0x78054afc, 0x4e14286b, 0x4e218bd8, 0x2a3d2551, 0x3a04017a, 0x5f4317cd, 0x0e604a37, 0x9a834614, 0x0e2edf4d, 0x7a51a0a0, 0x5f8e9043, 0x6ea06bb2, 0xaa2857dd, 0x7a1903fc, 0x301ba9ba, 0x9ac929cd, 0x4e061ff0, 0x2e38fcfc, 0x0e2f614a, 0x7ee0d8e4, 0x6e73afda, 0x7f4156f7, 0x0e6078bf, 0x4ee1d9ed, 0x93403fbe, 0xce6f8640, 0x4e3855e3, 0x6f76fe23, 0x112466e8, 0x1e358a90, 0x7f45272c, 0x6ea19a9d, 0x8a696350, 0x1e3900f6, 0x5e61c866, 0x0e3fbfd0, 0x5ee09ad0, 0x0e651d27, 0x4dffc35e, 0x2e20c6ce, 0x0fbe118d, 0x1e656a15, 0xd1357365, 0x0e20a847, 0xce4a835c, 0x4e203905, 0x2e60090d, 0x7f4a27bb, 0x1e64c316, 0xce7d86a4, 0x7ebded2d, 0x6e70a97e, 0x4eb9a42b, 0x0e209bef, 0x6f151730, 0x0e7e30f7, 0x4e724509, 0xd503375f, 0xce58b6ae, 0x5e21a9b8, 0xcb2ca538, 0x5ac01131, 0x6ea19a24, 0xeb40c8b3, 0xc8df7d65, 0x78108341, 0x3218ab9b, 0x0f3da7dd, 0x2e003089, 0x4e21cab5, 0x8aa5c924, 0x1a94950c, 0x123e506f, 0x13117e37, 0x1ee6005b, 0x5ac00647, 0x5eec8cd5, 0x7ef0fb3d, 0x9223272a, 0x5ee0cb02, 0x6e66071d, 0x6ea1dbbf, 0x5e61c903, 0x5ac015ea, 0x93db6206, 0x7e62b5e3, 0x6ea0c87b, 0xdac0090e, 0x48df7d90, 0x6e206ba5, 0x9e2503c2, 0x6e25fc89, 0x4d60e2db, 0x1e3e22a0, 0x2eb81c19, 0x7856ea00, 0x5fbfb22d, 0x1e630244, 0x4e202a83, 0x1f50a722, 0x7f7b55d2, 0x0fae89b9, 0x4e781d73, 0xce738c3a, 0x4f15a591, 0x6e21c7e1, 0x586ff77e, 0x8a5d3592, 0x93401c67, 0x5e61cb86, 0xce6bc2c1, 0x6e393f10, 0x9bb70ec3, 0xdac0098c, 0x4da84b95, 0x7f494476, 0x9ace5c11, 0x7e61ca14, 0x4f7a60ef, 0x1ad32b39, 0x0ea3777f, 0x5e61da7f, 0x4f1404e2, 0x4e3244e2, 0x6e1b1ceb, 0x0dee5aac, 0x4e2f9dc4, 0x5ea1b8c3, 0x1e59f863, 0xd500403f, 0x4e3ae7d0, 0x4ef5c6ea, 0x08dffe3b, 0x6e36f4f6, 0x2e764f29, 0x0e726f23, 0x5f42375b, 0x7f71fc40, 0x6e618aad, 0x93403e5b, 0x0e205976, 0x0e7250c4, 0x6eb0abc9, 0x2e2049f0, 0x5f14754d, 0x7f6ce468, 0x6f950bbe, 0x6e31aa47, 0x4eb83396, 0x0dccc952, 0x2ea1ca90, 0xce69c701, 0xb0bed69e, 0x7c5dec39, 0x4e2868a2, 0x0e591b08, 0x5f34e6dd, 0x3a449184, 0x5e3ce6de, 0x4ea149b7, 0x4e7ad29b, 0xba198503, 0x1f683e8f, 0xfa52f2a7, 0x6e30dffc, 0x4e6c3d17, 0x2eae3248, 0xd503349f, 0x1e60002c, 0x0f180680, 0x9e240049, 0x6f75774e, 0xa90d8678, 0x9ad924c4, 0x7eb0f85b, 0x0e205aaf, 0x7ee08899, 0x5f4bffd8, 0x1b0ff5f3, 0x4ee11dcd, 0x2e218948, 0x0dcb2733, 0x4eac107c, 0x4ea04a53, 0x4e287b44, 0x0e60b82a, 0x5ee0ebbc, 0xce454ff1, 0x5e1761e7, 0x5e09202f, 0x0e0c0754, 0x1e72e6b9, 0x7e21da70, 0x0fbdb20c, 0x5efb8c84, 0xd500401f, 0x3a47526e, 0x1e680acf, 0x7f7375fc, 0xf80522da, 0x4ee60c02, 0x4d40c2e7, 0x6f89096b, 0x7ee1bb6e, 0x5e280b4a, 0x1e3120c8, 0x7eb2ef96, 0x4fd012dd, 0x0f3027ef, 0x4e2078a8, 0xd503201f, 0x2e2312d9, 0x6ebf1c6e, 0x5ee1f8df, 0x4e607a46, 0x6e30c877, 0x6c09d2d1, 0x4e61abd8, 0x0e35267e, 0x6ac17728, 0x0e861aa0, 0x6f63fe26, 0x6f157628, 0x6f30a5f9, 0x4d60cc0c, 0x4e21cb59, 0x2e68a3fb, 0x7efae601, 0x6ea0f82c, 0x9b25ec12, 0x1a1a0305, 0x0e043fe1, 0x6e73c0ed, 0x6ea1b8c0, 0x7e20380b, 0x0f0534e8, 0x1f56bc7d, 0xba0c0128, 0x1e672160, 0x6e7b259b, 0x7ee07b5d, 0x9a820443, 0x4e040581, 0x2f1d87e8, 0x1acd2f5b, 0x6e20794f, 0x2e6a3c93, 0xc8dffe13, 0xce5ab1c6, 0x6eea55f6, 0x4ea039b3, 0x0d602fec, 0x2e246e2f, 0x7857be39, 0xb80608fb, 0x1e67c017, 0x9bcf7f63, 0x0f92d857, 0x5e0812f7, 0x1e210172, 0x7e6128e9, 0x7ea94d41, 0x981179e1, 0x1effb018, 0x2e600828, 0x0eb9c6b2, 0x6ee1baae, 0x4ea0db28, 0x2ea1487b, 0x4ea6c7f0, 0x2e2374c7, 0x7e30d8dd, 0xb9991fa7, 0x4e791e3e, 0x889f7c4b, 0x0e6c753c, 0x1e740ad1, 0x1e244324, 0x1ef33010, 0x5ac01102, 0x9bd97fba, 0x6e290143, 0x1e2220d8, 0x4d8d5aee, 0x6f28570b, 0xfa4ab0c1, 0xdac00b14, 0x7ea1a90e, 0x2e3027d8, 0x6f25a733, 0x4e61a96e, 0x4e1a2fcb, 0x0e22fe0a, 0xc8df7cd0, 0x5e280a55, 0x4e012b20, 0x7e70dbf4, 0x520c5a4e, 0x6ea6c57f, 0x0e861af8, 0xd503233f, 0x889ffe3c, 0x5e274ea9, 0x4e21a89a, 0x0e170c02, 0x6efd4c0b, 0xd5033ebf, 0x6e61a92c, 0x2e205b72, 0x789fb828, 0x0e626e94, 0x2ea6724c, 0x9a10028b, 0x2c6c51fc, 0x5a9de6b9, 0x6e6881f3, 0x5ee0ea6b, 0x0faec36e, 0x0e955bca, 0x1acf206d, 0x7f6f571b, 0x4e286930, 0x12b41ceb, 0x1e770b7a, 0x0ea18ac2, 0x5e282aaf, 0xf2b7fa1e, 0x1ac34311, 0x13167d11, 0x4ea63412, 0x6e758038, 0x2f1d85d6, 0x0f275480, 0x0ead6c71, 0x6e204b69, 0x1e6303f4, 0x5e0031ef, 0x13001e40, 0x7a16006f, 0x6e6ae4c0, 0x0f0f242f, 0x6e674f50, 0x4e606b7a, 0x7e6ee684, 0x1e6b5957, 0x7ea1bbab, 0x7ea0b6cb, 0xce4da241, 0x0ea1b953, 0x0eb2af4b, 0x9ac309d0, 0x6e61d8bd, 0x5ea0d890, 0x5f47d1e7, 0xfa5981ca, 0x1e7f7959, 0x6ef24dd8, 0x0e0a41d1, 0x5ee0e898, 0x4e6038e2, 0x13097d65, 0x6f839088, 0x9e290265, 0x0e208824, 0x2e65af79, 0x6f36a561, 0x9ad3204b, 0x0e21482e, 0x1e24431d, 0xd50330bf, 0x0df641aa, 0x6e602a83, 0xce30505f, 0x5e025238, 0xd503201f, 0x4e608880, 0x4de9c38d, 0x5e0f5348, 0x6eb48ca9, 0x50fda31b, 0x2e251eec, 0x7842ba50, 0xd8a1cd86, 0x2ea09862, 0x0ea09983, 0x2ea333b0, 0x0ea6032c, 0x4f94801b, 0x7e3ee57d, 0x38135e4f, 0xd8fdd9dd, 0x5ee0fcde, 0x9e64033d, 0x6e37f547, 0x6e3dd7ef, 0x13003f3d, 0x0e602f9f, 0x4e7ad014, 0x9b3b6857, 0x5ea0cb67, 0x0eb31c9f, 0x4e7c5372, 0x5e61b8c0, 0x0ea19b23, 0x0ee6e1df, 0x6e63a626, 0x2f139405, 0x7eb0f96d, 0x9e588c63, 0x2e714c3a, 0x6e8c941e, 0x0f61b331, 0x6f01f625, 0x4e78d4ea, 0x6f403709, 0x1a0300da, 0xda0102c8, 0x7e61d9fd, 0xb89469bb, 0x0c838780, 0x2e60a590, 0x4dfd29e1, 0x4e150f2e, 0xce2810bc, 0x5f541591, 0x9ee60259, 0x2eb40e56, 0x5e014027, 0x2ef71faf, 0x4e2d452f, 0x5ee0a813, 0x4eb03301, 0x38443acf, 0x6eabd502, 0x0e2ee71e, 0x5a960364, 0xce7ec596, 0x7efbed09, 0x4ef42ea2, 0x0eb30ea5, 0x5ee0d9f8, 0x6f513552, 0xf89eb3fa, 0x7ea2eca6, 0x9b00cc19, 0xf897409e, 0x1e73485f, 0x381afa77, 0x0f169f3b, 0x5ee1aa70, 0x5e1803ee, 0x0dbf5a4c, 0xce78c7a6, 0x9b0b260c, 0x2ef8fa19, 0x6e70aa4b, 0xce45b805, 0x2ea08e86, 0x4ee0bafd, 0x2ea09a1f, 0x4e218900, 0x6e744f13, 0xce518653, 0xf81b7a68, 0xce45ac5e, 0x7e62e416, 0x1a1b02b6, 0x7e21db48, 0x381daaaf, 0x6b2c0987, 0x0e2ec651, 0x4eae8502, 0x9bde7ca0, 0x6f47201f, 0x7e61a8a3, 0x6e60d5db, 0x4e2879de, 0xf81d194e, 0x4f1b8d05, 0x4d0048b2, 0x6e203be9, 0x4e3e7eb1, 0x0e260ef8, 0x2e688518, 0x7e3fec46, 0xdac00843, 0xf85c8917, 0x2e212a0f, 0x0e8196da, 0xd503359f, 0xce4c81f2, 0x6ee19992, 0x6e21ca79, 0x4d40c1d2, 0x4f5816ef, 0x4e34c3ea, 0x4df7c283, 0x7ef7eeb6, 0x18e276ce, 0xab0d21c0, 0xd5032f7f, 0x4ea00dbf, 0x5ac01251, 0xd0121955, 0x7f1495e4, 0x7ef0fa11, 0x5e24dd9c, 0x9add25b5, 0x0eb2bdef, 0x9e1977c7, 0x6f4b26bd, 0x0e200a9c, 0x9b4f7c00, 0x0ea0392e, 0x7e212a2c, 0x0b248b90, 0x1acc27a1, 0x2e701c90, 0x5ee1b870, 0x5e280aba, 0x5ea0780e, 0x1e264246, 0x4e052d04, 0x0e731dc4, 0xce461997, 0x9a9e9413, 0x3d462048, 0x5ea1fac5, 0x2ea0c8c4, 0x9a030280, 0x2ebda4b8, 0x5eef8614, 0x6eadc4e0, 0xbd035a8f, 0x4e606b84, 0x4eb1aba1, 0x4e286928, 0x4e2858cc, 0x9add0ce9, 0x4e070d65, 0x5fd399d5, 0x0f03fde7, 0x6ee90c74, 0x4ef8e31e, 0x381d986a, 0x5ea0ebf4, 0x5ea0d87e, 0x2e76ac9e, 0x6eb36cd4, 0x2e6e1c4c, 0x2e2feebc, 0x1ace4b03, 0x5ee0db12, 0x5ea0e9b1, 0x2e1c32d5, 0x5fa49a09, 0x0e258737, 0x7e21ca8e, 0xce4f9988, 0x5f7f56a6, 0x0e739766, 0x4e28586c, 0x6e619908, 0xd500401f, 0xf88b9252, 0x6e251c8e, 0x9e20015b, 0x7f1486b9, 0x717c339b, 0x1f31ff70, 0x4ea0eb62, 0x9acb0926, 0x489f7d85, 0x4e209b54, 0x2e84cf03, 0x2e65946c, 0x0e7d80cd, 0xc8dffecc, 0xce668bd8, 0x6e2188af, 0xeb4ada34, 0x2b25ec33, 0x0d40e6e7, 0x4eb2c757, 0x4ec82ad0, 0x7e21cb0a, 0x0e21a847, 0x4e0b1ec0, 0x381e6ac0, 0x6e61c8f5, 0x0f10071c, 0x2ee21daa, 0x5e61ab31, 0x6e218892, 0x2e7e7cb5, 0x6f2826aa, 0x7f6b54df, 0x4eaa2620, 0xdac00034, 0x4f6477be, 0x7e6148ea, 0x4eef1f57, 0x78459aeb, 0x2ebc3f10, 0x2e35f4eb, 0x4fbf19ce, 0xd8d0e58e, 0x2e21bbc7, 0x6ee0cab6, 0x9bc57e3f, 0x2f854037, 0x4e92181c, 0x6e6d1f89, 0x0f305545, 0x4ee19a57, 0x0e887bdf, 0x5e1a4185, 0x7ef0c821, 0x2eb6607c, 0x2ea0d9b8, 0x9e0380f4, 0x2ebf1c83, 0x1e62597d, 0x7f6e2548, 0x5ac00205, 0x4e616adb, 0xce638b8c, 0x5e1653cf, 0x2e6069be, 0x0e2ac641, 0x1e33c76f, 0xce44956d, 0x9bb90d31, 0x1e24c20a, 0x7ee038c1, 0x93407e5e, 0x4e280127, 0xc8df7f7d, 0xba42f263, 0x1e6f199c, 0x6e212889, 0x6e92f60e, 0x6ebdc499, 0x8b9acbf8, 0x4d40c581, 0x3a020250, 0x6e6a6716, 0x9248403b, 0x9081ffea, 0x4e603856, 0x9ad1242b, 0x6f270579, 0x1a070349, 0xcec08133, 0xd503305f, 0x5a1a00ca, 0x2e60b8a2, 0x0e5f28fd, 0x0e31a3da, 0x7e61cbc1, 0xd503399f, 0x5f5e54aa, 0x0eb8bdea, 0x4eba8f10, 0x4e2a2e60, 0x2f3da7d6, 0x1e58e297, 0x6e71aa3e, 0x6b86701a, 0xce4fa5e6, 0x4ee7c463, 0x8a79307f, 0x0ebea541, 0x2e218af4, 0x4e774f8a, 0xb9b95dc5, 0x6e61abd5, 0x4dd1e814, 0x4da72098, 0x98307582, 0x3a512101, 0x7ef95497, 0x1ace5535, 0x5a0c0349, 0x4e28581b, 0x6ebf1c02, 0x5ea1da23, 0x1e274314, 0x5e25dd29, 0x6e75f594, 0x6eaf6ed5, 0x4e214abe, 0x4e064172, 0x2e21c8f4, 0xf84c5b08, 0x1e244312, 0x14000000}; env.code_mem.emplace_back(0x14000000); // B . @@ -1596,7 +1696,9 @@ TEST_CASE("A64: rand2", "[a64][.]") { TEST_CASE("A64: SABD", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SABD(V0.B16(), V3.B16(), V4.B16()); @@ -1654,7 +1756,9 @@ TEST_CASE("A64: SABD", "[a64]") { TEST_CASE("A64: UZP{1,2}.2D", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.D2(), V0.D2(), V1.D2()); @@ -1673,7 +1777,9 @@ TEST_CASE("A64: UZP{1,2}.2D", "[a64]") { TEST_CASE("A64: UZP{1,2}.S", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.S2(), V0.S2(), V1.S2()); @@ -1696,7 +1802,9 @@ TEST_CASE("A64: UZP{1,2}.S", "[a64]") { TEST_CASE("A64: UZP{1,2}.H", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.H4(), V0.H4(), V1.H4()); @@ -1719,7 +1827,9 @@ TEST_CASE("A64: UZP{1,2}.H", "[a64]") { TEST_CASE("A64: UZP{1,2}.B", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.UZP1(V2.B8(), V0.B8(), V1.B8()); @@ -1742,7 +1852,9 @@ TEST_CASE("A64: UZP{1,2}.B", "[a64]") { TEST_CASE("A64: {S,U}MIN.S, {S,U}MAX.S", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMIN(V2.S4(), V0.S4(), V1.S4()); @@ -1786,7 +1898,9 @@ TEST_CASE("A64: {S,U}MIN.S, {S,U}MAX.S", "[a64]") { TEST_CASE("A64: {S,U}MIN.H, {S,U}MAX.H", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMIN(V2.H8(), V0.H8(), V1.H8()); @@ -1830,7 +1944,9 @@ TEST_CASE("A64: {S,U}MIN.H, {S,U}MAX.H", "[a64]") { TEST_CASE("A64: {S,U}MIN.B, {S,U}MAX.B", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMIN(V2.B16(), V0.B16(), V1.B16()); @@ -1874,7 +1990,9 @@ TEST_CASE("A64: {S,U}MIN.B, {S,U}MAX.B", "[a64]") { TEST_CASE("A64: {S,U}MINP.S, {S,U}MAXP.S", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMINP(V2.S2(), V0.S2(), V1.S2()); @@ -1942,7 +2060,9 @@ TEST_CASE("A64: {S,U}MINP.S, {S,U}MAXP.S", "[a64]") { TEST_CASE("A64: {S,U}MINP.H, {S,U}MAXP.H", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMINP(V2.H4(), V0.H4(), V1.H4()); @@ -2010,7 +2130,9 @@ TEST_CASE("A64: {S,U}MINP.H, {S,U}MAXP.H", "[a64]") { TEST_CASE("A64: {S,U}MINP.B, {S,U}MAXP.B", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; code.SMINP(V2.B8(), V0.B8(), V1.B8()); @@ -2084,7 +2206,9 @@ TEST_CASE("A64: {S,U}MINP.B, {S,U}MAXP.B", "[a64]") { TEST_CASE("A64: SQABS", "[a64]") { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; // should set QC flag diff --git a/externals/dynarmic/tests/A64/fp_min_max.cpp b/externals/dynarmic/tests/A64/fp_min_max.cpp index 7aa1ef4407..a857005d15 100644 --- a/externals/dynarmic/tests/A64/fp_min_max.cpp +++ b/externals/dynarmic/tests/A64/fp_min_max.cpp @@ -64,7 +64,9 @@ u32 force_default_nan(u32 value) { template void run_test(u32 instruction, Fn fn) { A64TestEnv env; - A64::Jit jit{A64::UserConfig{&env}}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; env.code_mem.emplace_back(instruction); // FMAX S0, S1, S2 env.code_mem.emplace_back(0x14000000); // B . diff --git a/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp b/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp index 1a56a982ef..27d014f71e 100644 --- a/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp +++ b/externals/dynarmic/tests/A64/fuzz_with_unicorn.cpp @@ -154,7 +154,8 @@ static u32 GenFloatInst(u64 pc, bool is_last_inst) { } static Dynarmic::A64::UserConfig GetUserConfig(A64TestEnv& jit_env) { - Dynarmic::A64::UserConfig jit_user_config{&jit_env}; + Dynarmic::A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &jit_env; jit_user_config.optimizations &= ~OptimizationFlag::FastDispatch; // The below corresponds to the settings for qemu's aarch64_max_initfn jit_user_config.dczid_el0 = 7; diff --git a/externals/dynarmic/tests/A64/misaligned_page_table.cpp b/externals/dynarmic/tests/A64/misaligned_page_table.cpp index f54aa58641..75ac41e06d 100644 --- a/externals/dynarmic/tests/A64/misaligned_page_table.cpp +++ b/externals/dynarmic/tests/A64/misaligned_page_table.cpp @@ -10,7 +10,8 @@ TEST_CASE("misaligned load/store do not use page_table when detect_misaligned_access_via_page_table is set", "[a64]") { A64TestEnv env; - Dynarmic::A64::UserConfig conf{&env}; + Dynarmic::A64::UserConfig conf{}; + conf.callbacks = &env; conf.page_table = nullptr; conf.detect_misaligned_access_via_page_table = 128; conf.only_detect_misalignment_via_page_table_on_page_boundary = true; diff --git a/externals/dynarmic/tests/A64/test_invalidation.cpp b/externals/dynarmic/tests/A64/test_invalidation.cpp index fa35b02b7f..cba47dd8ca 100644 --- a/externals/dynarmic/tests/A64/test_invalidation.cpp +++ b/externals/dynarmic/tests/A64/test_invalidation.cpp @@ -12,8 +12,8 @@ using namespace Dynarmic; TEST_CASE("ensure fast dispatch entry is cleared even when a block does not have any patching requirements", "[a64]") { A64TestEnv env; - - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; A64::Jit jit{conf}; REQUIRE(conf.HasOptimization(OptimizationFlag::FastDispatch)); @@ -64,8 +64,8 @@ TEST_CASE("ensure fast dispatch entry is cleared even when a block does not have TEST_CASE("ensure fast dispatch entry is cleared even when a block does not have any patching requirements 2", "[a64]") { A64TestEnv env; - - A64::UserConfig conf{&env}; + A64::UserConfig conf{}; + conf.callbacks = &env; A64::Jit jit{conf}; REQUIRE(conf.HasOptimization(OptimizationFlag::FastDispatch)); diff --git a/externals/dynarmic/tests/test_generator.cpp b/externals/dynarmic/tests/test_generator.cpp index cfdd8ea436..450d3e3fc4 100644 --- a/externals/dynarmic/tests/test_generator.cpp +++ b/externals/dynarmic/tests/test_generator.cpp @@ -23,6 +23,7 @@ #include "./rand_int.h" #include "dynarmic/common/fp/fpcr.h" #include "dynarmic/common/fp/fpsr.h" +#include "dynarmic/common/llvm_disassemble.h" #include "dynarmic/frontend/A32/ITState.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h" #include "dynarmic/frontend/A32/a32_types.h" @@ -396,39 +397,41 @@ Dynarmic::A32::UserConfig GetA32UserConfig(TestEnv& testenv, bool noopt) { template void RunTestInstance(Dynarmic::A32::Jit& jit, - TestEnv& jit_env, - const std::array& regs, - const std::array& vecs, - const std::vector& instructions, - const u32 cpsr, - const u32 fpscr, - const size_t ticks_left) { + TestEnv& jit_env, + const std::array& regs, + const std::array& vecs, + const std::vector& instructions, + const u32 cpsr, + const u32 fpscr, + const size_t ticks_left, + const bool show_disas) { const u32 initial_pc = regs[15]; const u32 num_words = initial_pc / sizeof(typename TestEnv::InstructionType); const u32 code_mem_size = num_words + static_cast(instructions.size()); - fmt::print("instructions:"); - for (auto instruction : instructions) { - if constexpr (sizeof(decltype(instruction)) == 2) { - fmt::print(" {:04x}", instruction); - } else { - fmt::print(" {:08x}", instruction); + if (show_disas) { + fmt::print("instructions:\n"); + auto current_pc = initial_pc; + for (auto instruction : instructions) { + if constexpr (sizeof(decltype(instruction)) == 2) { + fmt::print("{:04x} ?\n", instruction); + } else { + fmt::print("{}", Dynarmic::Common::DisassembleAArch64(instruction, current_pc)); + } + current_pc += sizeof(decltype(instruction)); } - } - fmt::print("\n"); - fmt::print("initial_regs:"); - for (u32 i : regs) { - fmt::print(" {:08x}", i); + fmt::print("initial_regs:"); + for (u32 i : regs) + fmt::print(" {:08x}", i); + fmt::print("\n"); + fmt::print("initial_vecs:"); + for (u32 i : vecs) + fmt::print(" {:08x}", i); + fmt::print("\n"); + fmt::print("initial_cpsr: {:08x}\n", cpsr); + fmt::print("initial_fpcr: {:08x}\n", fpscr); } - fmt::print("\n"); - fmt::print("initial_vecs:"); - for (u32 i : vecs) { - fmt::print(" {:08x}", i); - } - fmt::print("\n"); - fmt::print("initial_cpsr: {:08x}\n", cpsr); - fmt::print("initial_fpcr: {:08x}\n", fpscr); jit.ClearCache(); @@ -450,36 +453,37 @@ void RunTestInstance(Dynarmic::A32::Jit& jit, jit.Run(); } - fmt::print("final_regs:"); - for (u32 i : jit.Regs()) { - fmt::print(" {:08x}", i); + if (show_disas) { + fmt::print("final_regs:"); + for (u32 i : jit.Regs()) { + fmt::print(" {:08x}", i); + } + fmt::print("\n"); + fmt::print("final_vecs:"); + for (u32 i : jit.ExtRegs()) { + fmt::print(" {:08x}", i); + } + fmt::print("\n"); + fmt::print("final_cpsr: {:08x}\n", jit.Cpsr()); + fmt::print("final_fpsr: {:08x}\n", mask_fpsr_cum_bits ? jit.Fpscr() & 0xffffff00 : jit.Fpscr()); + fmt::print("mod_mem: "); + for (auto [addr, value] : jit_env.modified_memory) { + fmt::print("{:08x}:{:02x} ", addr, value); + } + fmt::print("\n"); + fmt::print("interrupts:\n"); + for (const auto& i : jit_env.interrupts) { + std::puts(i.c_str()); + } + fmt::print("===\n"); + jit.DumpDisassembly(); } - fmt::print("\n"); - fmt::print("final_vecs:"); - for (u32 i : jit.ExtRegs()) { - fmt::print(" {:08x}", i); - } - fmt::print("\n"); - fmt::print("final_cpsr: {:08x}\n", jit.Cpsr()); - fmt::print("final_fpsr: {:08x}\n", mask_fpsr_cum_bits ? jit.Fpscr() & 0xffffff00 : jit.Fpscr()); - - fmt::print("mod_mem: "); - for (auto [addr, value] : jit_env.modified_memory) { - fmt::print("{:08x}:{:02x} ", addr, value); - } - fmt::print("\n"); - - fmt::print("interrupts:\n"); - for (const auto& i : jit_env.interrupts) { - std::puts(i.c_str()); - } - - fmt::print("===\n"); } Dynarmic::A64::UserConfig GetA64UserConfig(A64TestEnv& jit_env, bool noopt) { - Dynarmic::A64::UserConfig jit_user_config{&jit_env}; - jit_user_config.optimizations &= ~OptimizationFlag::FastDispatch; + Dynarmic::A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &jit_env; + jit_user_config.optimizations = all_safe_optimizations; // The below corresponds to the settings for qemu's aarch64_max_initfn jit_user_config.dczid_el0 = 7; jit_user_config.ctr_el0 = 0x80038003; @@ -491,15 +495,16 @@ Dynarmic::A64::UserConfig GetA64UserConfig(A64TestEnv& jit_env, bool noopt) { template void RunTestInstance(Dynarmic::A64::Jit& jit, - A64TestEnv& jit_env, - const std::array& regs, - const std::array, 32>& vecs, - const std::vector& instructions, - const u32 pstate, - const u32 fpcr, - const u64 initial_sp, - const u64 start_address, - const size_t ticks_left) { + A64TestEnv& jit_env, + const std::array& regs, + const std::array, 32>& vecs, + const std::vector& instructions, + const u32 pstate, + const u32 fpcr, + const u64 initial_sp, + const u64 start_address, + const size_t ticks_left, + const bool show_disas) { jit.ClearCache(); for (size_t jit_rerun_count = 0; jit_rerun_count < num_jit_reruns; ++jit_rerun_count) { @@ -522,59 +527,53 @@ void RunTestInstance(Dynarmic::A64::Jit& jit, jit.Run(); } - fmt::print("instructions:"); - for (u32 instruction : instructions) { - fmt::print(" {:08x}", instruction); - } - fmt::print("\n"); + if (show_disas) { + fmt::print("instructions:\n"); + auto current_pc = start_address; + for (u32 instruction : instructions) { + fmt::print("{}", Dynarmic::Common::DisassembleAArch64(instruction, current_pc)); + current_pc += 4; + } - fmt::print("initial_regs:"); - for (u64 i : regs) { - fmt::print(" {:016x}", i); + fmt::print("initial_regs:"); + for (u64 i : regs) + fmt::print(" {:016x}", i); + fmt::print("\n"); + fmt::print("initial_vecs:"); + for (auto i : vecs) + fmt::print(" {:016x}:{:016x}", i[0], i[1]); + fmt::print("\n"); + fmt::print("initial_sp: {:016x}\n", initial_sp); + fmt::print("initial_pstate: {:08x}\n", pstate); + fmt::print("initial_fpcr: {:08x}\n", fpcr); + fmt::print("final_regs:"); + for (u64 i : jit.GetRegisters()) + fmt::print(" {:016x}", i); + fmt::print("\n"); + fmt::print("final_vecs:"); + for (auto i : jit.GetVectors()) + fmt::print(" {:016x}:{:016x}", i[0], i[1]); + fmt::print("\n"); + fmt::print("final_sp: {:016x}\n", jit.GetSP()); + fmt::print("final_pc: {:016x}\n", jit.GetPC()); + fmt::print("final_pstate: {:08x}\n", jit.GetPstate()); + fmt::print("final_fpcr: {:08x}\n", jit.GetFpcr()); + fmt::print("final_qc : {}\n", FP::FPSR{jit.GetFpsr()}.QC()); + fmt::print("mod_mem:"); + for (auto [addr, value] : jit_env.modified_memory) + fmt::print(" {:08x}:{:02x}", addr, value); + fmt::print("\n"); + fmt::print("interrupts:\n"); + for (const auto& i : jit_env.interrupts) + std::puts(i.c_str()); + fmt::print("===\n"); + jit.DumpDisassembly(); } - fmt::print("\n"); - fmt::print("initial_vecs:"); - for (auto i : vecs) { - fmt::print(" {:016x}:{:016x}", i[0], i[1]); - } - fmt::print("\n"); - fmt::print("initial_sp: {:016x}\n", initial_sp); - fmt::print("initial_pstate: {:08x}\n", pstate); - fmt::print("initial_fpcr: {:08x}\n", fpcr); - - fmt::print("final_regs:"); - for (u64 i : jit.GetRegisters()) { - fmt::print(" {:016x}", i); - } - fmt::print("\n"); - fmt::print("final_vecs:"); - for (auto i : jit.GetVectors()) { - fmt::print(" {:016x}:{:016x}", i[0], i[1]); - } - fmt::print("\n"); - fmt::print("final_sp: {:016x}\n", jit.GetSP()); - fmt::print("final_pc: {:016x}\n", jit.GetPC()); - fmt::print("final_pstate: {:08x}\n", jit.GetPstate()); - fmt::print("final_fpcr: {:08x}\n", jit.GetFpcr()); - fmt::print("final_qc : {}\n", FP::FPSR{jit.GetFpsr()}.QC()); - - fmt::print("mod_mem:"); - for (auto [addr, value] : jit_env.modified_memory) { - fmt::print(" {:08x}:{:02x}", addr, value); - } - fmt::print("\n"); - - fmt::print("interrupts:\n"); - for (const auto& i : jit_env.interrupts) { - std::puts(i.c_str()); - } - - fmt::print("===\n"); } } // Anonymous namespace -void TestThumb(size_t num_instructions, size_t num_iterations, bool noopt) { +void TestThumb(size_t num_instructions, size_t num_iterations, bool noopt, bool show_disas) { ThumbTestEnv jit_env{}; Dynarmic::A32::Jit jit{GetA32UserConfig(jit_env, noopt)}; @@ -597,11 +596,11 @@ void TestThumb(size_t num_instructions, size_t num_iterations, bool noopt) { } regs[15] = start_address; - RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions); + RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions, show_disas); } } -void TestArm(size_t num_instructions, size_t num_iterations, bool noopt) { +void TestArm(size_t num_instructions, size_t num_iterations, bool noopt, bool show_disas) { ArmTestEnv jit_env{}; Dynarmic::A32::Jit jit{GetA32UserConfig(jit_env, noopt)}; @@ -623,11 +622,11 @@ void TestArm(size_t num_instructions, size_t num_iterations, bool noopt) { } regs[15] = start_address; - RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions); + RunTestInstance(jit, jit_env, regs, ext_reg, instructions, cpsr, fpcr, num_instructions, show_disas); } } -void TestA64(size_t num_instructions, size_t num_iterations, bool noopt) { +void TestA64(size_t num_instructions, size_t num_iterations, bool noopt, bool show_disas) { A64TestEnv jit_env{}; Dynarmic::A64::Jit jit{GetA64UserConfig(jit_env, noopt)}; @@ -649,7 +648,7 @@ void TestA64(size_t num_instructions, size_t num_iterations, bool noopt) { instructions.emplace_back(GenRandomA64Inst(static_cast(start_address + 4 * instructions.size()), i == num_instructions - 1)); } - RunTestInstance(jit, jit_env, regs, vecs, instructions, pstate, fpcr, initial_sp, start_address, num_instructions); + RunTestInstance(jit, jit_env, regs, vecs, instructions, pstate, fpcr, initial_sp, start_address, num_instructions, show_disas); } } @@ -677,6 +676,7 @@ int main(int argc, char* argv[]) { const auto instruction_count = str2sz(argv[3]); const auto iterator_count = str2sz(argv[4]); const bool noopt = argc == 6 && (strcmp(argv[5], "noopt") == 0); + const bool show_disas = argc == 6 && (strcmp(argv[5], "disas") == 0); if (!seed || !instruction_count || !iterator_count) { fmt::print("invalid numeric arguments\n"); @@ -686,11 +686,11 @@ int main(int argc, char* argv[]) { detail::g_rand_int_generator.seed(static_cast(*seed)); if (strcmp(argv[1], "thumb") == 0) { - TestThumb(*instruction_count, *iterator_count, noopt); + TestThumb(*instruction_count, *iterator_count, noopt, show_disas); } else if (strcmp(argv[1], "arm") == 0) { - TestArm(*instruction_count, *iterator_count, noopt); + TestArm(*instruction_count, *iterator_count, noopt, show_disas); } else if (strcmp(argv[1], "a64") == 0) { - TestA64(*instruction_count, *iterator_count, noopt); + TestA64(*instruction_count, *iterator_count, noopt, show_disas); } else { fmt::print("unrecognized instruction class\n"); return 1; diff --git a/externals/dynarmic/tests/test_reader.cpp b/externals/dynarmic/tests/test_reader.cpp index 44d6e966ea..211d26adda 100644 --- a/externals/dynarmic/tests/test_reader.cpp +++ b/externals/dynarmic/tests/test_reader.cpp @@ -158,7 +158,8 @@ void RunTestInstance(Dynarmic::A32::Jit& jit, } A64::UserConfig GetA64UserConfig(A64TestEnv& jit_env, bool noopt) { - A64::UserConfig jit_user_config{&jit_env}; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &jit_env; jit_user_config.optimizations &= ~OptimizationFlag::FastDispatch; // The below corresponds to the settings for qemu's aarch64_max_initfn jit_user_config.dczid_el0 = 7; diff --git a/externals/nx_tzdb/tzdb_to_nx/externals/tz/CMakeLists.txt b/externals/nx_tzdb/tzdb_to_nx/externals/tz/CMakeLists.txt index 948fe69a23..2312b34dd6 100644 --- a/externals/nx_tzdb/tzdb_to_nx/externals/tz/CMakeLists.txt +++ b/externals/nx_tzdb/tzdb_to_nx/externals/tz/CMakeLists.txt @@ -24,8 +24,8 @@ if (NOT EXISTS "${TZ_DIR}" OR NOT EXISTS "${TZIF_LIST_FILE}") # separate directory before building. execute_process( COMMAND - ${GIT_PROGRAM} clone --depth 1 "file://${TZ_SOURCE_DIR}" "${TZ_TMP_SOURCE_DIR}" - COMMAND_ERROR_IS_FATAL ANY + ${GIT_PROGRAM} clone --depth=1 "file://${TZ_SOURCE_DIR}" "${TZ_TMP_SOURCE_DIR}" + # No need to be fatal, on SunOS this works fine - COMMAND_ERROR_IS_FATAL ANY ) if (APPLE) diff --git a/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/main.cpp b/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/main.cpp index c1825970ac..12c12ac268 100644 --- a/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/main.cpp +++ b/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/main.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #include "tzif.h" #include #include @@ -7,7 +10,7 @@ #include #include #include -#include +#include #include constexpr std::size_t ten_megabytes{(1 << 20) * 10}; @@ -92,7 +95,7 @@ int main(int argc, char *argv[]) { } } - u_int8_t *buf = new u_int8_t[filesize]; + std::uint8_t *buf = new std::uint8_t[filesize]; filesize = read(f, buf, filesize); if (filesize == static_cast(-1)) { @@ -124,7 +127,7 @@ int main(int argc, char *argv[]) { delete[] buf; - std::vector output_buffer; + std::vector output_buffer; tzif_data->ReformatNintendo(output_buffer); filename = "(stdout)"; diff --git a/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.cpp b/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.cpp index 4d2b842741..476afcbc8e 100644 --- a/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.cpp +++ b/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.cpp @@ -1,14 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #include "tzif.h" #include #include #include -#include +#include namespace Tzif { -static std::size_t SkipToVersion2(const u_int8_t *data, std::size_t size) { +static std::size_t SkipToVersion2(const std::uint8_t *data, std::size_t size) { char magic[5]; - const u_int8_t *p{data}; + const std::uint8_t *p{data}; std::memcpy(magic, data, 4); magic[4] = '\0'; @@ -28,15 +31,15 @@ static std::size_t SkipToVersion2(const u_int8_t *data, std::size_t size) { } template constexpr static void SwapEndianess(Type *value) { - u_int8_t *data = reinterpret_cast(value); + std::uint8_t *data = reinterpret_cast(value); union { - u_int8_t data[sizeof(Type)]; + std::uint8_t data[sizeof(Type)]; Type value; } temp; - for (u_int32_t i = 0; i < sizeof(Type); i++) { - u_int32_t alt_index = sizeof(Type) - i - 1; + for (std::uint32_t i = 0; i < sizeof(Type); i++) { + std::uint32_t alt_index = sizeof(Type) - i - 1; temp.data[alt_index] = data[i]; } @@ -52,13 +55,13 @@ static void FlipHeader(Header &header) { SwapEndianess(&header.charcnt); } -std::unique_ptr ReadData(const u_int8_t *data, std::size_t size) { +std::unique_ptr ReadData(const std::uint8_t *data, std::size_t size) { const std::size_t v2_offset = SkipToVersion2(data, size); if (v2_offset == static_cast(-1)) { return nullptr; } - const u_int8_t *p = data + v2_offset; + const std::uint8_t *p = data + v2_offset; Header header; std::memcpy(&header, p, sizeof(header)); @@ -67,10 +70,10 @@ std::unique_ptr ReadData(const u_int8_t *data, std::size_t size) { FlipHeader(header); const std::size_t data_block_length = - header.timecnt * sizeof(int64_t) + header.timecnt * sizeof(u_int8_t) + + header.timecnt * sizeof(int64_t) + header.timecnt * sizeof(std::uint8_t) + header.typecnt * sizeof(TimeTypeRecord) + - header.charcnt * sizeof(int8_t) + header.isstdcnt * sizeof(u_int8_t) + - header.isutcnt * sizeof(u_int8_t); + header.charcnt * sizeof(int8_t) + header.isstdcnt * sizeof(std::uint8_t) + + header.isutcnt * sizeof(std::uint8_t); if (v2_offset + data_block_length + sizeof(Header) > size) { return nullptr; @@ -81,7 +84,7 @@ std::unique_ptr ReadData(const u_int8_t *data, std::size_t size) { const auto copy = [](std::unique_ptr &array, int length, - const u_int8_t *const &ptr) -> const u_int8_t * { + const std::uint8_t *const &ptr) -> const std::uint8_t * { const std::size_t region_length = length * sizeof(Type); array = std::make_unique(length); std::memcpy(array.get(), ptr, region_length); @@ -110,16 +113,16 @@ std::unique_ptr ReadData(const u_int8_t *data, std::size_t size) { return impl; } -static void PushToBuffer(std::vector &buffer, const void *data, +static void PushToBuffer(std::vector &buffer, const void *data, std::size_t size) { - const u_int8_t *p{reinterpret_cast(data)}; + const std::uint8_t *p{reinterpret_cast(data)}; for (std::size_t i = 0; i < size; i++) { buffer.push_back(*p); p++; } } -void DataImpl::ReformatNintendo(std::vector &buffer) const { +void DataImpl::ReformatNintendo(std::vector &buffer) const { buffer.clear(); Header header_copy{header}; @@ -131,7 +134,7 @@ void DataImpl::ReformatNintendo(std::vector &buffer) const { PushToBuffer(buffer, transition_times.get(), header.timecnt * sizeof(int64_t)); PushToBuffer(buffer, transition_types.get(), - header.timecnt * sizeof(u_int8_t)); + header.timecnt * sizeof(std::uint8_t)); PushToBuffer(buffer, local_time_type_records.get(), header.typecnt * sizeof(TimeTypeRecord)); PushToBuffer(buffer, time_zone_designations.get(), diff --git a/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.h b/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.h index 62ff3afe15..a6eb32a896 100644 --- a/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.h +++ b/externals/nx_tzdb/tzdb_to_nx/src/tzdb2nx/tzif.h @@ -1,22 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + #pragma once #include #include -#include +#include #include namespace Tzif { typedef struct { char magic[4]; - u_int8_t version; - u_int8_t reserved[15]; - u_int32_t isutcnt; - u_int32_t isstdcnt; - u_int32_t leapcnt; - u_int32_t timecnt; - u_int32_t typecnt; - u_int32_t charcnt; + std::uint8_t version; + std::uint8_t reserved[15]; + std::uint32_t isutcnt; + std::uint32_t isstdcnt; + std::uint32_t leapcnt; + std::uint32_t timecnt; + std::uint32_t typecnt; + std::uint32_t charcnt; } Header; static_assert(sizeof(Header) == 0x2c); @@ -34,9 +37,9 @@ public: #pragma pack(push, 1) typedef struct { - u_int32_t utoff; - u_int8_t dst; - u_int8_t idx; + std::uint32_t utoff; + std::uint8_t dst; + std::uint8_t idx; } TimeTypeRecord; #pragma pack(pop) static_assert(sizeof(TimeTypeRecord) == 0x6); @@ -46,7 +49,7 @@ public: explicit Data() = default; virtual ~Data() = default; - virtual void ReformatNintendo(std::vector &buffer) const = 0; + virtual void ReformatNintendo(std::vector &buffer) const = 0; }; class DataImpl : public Data { @@ -54,19 +57,19 @@ public: explicit DataImpl() = default; ~DataImpl() override = default; - void ReformatNintendo(std::vector &buffer) const override; + void ReformatNintendo(std::vector &buffer) const override; Header header; Footer footer; std::unique_ptr transition_times; - std::unique_ptr transition_types; + std::unique_ptr transition_types; std::unique_ptr local_time_type_records; std::unique_ptr time_zone_designations; - std::unique_ptr standard_indicators; - std::unique_ptr ut_indicators; + std::unique_ptr standard_indicators; + std::unique_ptr ut_indicators; }; -std::unique_ptr ReadData(const u_int8_t *data, std::size_t size); +std::unique_ptr ReadData(const std::uint8_t *data, std::size_t size); } // namespace Tzif diff --git a/externals/renderdoc/renderdoc_app.h b/externals/renderdoc/renderdoc_app.h index 84ff62b5db..f4eb12526e 100644 --- a/externals/renderdoc/renderdoc_app.h +++ b/externals/renderdoc/renderdoc_app.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Baldur Karlsson // SPDX-License-Identifier: MIT @@ -38,14 +41,8 @@ #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) #define RENDERDOC_CC __cdecl -#elif defined(__linux__) -#define RENDERDOC_CC -#elif defined(__APPLE__) -#define RENDERDOC_CC -#elif defined(__FreeBSD__) -#define RENDERDOC_CC #else -#error "Unknown platform" +#define RENDERDOC_CC #endif #ifdef __cplusplus diff --git a/externals/xbyak b/externals/xbyak index 0d67fd1530..4e44f4614d 160000 --- a/externals/xbyak +++ b/externals/xbyak @@ -1 +1 @@ -Subproject commit 0d67fd1530016b7c56f3cd74b3fca920f4c3e2b4 +Subproject commit 4e44f4614ddbf038f2a6296f5b906d5c72691e0f diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index 8fc4a82088..81ce67da4c 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -147,11 +147,6 @@ android { dimension = "version" // No need to set applicationId here } - - create("genshinSpoof") { - dimension = "version" - applicationId = "com.miHoYo.Yuanshen" - } } } @@ -174,6 +169,7 @@ android { "-DYUZU_USE_BUNDLED_VCPKG=ON", "-DYUZU_USE_BUNDLED_FFMPEG=ON", "-DYUZU_ENABLE_LTO=ON", + "-DYUZU_TESTS=OFF", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" ) diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index cd18f1e5b3..af87ea132a 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h @@ -8,172 +8,233 @@ #include #include "common/common_types.h" -#include "common/settings_setting.h" #include "common/settings_enums.h" +#include "common/settings_setting.h" namespace AndroidSettings { - struct GameDir { - std::string path; - bool deep_scan = false; - }; +struct GameDir { + std::string path; + bool deep_scan = false; +}; - struct OverlayControlData { - std::string id; - bool enabled; - std::pair landscape_position; - std::pair portrait_position; - std::pair foldable_position; - }; +struct OverlayControlData { + std::string id; + bool enabled; + std::pair landscape_position; + std::pair portrait_position; + std::pair foldable_position; +}; - struct Values { - Settings::Linkage linkage; +struct Values { + Settings::Linkage linkage; - // Path settings - std::vector game_dirs; + // Path settings + std::vector game_dirs; - // Android - Settings::Setting picture_in_picture{linkage, false, "picture_in_picture", - Settings::Category::Android}; - Settings::Setting screen_layout{linkage, - 5, - "screen_layout", - Settings::Category::Android, - Settings::Specialization::Default, - true, - true}; - Settings::Setting vertical_alignment{linkage, - 0, - "vertical_alignment", - Settings::Category::Android, + // Android + Settings::Setting picture_in_picture{linkage, false, "picture_in_picture", + Settings::Category::Android}; + Settings::Setting screen_layout{linkage, + 5, + "screen_layout", + Settings::Category::Android, + Settings::Specialization::Default, + true, + true}; + Settings::Setting vertical_alignment{linkage, + 0, + "vertical_alignment", + Settings::Category::Android, + Settings::Specialization::Default, + true, + true}; + + Settings::SwitchableSetting driver_path{linkage, "", "driver_path", + Settings::Category::GpuDriver}; + + // LRU Cache + Settings::SwitchableSetting use_lru_cache{linkage, true, "use_lru_cache", + Settings::Category::System}; + + Settings::Setting theme{linkage, 0, "theme", Settings::Category::Android}; + Settings::Setting theme_mode{linkage, -1, "theme_mode", Settings::Category::Android}; + Settings::Setting black_backgrounds{linkage, false, "black_backgrounds", + Settings::Category::Android}; + + // Input/performance overlay settings + std::vector overlay_control_data; + Settings::Setting overlay_scale{linkage, 50, "control_scale", Settings::Category::Overlay}; + Settings::Setting overlay_opacity{linkage, 100, "control_opacity", + Settings::Category::Overlay}; + + Settings::Setting joystick_rel_center{linkage, true, "joystick_rel_center", + Settings::Category::Overlay}; + Settings::Setting dpad_slide{linkage, true, "dpad_slide", Settings::Category::Overlay}; + Settings::Setting haptic_feedback{linkage, true, "haptic_feedback", + Settings::Category::Overlay}; + Settings::Setting show_performance_overlay{linkage, + true, + "show_performance_overlay", + Settings::Category::Overlay, + Settings::Specialization::Paired, + true, + true}; + Settings::Setting perf_overlay_background{linkage, + false, + "perf_overlay_background", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + Settings::Setting perf_overlay_position{linkage, + 0, + "perf_overlay_position", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + + Settings::Setting show_fps{linkage, + true, + "show_fps", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + Settings::Setting show_frame_time{linkage, + false, + "show_frame_time", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + Settings::Setting show_app_ram_usage{linkage, + false, + "show_app_ram_usage", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + Settings::Setting show_system_ram_usage{linkage, + false, + "show_system_ram_usage", + Settings::Category::Overlay, Settings::Specialization::Default, true, - true}; - - Settings::SwitchableSetting driver_path{linkage, "", "driver_path", - Settings::Category::GpuDriver}; - - // LRU Cache - Settings::SwitchableSetting use_lru_cache{linkage, true, "use_lru_cache", - Settings::Category::System}; - - Settings::Setting theme{linkage, 0, "theme", Settings::Category::Android}; - Settings::Setting theme_mode{linkage, -1, "theme_mode", Settings::Category::Android}; - Settings::Setting black_backgrounds{linkage, false, "black_backgrounds", - Settings::Category::Android}; - - // Input/performance overlay settings - std::vector overlay_control_data; - Settings::Setting overlay_scale{linkage, 50, "control_scale", - Settings::Category::Overlay}; - Settings::Setting overlay_opacity{linkage, 100, "control_opacity", - Settings::Category::Overlay}; - - Settings::Setting joystick_rel_center{linkage, true, "joystick_rel_center", - Settings::Category::Overlay}; - Settings::Setting dpad_slide{linkage, true, "dpad_slide", - Settings::Category::Overlay}; - Settings::Setting haptic_feedback{linkage, true, "haptic_feedback", - Settings::Category::Overlay}; - Settings::Setting show_performance_overlay{linkage, true, "show_performance_overlay", - Settings::Category::Overlay, - Settings::Specialization::Paired, true, - true}; - Settings::Setting perf_overlay_background{linkage, false, "perf_overlay_background", - Settings::Category::Overlay, - Settings::Specialization::Default, true, - true, - &show_performance_overlay}; - Settings::Setting perf_overlay_position{linkage, 0, "perf_overlay_position", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - - Settings::Setting show_fps{linkage, true, "show_fps", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - Settings::Setting show_frame_time{linkage, false, "show_frame_time", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - Settings::Setting show_app_ram_usage{linkage, false, "show_app_ram_usage", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - Settings::Setting show_system_ram_usage{linkage, false, "show_system_ram_usage", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - Settings::Setting show_bat_temperature{linkage, false, "show_bat_temperature", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - Settings::Setting bat_temperature_unit{linkage, - Settings::TemperatureUnits::Celsius, - "bat_temperature_unit", - Settings::Category::Overlay, - Settings::Specialization::Default, - true, true, - &show_bat_temperature}; - Settings::Setting show_power_info{linkage, false, "show_power_info", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - Settings::Setting show_shaders_building{linkage, true, "show_shaders_building", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; - - - Settings::Setting show_input_overlay{linkage, true, "show_input_overlay", - Settings::Category::Overlay}; - Settings::Setting touchscreen{linkage, true, "touchscreen", - Settings::Category::Overlay}; - Settings::Setting lock_drawer{linkage, false, "lock_drawer", - Settings::Category::Overlay}; - - /// DEVICE/SOC OVERLAY - - Settings::Setting show_soc_overlay{linkage, true, "show_soc_overlay", + true, + &show_performance_overlay}; + Settings::Setting show_bat_temperature{linkage, + false, + "show_bat_temperature", Settings::Category::Overlay, - Settings::Specialization::Paired, true, true}; - - Settings::Setting show_device_model{linkage, true, "show_device_model", + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + Settings::Setting bat_temperature_unit{ + linkage, + Settings::TemperatureUnits::Celsius, + "bat_temperature_unit", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_bat_temperature}; + Settings::Setting show_power_info{linkage, + false, + "show_power_info", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + Settings::Setting show_shaders_building{linkage, + true, + "show_shaders_building", Settings::Category::Overlay, - Settings::Specialization::Default, true, true, + Settings::Specialization::Default, + true, + true, &show_performance_overlay}; - Settings::Setting show_gpu_model{linkage, true, "show_gpu_model", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; + Settings::Setting show_input_overlay{linkage, true, "show_input_overlay", + Settings::Category::Overlay}; + Settings::Setting touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay}; + Settings::Setting lock_drawer{linkage, false, "lock_drawer", Settings::Category::Overlay}; - Settings::Setting show_soc_model{linkage, true, "show_soc_model", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_soc_overlay}; + /// DEVICE/SOC OVERLAY - Settings::Setting show_fw_version{linkage, true, "show_firmware_version", + Settings::Setting show_soc_overlay{linkage, + true, + "show_soc_overlay", + Settings::Category::Overlay, + Settings::Specialization::Paired, + true, + true}; + + Settings::Setting show_device_model{linkage, + true, + "show_device_model", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + + Settings::Setting show_gpu_model{linkage, + true, + "show_gpu_model", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + + Settings::Setting show_soc_model{linkage, + true, + "show_soc_model", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_soc_overlay}; + + Settings::Setting show_fw_version{linkage, + true, + "show_firmware_version", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_performance_overlay}; + + Settings::Setting soc_overlay_background{linkage, + false, + "soc_overlay_background", + Settings::Category::Overlay, + Settings::Specialization::Default, + true, + true, + &show_soc_overlay}; + Settings::Setting soc_overlay_position{linkage, + 2, + "soc_overlay_position", Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_performance_overlay}; + Settings::Specialization::Default, + true, + true, + &show_soc_overlay}; - Settings::Setting soc_overlay_background{linkage, false, "soc_overlay_background", - Settings::Category::Overlay, - Settings::Specialization::Default, true, - true, - &show_soc_overlay}; - Settings::Setting soc_overlay_position{linkage, 2, "soc_overlay_position", - Settings::Category::Overlay, - Settings::Specialization::Default, true, true, - &show_soc_overlay}; + Settings::Setting dont_show_eden_veil_warning{ + linkage, false, "dont_show_eden_veil_warning", Settings::Category::Miscellaneous}; +}; - Settings::Setting dont_show_eden_veil_warning{linkage, false, - "dont_show_eden_veil_warning", - Settings::Category::Miscellaneous}; - }; - - extern Values values; +extern Values values; } // namespace AndroidSettings diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 9fed0b1449..36f7d04386 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -4,7 +4,6 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later - #include #include #include @@ -24,9 +23,9 @@ #include #include -#include "common/android/multiplayer/multiplayer.h" #include "common/android/android_common.h" #include "common/android/id_cache.h" +#include "common/android/multiplayer/multiplayer.h" #include "common/detached_tasks.h" #include "common/dynamic_library.h" #include "common/fs/path_util.h" @@ -65,23 +64,23 @@ #include "hid_core/hid_core.h" #include "hid_core/hid_types.h" #include "jni/native.h" +#include "network/announce_multiplayer_session.h" #include "video_core/renderer_base.h" #include "video_core/renderer_vulkan/renderer_vulkan.h" +#include "video_core/shader_notify.h" #include "video_core/vulkan_common/vulkan_instance.h" #include "video_core/vulkan_common/vulkan_surface.h" -#include "video_core/shader_notify.h" -#include "network/announce_multiplayer_session.h" #define jconst [[maybe_unused]] const auto #define jauto [[maybe_unused]] auto static EmulationSession s_instance; -//Abdroid Multiplayer which can be initialized with parameters +// Abdroid Multiplayer which can be initialized with parameters std::unique_ptr multiplayer{nullptr}; std::shared_ptr announce_multiplayer_session; -//Power Status default values +// Power Status default values std::atomic g_battery_percentage = {100}; std::atomic g_is_charging = {false}; std::atomic g_has_battery = {true}; @@ -581,7 +580,9 @@ jobjectArray Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getSystemDriverInfo( return j_driver_info; } -jstring Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getGpuModel(JNIEnv *env, jobject j_obj, jobject j_surf, jstring j_hook_lib_dir) { +jstring Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getGpuModel(JNIEnv* env, jobject j_obj, + jobject j_surf, + jstring j_hook_lib_dir) { const char* file_redirect_dir_{}; int featureFlags{}; std::string hook_lib_dir = Common::Android::GetJString(env, j_hook_lib_dir); @@ -590,11 +591,11 @@ jstring Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getGpuModel(JNIEnv *env, j auto driver_library = std::make_shared(handle); InputCommon::InputSubsystem input_subsystem; auto window = - std::make_unique(ANativeWindow_fromSurface(env, j_surf), driver_library); + std::make_unique(ANativeWindow_fromSurface(env, j_surf), driver_library); Vulkan::vk::InstanceDispatch dld; Vulkan::vk::Instance vk_instance = Vulkan::CreateInstance( - *driver_library, dld, VK_API_VERSION_1_1, Core::Frontend::WindowSystemType::Android); + *driver_library, dld, VK_API_VERSION_1_1, Core::Frontend::WindowSystemType::Android); auto surface = Vulkan::CreateSurface(vk_instance, window->GetWindowInfo()); @@ -791,16 +792,19 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_firmwareVersion(JNIEnv* env, jclas } jint Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyFirmware(JNIEnv* env, jclass clazz) { - return static_cast(FirmwareManager::VerifyFirmware(EmulationSession::GetInstance().System())); + return static_cast( + FirmwareManager::VerifyFirmware(EmulationSession::GetInstance().System())); } -jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_gameRequiresFirmware(JNIEnv* env, jclass clazz, jstring jprogramId) { +jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_gameRequiresFirmware(JNIEnv* env, jclass clazz, + jstring jprogramId) { auto program_id = EmulationSession::GetProgramId(env, jprogramId); return FirmwareManager::GameRequiresFirmware(program_id); } -jint Java_org_yuzu_yuzu_1emu_NativeLibrary_installKeys(JNIEnv* env, jclass clazz, jstring jpath, jstring jext) { +jint Java_org_yuzu_yuzu_1emu_NativeLibrary_installKeys(JNIEnv* env, jclass clazz, jstring jpath, + jstring jext) { const auto path = Common::Android::GetJString(env, jpath); const auto ext = Common::Android::GetJString(env, jext); @@ -957,105 +961,97 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_areKeysPresent(JNIEnv* env, jobje } JNIEXPORT void JNICALL -Java_org_yuzu_yuzu_1emu_NativeLibrary_initMultiplayer( - JNIEnv* env, [[maybe_unused]] jobject obj) { +Java_org_yuzu_yuzu_1emu_NativeLibrary_initMultiplayer(JNIEnv* env, [[maybe_unused]] jobject obj) { if (multiplayer) { return; } announce_multiplayer_session = std::make_shared(); - multiplayer = std::make_unique(s_instance.System(), announce_multiplayer_session); + multiplayer = + std::make_unique(s_instance.System(), announce_multiplayer_session); multiplayer->NetworkInit(); } -JNIEXPORT jobjectArray JNICALL -Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayGetPublicRooms( - JNIEnv *env, [[maybe_unused]] jobject obj) { +JNIEXPORT jobjectArray JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayGetPublicRooms( + JNIEnv* env, [[maybe_unused]] jobject obj) { return Common::Android::ToJStringArray(env, multiplayer->NetPlayGetPublicRooms()); } JNIEXPORT jint JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayCreateRoom( - JNIEnv* env, [[maybe_unused]] jobject obj, jstring ipaddress, jint port, - jstring username, jstring preferredGameName, jlong preferredGameId, jstring password, - jstring room_name, jint max_players, jboolean isPublic) { - return static_cast( - multiplayer->NetPlayCreateRoom(Common::Android::GetJString(env, ipaddress), port, - Common::Android::GetJString(env, username), Common::Android::GetJString(env, preferredGameName), - preferredGameId,Common::Android::GetJString(env, password), - Common::Android::GetJString(env, room_name), max_players, isPublic)); + JNIEnv* env, [[maybe_unused]] jobject obj, jstring ipaddress, jint port, jstring username, + jstring preferredGameName, jlong preferredGameId, jstring password, jstring room_name, + jint max_players, jboolean isPublic) { + return static_cast(multiplayer->NetPlayCreateRoom( + Common::Android::GetJString(env, ipaddress), port, + Common::Android::GetJString(env, username), + Common::Android::GetJString(env, preferredGameName), preferredGameId, + Common::Android::GetJString(env, password), Common::Android::GetJString(env, room_name), + max_players, isPublic)); } JNIEXPORT jint JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayJoinRoom( - JNIEnv* env, [[maybe_unused]] jobject obj, jstring ipaddress, jint port, - jstring username, jstring password) { - return static_cast( - multiplayer->NetPlayJoinRoom(Common::Android::GetJString(env, ipaddress), port, - Common::Android::GetJString(env, username), Common::Android::GetJString(env, password))); + JNIEnv* env, [[maybe_unused]] jobject obj, jstring ipaddress, jint port, jstring username, + jstring password) { + return static_cast(multiplayer->NetPlayJoinRoom( + Common::Android::GetJString(env, ipaddress), port, + Common::Android::GetJString(env, username), Common::Android::GetJString(env, password))); } -JNIEXPORT jobjectArray JNICALL -Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayRoomInfo( - JNIEnv* env, [[maybe_unused]] jobject obj) { +JNIEXPORT jobjectArray JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayRoomInfo( + JNIEnv* env, [[maybe_unused]] jobject obj) { return Common::Android::ToJStringArray(env, multiplayer->NetPlayRoomInfo()); } -JNIEXPORT jboolean JNICALL -Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayIsJoined( - [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { +JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayIsJoined( + [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { return multiplayer->NetPlayIsJoined(); } -JNIEXPORT jboolean JNICALL -Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayIsHostedRoom( - [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { +JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayIsHostedRoom( + [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { return multiplayer->NetPlayIsHostedRoom(); } -JNIEXPORT void JNICALL -Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlaySendMessage( - JNIEnv* env, [[maybe_unused]] jobject obj, jstring msg) { +JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlaySendMessage( + JNIEnv* env, [[maybe_unused]] jobject obj, jstring msg) { multiplayer->NetPlaySendMessage(Common::Android::GetJString(env, msg)); } JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayKickUser( - JNIEnv* env, [[maybe_unused]] jobject obj, jstring username) { + JNIEnv* env, [[maybe_unused]] jobject obj, jstring username) { multiplayer->NetPlayKickUser(Common::Android::GetJString(env, username)); } JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayLeaveRoom( - [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { + [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { multiplayer->NetPlayLeaveRoom(); } -JNIEXPORT jboolean JNICALL -Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayIsModerator( - [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { +JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayIsModerator( + [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jobject obj) { return multiplayer->NetPlayIsModerator(); } -JNIEXPORT jobjectArray JNICALL -Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayGetBanList( - JNIEnv* env, [[maybe_unused]] jobject obj) { +JNIEXPORT jobjectArray JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayGetBanList( + JNIEnv* env, [[maybe_unused]] jobject obj) { return Common::Android::ToJStringArray(env, multiplayer->NetPlayGetBanList()); } JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayBanUser( - JNIEnv* env, [[maybe_unused]] jobject obj, jstring username) { + JNIEnv* env, [[maybe_unused]] jobject obj, jstring username) { multiplayer->NetPlayBanUser(Common::Android::GetJString(env, username)); } JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_network_NetPlayManager_netPlayUnbanUser( - JNIEnv* env, [[maybe_unused]] jobject obj, jstring username) { + JNIEnv* env, [[maybe_unused]] jobject obj, jstring username) { multiplayer->NetPlayUnbanUser(Common::Android::GetJString(env, username)); } -JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_updatePowerState( - JNIEnv* env, - jobject, - jint percentage, - jboolean isCharging, - jboolean hasBattery) { +JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_updatePowerState(JNIEnv* env, jobject, + jint percentage, + jboolean isCharging, + jboolean hasBattery) { g_battery_percentage.store(percentage, std::memory_order_relaxed); g_is_charging.store(isCharging, std::memory_order_relaxed); diff --git a/src/audio_core/in/audio_in.cpp b/src/audio_core/in/audio_in.cpp index df8c44d1f2..b28eb69786 100644 --- a/src/audio_core/in/audio_in.cpp +++ b/src/audio_core/in/audio_in.cpp @@ -8,8 +8,8 @@ namespace AudioCore::AudioIn { In::In(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_) - : manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event, - session_id_} {} + : manager{manager_}, parent_mutex{manager.mutex}, event{event_}, + system{system_, event, session_id_} {} void In::Free() { std::scoped_lock l{parent_mutex}; diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp index b2dd3ef9f7..84d99877cb 100644 --- a/src/audio_core/in/audio_in_system.cpp +++ b/src/audio_core/in/audio_in_system.cpp @@ -14,8 +14,8 @@ namespace AudioCore::AudioIn { System::System(Core::System& system_, Kernel::KEvent* event_, const size_t session_id_) - : system{system_}, buffer_event{event_}, - session_id{session_id_}, session{std::make_unique(system_)} {} + : system{system_}, buffer_event{event_}, session_id{session_id_}, + session{std::make_unique(system_)} {} System::~System() { Finalize(); diff --git a/src/audio_core/out/audio_out.cpp b/src/audio_core/out/audio_out.cpp index b7ea134055..d31bced9df 100644 --- a/src/audio_core/out/audio_out.cpp +++ b/src/audio_core/out/audio_out.cpp @@ -8,8 +8,8 @@ namespace AudioCore::AudioOut { Out::Out(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_) - : manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event, - session_id_} {} + : manager{manager_}, parent_mutex{manager.mutex}, event{event_}, + system{system_, event, session_id_} {} void Out::Free() { std::scoped_lock l{parent_mutex}; diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp index 7b3ff4e881..4c940be2d3 100644 --- a/src/audio_core/out/audio_out_system.cpp +++ b/src/audio_core/out/audio_out_system.cpp @@ -14,8 +14,8 @@ namespace AudioCore::AudioOut { System::System(Core::System& system_, Kernel::KEvent* event_, size_t session_id_) - : system{system_}, buffer_event{event_}, - session_id{session_id_}, session{std::make_unique(system_)} {} + : system{system_}, buffer_event{event_}, session_id{session_id_}, + session{std::make_unique(system_)} {} System::~System() { Finalize(); diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index 3dae6069f7..163127789c 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp @@ -19,10 +19,9 @@ namespace AudioCore::Renderer { InfoUpdater::InfoUpdater(std::span input_, std::span output_, Kernel::KProcess* process_handle_, BehaviorInfo& behaviour_) - : input{input_.data() + sizeof(UpdateDataHeader)}, - input_origin{input_}, output{output_.data() + sizeof(UpdateDataHeader)}, - output_origin{output_}, in_header{reinterpret_cast( - input_origin.data())}, + : input{input_.data() + sizeof(UpdateDataHeader)}, input_origin{input_}, + output{output_.data() + sizeof(UpdateDataHeader)}, output_origin{output_}, + in_header{reinterpret_cast(input_origin.data())}, out_header{reinterpret_cast(output_origin.data())}, expected_input_size{input_.size()}, expected_output_size{output_.size()}, process_handle{process_handle_}, behaviour{behaviour_} { diff --git a/src/audio_core/renderer/memory/pool_mapper.cpp b/src/audio_core/renderer/memory/pool_mapper.cpp index e47eb66d51..1df786feb5 100644 --- a/src/audio_core/renderer/memory/pool_mapper.cpp +++ b/src/audio_core/renderer/memory/pool_mapper.cpp @@ -13,8 +13,8 @@ PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, bool force_map_) PoolMapper::PoolMapper(Kernel::KProcess* process_handle_, std::span pool_infos_, u32 pool_count_, bool force_map_) - : process_handle{process_handle_}, pool_infos{pool_infos_.data()}, - pool_count{pool_count_}, force_map{force_map_} {} + : process_handle{process_handle_}, pool_infos{pool_infos_.data()}, pool_count{pool_count_}, + force_map{force_map_} {} void PoolMapper::ClearUseState(std::span pools, const u32 count) { for (u32 i = 0; i < count; i++) { diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index 7dd155ff0c..ffdd77042e 100644 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -1,8 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include #include + #include #include "audio_core/common/common.h" diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp index 0a98eb31e2..e687d201aa 100644 --- a/src/audio_core/sink/sink_stream.cpp +++ b/src/audio_core/sink/sink_stream.cpp @@ -240,7 +240,9 @@ void SinkStream::ProcessAudioOutAndRender(std::span output_buffer, std::siz // Successfully dequeued a new buffer. queued_buffers--; - { std::unique_lock lk{release_mutex}; } + { + std::unique_lock lk{release_mutex}; + } release_cv.notify_one(); } diff --git a/src/common/address_space.h b/src/common/address_space.h index 8683c23c39..694bb2aed3 100644 --- a/src/common/address_space.h +++ b/src/common/address_space.h @@ -12,8 +12,7 @@ namespace Common { template -concept AddressSpaceValid = std::is_unsigned_v && sizeof(VaType) * 8 >= -AddressSpaceBits; +concept AddressSpaceValid = std::is_unsigned_v && sizeof(VaType) * 8 >= AddressSpaceBits; struct EmptyStruct {}; diff --git a/src/common/android/android_common.cpp b/src/common/android/android_common.cpp index a1cf081695..14598fe2f0 100644 --- a/src/common/android/android_common.cpp +++ b/src/common/android/android_common.cpp @@ -38,8 +38,8 @@ jstring ToJString(JNIEnv* env, std::string_view str) { } jobjectArray ToJStringArray(JNIEnv* env, const std::vector& strs) { - jobjectArray array = - env->NewObjectArray(static_cast(strs.size()), env->FindClass("java/lang/String"), env->NewStringUTF("")); + jobjectArray array = env->NewObjectArray( + static_cast(strs.size()), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (std::size_t i = 0; i < strs.size(); ++i) { env->SetObjectArrayElement(array, static_cast(i), ToJString(env, strs[i])); } diff --git a/src/common/android/id_cache.cpp b/src/common/android/id_cache.cpp index e0edd006a5..1d53710e32 100644 --- a/src/common/android/id_cache.cpp +++ b/src/common/android/id_cache.cpp @@ -6,16 +6,15 @@ #include +#include #include "applets/software_keyboard.h" #include "common/android/id_cache.h" +#include "common/android/multiplayer/multiplayer.h" #include "common/assert.h" #include "common/fs/fs_android.h" #include "video_core/rasterizer_interface.h" -#include "common/android/multiplayer/multiplayer.h" -#include - -static JavaVM *s_java_vm; +static JavaVM* s_java_vm; static jclass s_native_library_class; static jclass s_disk_cache_progress_class; static jclass s_load_callback_stage_class; @@ -105,534 +104,530 @@ static constexpr jint JNI_VERSION = JNI_VERSION_1_6; namespace Common::Android { - JNIEnv *GetEnvForThread() { - thread_local static struct OwnedEnv { - OwnedEnv() { - status = s_java_vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); - if (status == JNI_EDETACHED) - s_java_vm->AttachCurrentThread(&env, nullptr); - } - - ~OwnedEnv() { - if (status == JNI_EDETACHED) - s_java_vm->DetachCurrentThread(); - } - - int status; - JNIEnv *env = nullptr; - } owned; - return owned.env; - } - - jclass GetNativeLibraryClass() { - return s_native_library_class; - } - - jclass GetDiskCacheProgressClass() { - return s_disk_cache_progress_class; - } - - jclass GetDiskCacheLoadCallbackStageClass() { - return s_load_callback_stage_class; - } - - jclass GetGameDirClass() { - return s_game_dir_class; - } - - jmethodID GetGameDirConstructor() { - return s_game_dir_constructor; - } - - jmethodID GetExitEmulationActivity() { - return s_exit_emulation_activity; - } - - jmethodID GetDiskCacheLoadProgress() { - return s_disk_cache_load_progress; - } - - jmethodID GetCopyToStorage() { - return s_copy_to_storage; - } - - jmethodID GetFileExists() { - return s_file_exists; - } - - jmethodID GetFileExtension() { - return s_file_extension; - } - - jmethodID GetOnEmulationStarted() { - return s_on_emulation_started; - } - - jmethodID GetOnEmulationStopped() { - return s_on_emulation_stopped; - } - - jmethodID GetOnProgramChanged() { - return s_on_program_changed; - } - - jclass GetGameClass() { - return s_game_class; - } - - jmethodID GetGameConstructor() { - return s_game_constructor; - } - - jfieldID GetGameTitleField() { - return s_game_title_field; - } - - jfieldID GetGamePathField() { - return s_game_path_field; - } - - jfieldID GetGameProgramIdField() { - return s_game_program_id_field; - } - - jfieldID GetGameDeveloperField() { - return s_game_developer_field; - } - - jfieldID GetGameVersionField() { - return s_game_version_field; - } - - jfieldID GetGameIsHomebrewField() { - return s_game_is_homebrew_field; - } - - jclass GetStringClass() { - return s_string_class; - } - - jclass GetPairClass() { - return s_pair_class; - } - - jmethodID GetPairConstructor() { - return s_pair_constructor; - } - - jfieldID GetPairFirstField() { - return s_pair_first_field; - } - - jfieldID GetPairSecondField() { - return s_pair_second_field; - } - - jclass GetOverlayControlDataClass() { - return s_overlay_control_data_class; - } - - jmethodID GetOverlayControlDataConstructor() { - return s_overlay_control_data_constructor; - } - - jfieldID GetOverlayControlDataIdField() { - return s_overlay_control_data_id_field; - } - - jfieldID GetOverlayControlDataEnabledField() { - return s_overlay_control_data_enabled_field; - } - - jfieldID GetOverlayControlDataLandscapePositionField() { - return s_overlay_control_data_landscape_position_field; - } - - jfieldID GetOverlayControlDataPortraitPositionField() { - return s_overlay_control_data_portrait_position_field; - } - - jfieldID GetOverlayControlDataFoldablePositionField() { - return s_overlay_control_data_foldable_position_field; - } - - jclass GetPatchClass() { - return s_patch_class; - } - - jmethodID GetPatchConstructor() { - return s_patch_constructor; - } - - jfieldID GetPatchEnabledField() { - return s_patch_enabled_field; - } - - jfieldID GetPatchNameField() { - return s_patch_name_field; - } - - jfieldID GetPatchVersionField() { - return s_patch_version_field; - } - - jfieldID GetPatchTypeField() { - return s_patch_type_field; - } - - jfieldID GetPatchProgramIdField() { - return s_patch_program_id_field; - } - - jfieldID GetPatchTitleIdField() { - return s_patch_title_id_field; - } - - jclass GetDoubleClass() { - return s_double_class; - } - - jmethodID GetDoubleConstructor() { - return s_double_constructor; - } - - jfieldID GetDoubleValueField() { - return s_double_value_field; - } - - jclass GetIntegerClass() { - return s_integer_class; - } - - jmethodID GetIntegerConstructor() { - return s_integer_constructor; - } - - jfieldID GetIntegerValueField() { - return s_integer_value_field; - } - - jclass GetBooleanClass() { - return s_boolean_class; - } - - jmethodID GetBooleanConstructor() { - return s_boolean_constructor; - } - - jfieldID GetBooleanValueField() { - return s_boolean_value_field; - } - - jclass GetPlayerInputClass() { - return s_player_input_class; - } - - jmethodID GetPlayerInputConstructor() { - return s_player_input_constructor; - } - - jfieldID GetPlayerInputConnectedField() { - return s_player_input_connected_field; - } - - jfieldID GetPlayerInputButtonsField() { - return s_player_input_buttons_field; - } - - jfieldID GetPlayerInputAnalogsField() { - return s_player_input_analogs_field; - } - - jfieldID GetPlayerInputMotionsField() { - return s_player_input_motions_field; - } - - jfieldID GetPlayerInputVibrationEnabledField() { - return s_player_input_vibration_enabled_field; - } - - jfieldID GetPlayerInputVibrationStrengthField() { - return s_player_input_vibration_strength_field; - } - - jfieldID GetPlayerInputBodyColorLeftField() { - return s_player_input_body_color_left_field; - } - - jfieldID GetPlayerInputBodyColorRightField() { - return s_player_input_body_color_right_field; - } - - jfieldID GetPlayerInputButtonColorLeftField() { - return s_player_input_button_color_left_field; - } - - jfieldID GetPlayerInputButtonColorRightField() { - return s_player_input_button_color_right_field; - } - - jfieldID GetPlayerInputProfileNameField() { - return s_player_input_profile_name_field; - } - - jfieldID GetPlayerInputUseSystemVibratorField() { - return s_player_input_use_system_vibrator_field; - } - - jclass GetYuzuInputDeviceInterface() { - return s_yuzu_input_device_interface; - } - - jmethodID GetYuzuDeviceGetName() { - return s_yuzu_input_device_get_name; - } - - jmethodID GetYuzuDeviceGetGUID() { - return s_yuzu_input_device_get_guid; - } - - jmethodID GetYuzuDeviceGetPort() { - return s_yuzu_input_device_get_port; - } - - jmethodID GetYuzuDeviceGetSupportsVibration() { - return s_yuzu_input_device_get_supports_vibration; - } - - jmethodID GetYuzuDeviceVibrate() { - return s_yuzu_input_device_vibrate; - } - - jmethodID GetYuzuDeviceGetAxes() { - return s_yuzu_input_device_get_axes; - } - - jmethodID GetYuzuDeviceHasKeys() { - return s_yuzu_input_device_has_keys; - } - - jmethodID GetAddNetPlayMessage() { - return s_add_netplay_message; - } - - jmethodID ClearChat() { - return s_clear_chat; - } - -#ifdef __cplusplus - extern "C" { -#endif - - jint JNI_OnLoad(JavaVM *vm, void *reserved) { - s_java_vm = vm; - - JNIEnv *env; - if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) - return JNI_ERR; - - // Initialize Java classes - const jclass native_library_class = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary"); - s_native_library_class = reinterpret_cast(env->NewGlobalRef(native_library_class)); - s_disk_cache_progress_class = reinterpret_cast(env->NewGlobalRef( - env->FindClass("org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress"))); - s_load_callback_stage_class = reinterpret_cast(env->NewGlobalRef(env->FindClass( - "org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage"))); - - const jclass game_dir_class = env->FindClass("org/yuzu/yuzu_emu/model/GameDir"); - s_game_dir_class = reinterpret_cast(env->NewGlobalRef(game_dir_class)); - s_game_dir_constructor = env->GetMethodID(game_dir_class, "", - "(Ljava/lang/String;Z)V"); - env->DeleteLocalRef(game_dir_class); - - // Initialize methods - s_exit_emulation_activity = - env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); - s_disk_cache_load_progress = - env->GetStaticMethodID(s_disk_cache_progress_class, "loadProgress", "(III)V"); - s_copy_to_storage = env->GetStaticMethodID(s_native_library_class, "copyFileToStorage", - "(Ljava/lang/String;Ljava/lang/String;)Z"); - s_file_exists = env->GetStaticMethodID(s_native_library_class, "exists", - "(Ljava/lang/String;)Z"); - s_file_extension = env->GetStaticMethodID(s_native_library_class, "getFileExtension", - "(Ljava/lang/String;)Ljava/lang/String;"); - s_on_emulation_started = - env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V"); - s_on_emulation_stopped = - env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V"); - s_on_program_changed = - env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V"); - - const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game"); - s_game_class = reinterpret_cast(env->NewGlobalRef(game_class)); - s_game_constructor = env->GetMethodID(game_class, "", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/" - "String;Ljava/lang/String;Ljava/lang/String;Z)V"); - s_game_title_field = env->GetFieldID(game_class, "title", "Ljava/lang/String;"); - s_game_path_field = env->GetFieldID(game_class, "path", "Ljava/lang/String;"); - s_game_program_id_field = env->GetFieldID(game_class, "programId", "Ljava/lang/String;"); - s_game_developer_field = env->GetFieldID(game_class, "developer", "Ljava/lang/String;"); - s_game_version_field = env->GetFieldID(game_class, "version", "Ljava/lang/String;"); - s_game_is_homebrew_field = env->GetFieldID(game_class, "isHomebrew", "Z"); - env->DeleteLocalRef(game_class); - - const jclass string_class = env->FindClass("java/lang/String"); - s_string_class = reinterpret_cast(env->NewGlobalRef(string_class)); - env->DeleteLocalRef(string_class); - - const jclass pair_class = env->FindClass("kotlin/Pair"); - s_pair_class = reinterpret_cast(env->NewGlobalRef(pair_class)); - s_pair_constructor = - env->GetMethodID(pair_class, "", "(Ljava/lang/Object;Ljava/lang/Object;)V"); - s_pair_first_field = env->GetFieldID(pair_class, "first", "Ljava/lang/Object;"); - s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;"); - env->DeleteLocalRef(pair_class); - - const jclass overlay_control_data_class = - env->FindClass("org/yuzu/yuzu_emu/overlay/model/OverlayControlData"); - s_overlay_control_data_class = - reinterpret_cast(env->NewGlobalRef(overlay_control_data_class)); - s_overlay_control_data_constructor = - env->GetMethodID(overlay_control_data_class, "", - "(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;)V"); - s_overlay_control_data_id_field = - env->GetFieldID(overlay_control_data_class, "id", "Ljava/lang/String;"); - s_overlay_control_data_enabled_field = - env->GetFieldID(overlay_control_data_class, "enabled", "Z"); - s_overlay_control_data_landscape_position_field = - env->GetFieldID(overlay_control_data_class, "landscapePosition", "Lkotlin/Pair;"); - s_overlay_control_data_portrait_position_field = - env->GetFieldID(overlay_control_data_class, "portraitPosition", "Lkotlin/Pair;"); - s_overlay_control_data_foldable_position_field = - env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;"); - env->DeleteLocalRef(overlay_control_data_class); - - const jclass patch_class = env->FindClass("org/yuzu/yuzu_emu/model/Patch"); - s_patch_class = reinterpret_cast(env->NewGlobalRef(patch_class)); - s_patch_constructor = env->GetMethodID( - patch_class, "", - "(ZLjava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"); - s_patch_enabled_field = env->GetFieldID(patch_class, "enabled", "Z"); - s_patch_name_field = env->GetFieldID(patch_class, "name", "Ljava/lang/String;"); - s_patch_version_field = env->GetFieldID(patch_class, "version", "Ljava/lang/String;"); - s_patch_type_field = env->GetFieldID(patch_class, "type", "I"); - s_patch_program_id_field = env->GetFieldID(patch_class, "programId", "Ljava/lang/String;"); - s_patch_title_id_field = env->GetFieldID(patch_class, "titleId", "Ljava/lang/String;"); - env->DeleteLocalRef(patch_class); - - const jclass double_class = env->FindClass("java/lang/Double"); - s_double_class = reinterpret_cast(env->NewGlobalRef(double_class)); - s_double_constructor = env->GetMethodID(double_class, "", "(D)V"); - s_double_value_field = env->GetFieldID(double_class, "value", "D"); - env->DeleteLocalRef(double_class); - - const jclass int_class = env->FindClass("java/lang/Integer"); - s_integer_class = reinterpret_cast(env->NewGlobalRef(int_class)); - s_integer_constructor = env->GetMethodID(int_class, "", "(I)V"); - s_integer_value_field = env->GetFieldID(int_class, "value", "I"); - env->DeleteLocalRef(int_class); - - const jclass boolean_class = env->FindClass("java/lang/Boolean"); - s_boolean_class = reinterpret_cast(env->NewGlobalRef(boolean_class)); - s_boolean_constructor = env->GetMethodID(boolean_class, "", "(Z)V"); - s_boolean_value_field = env->GetFieldID(boolean_class, "value", "Z"); - env->DeleteLocalRef(boolean_class); - - const jclass player_input_class = - env->FindClass("org/yuzu/yuzu_emu/features/input/model/PlayerInput"); - s_player_input_class = reinterpret_cast(env->NewGlobalRef(player_input_class)); - s_player_input_constructor = env->GetMethodID( - player_input_class, "", - "(Z[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ZIJJJJLjava/lang/String;Z)V"); - s_player_input_connected_field = env->GetFieldID(player_input_class, "connected", "Z"); - s_player_input_buttons_field = - env->GetFieldID(player_input_class, "buttons", "[Ljava/lang/String;"); - s_player_input_analogs_field = - env->GetFieldID(player_input_class, "analogs", "[Ljava/lang/String;"); - s_player_input_motions_field = - env->GetFieldID(player_input_class, "motions", "[Ljava/lang/String;"); - s_player_input_vibration_enabled_field = - env->GetFieldID(player_input_class, "vibrationEnabled", "Z"); - s_player_input_vibration_strength_field = - env->GetFieldID(player_input_class, "vibrationStrength", "I"); - s_player_input_body_color_left_field = - env->GetFieldID(player_input_class, "bodyColorLeft", "J"); - s_player_input_body_color_right_field = - env->GetFieldID(player_input_class, "bodyColorRight", "J"); - s_player_input_button_color_left_field = - env->GetFieldID(player_input_class, "buttonColorLeft", "J"); - s_player_input_button_color_right_field = - env->GetFieldID(player_input_class, "buttonColorRight", "J"); - s_player_input_profile_name_field = - env->GetFieldID(player_input_class, "profileName", "Ljava/lang/String;"); - s_player_input_use_system_vibrator_field = - env->GetFieldID(player_input_class, "useSystemVibrator", "Z"); - env->DeleteLocalRef(player_input_class); - - const jclass yuzu_input_device_interface = - env->FindClass("org/yuzu/yuzu_emu/features/input/YuzuInputDevice"); - s_yuzu_input_device_interface = - reinterpret_cast(env->NewGlobalRef(yuzu_input_device_interface)); - s_yuzu_input_device_get_name = - env->GetMethodID(yuzu_input_device_interface, "getName", "()Ljava/lang/String;"); - s_yuzu_input_device_get_guid = - env->GetMethodID(yuzu_input_device_interface, "getGUID", "()Ljava/lang/String;"); - s_yuzu_input_device_get_port = env->GetMethodID(yuzu_input_device_interface, "getPort", - "()I"); - s_yuzu_input_device_get_supports_vibration = - env->GetMethodID(yuzu_input_device_interface, "getSupportsVibration", "()Z"); - s_yuzu_input_device_vibrate = env->GetMethodID(yuzu_input_device_interface, "vibrate", - "(F)V"); - s_yuzu_input_device_get_axes = - env->GetMethodID(yuzu_input_device_interface, "getAxes", "()[Ljava/lang/Integer;"); - s_yuzu_input_device_has_keys = - env->GetMethodID(yuzu_input_device_interface, "hasKeys", "([I)[Z"); - env->DeleteLocalRef(yuzu_input_device_interface); - s_add_netplay_message = env->GetStaticMethodID(s_native_library_class, "addNetPlayMessage", - "(ILjava/lang/String;)V"); - s_clear_chat = env->GetStaticMethodID(s_native_library_class, "clearChat", "()V"); - - - // Initialize Android Storage - Common::FS::Android::RegisterCallbacks(env, s_native_library_class); - - // Initialize applets - Common::Android::SoftwareKeyboard::InitJNI(env); - - return JNI_VERSION; - } - - void JNI_OnUnload(JavaVM *vm, void *reserved) { - JNIEnv *env; - if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) { - return; +JNIEnv* GetEnvForThread() { + thread_local static struct OwnedEnv { + OwnedEnv() { + status = s_java_vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + if (status == JNI_EDETACHED) + s_java_vm->AttachCurrentThread(&env, nullptr); } - // UnInitialize Android Storage - Common::FS::Android::UnRegisterCallbacks(); - env->DeleteGlobalRef(s_native_library_class); - env->DeleteGlobalRef(s_disk_cache_progress_class); - env->DeleteGlobalRef(s_load_callback_stage_class); - env->DeleteGlobalRef(s_game_dir_class); - env->DeleteGlobalRef(s_game_class); - env->DeleteGlobalRef(s_string_class); - env->DeleteGlobalRef(s_pair_class); - env->DeleteGlobalRef(s_overlay_control_data_class); - env->DeleteGlobalRef(s_patch_class); - env->DeleteGlobalRef(s_double_class); - env->DeleteGlobalRef(s_integer_class); - env->DeleteGlobalRef(s_boolean_class); - env->DeleteGlobalRef(s_player_input_class); - env->DeleteGlobalRef(s_yuzu_input_device_interface); + ~OwnedEnv() { + if (status == JNI_EDETACHED) + s_java_vm->DetachCurrentThread(); + } - // UnInitialize applets - SoftwareKeyboard::CleanupJNI(env); + int status; + JNIEnv* env = nullptr; + } owned; + return owned.env; +} - AndroidMultiplayer::NetworkShutdown(); - } +jclass GetNativeLibraryClass() { + return s_native_library_class; +} + +jclass GetDiskCacheProgressClass() { + return s_disk_cache_progress_class; +} + +jclass GetDiskCacheLoadCallbackStageClass() { + return s_load_callback_stage_class; +} + +jclass GetGameDirClass() { + return s_game_dir_class; +} + +jmethodID GetGameDirConstructor() { + return s_game_dir_constructor; +} + +jmethodID GetExitEmulationActivity() { + return s_exit_emulation_activity; +} + +jmethodID GetDiskCacheLoadProgress() { + return s_disk_cache_load_progress; +} + +jmethodID GetCopyToStorage() { + return s_copy_to_storage; +} + +jmethodID GetFileExists() { + return s_file_exists; +} + +jmethodID GetFileExtension() { + return s_file_extension; +} + +jmethodID GetOnEmulationStarted() { + return s_on_emulation_started; +} + +jmethodID GetOnEmulationStopped() { + return s_on_emulation_stopped; +} + +jmethodID GetOnProgramChanged() { + return s_on_program_changed; +} + +jclass GetGameClass() { + return s_game_class; +} + +jmethodID GetGameConstructor() { + return s_game_constructor; +} + +jfieldID GetGameTitleField() { + return s_game_title_field; +} + +jfieldID GetGamePathField() { + return s_game_path_field; +} + +jfieldID GetGameProgramIdField() { + return s_game_program_id_field; +} + +jfieldID GetGameDeveloperField() { + return s_game_developer_field; +} + +jfieldID GetGameVersionField() { + return s_game_version_field; +} + +jfieldID GetGameIsHomebrewField() { + return s_game_is_homebrew_field; +} + +jclass GetStringClass() { + return s_string_class; +} + +jclass GetPairClass() { + return s_pair_class; +} + +jmethodID GetPairConstructor() { + return s_pair_constructor; +} + +jfieldID GetPairFirstField() { + return s_pair_first_field; +} + +jfieldID GetPairSecondField() { + return s_pair_second_field; +} + +jclass GetOverlayControlDataClass() { + return s_overlay_control_data_class; +} + +jmethodID GetOverlayControlDataConstructor() { + return s_overlay_control_data_constructor; +} + +jfieldID GetOverlayControlDataIdField() { + return s_overlay_control_data_id_field; +} + +jfieldID GetOverlayControlDataEnabledField() { + return s_overlay_control_data_enabled_field; +} + +jfieldID GetOverlayControlDataLandscapePositionField() { + return s_overlay_control_data_landscape_position_field; +} + +jfieldID GetOverlayControlDataPortraitPositionField() { + return s_overlay_control_data_portrait_position_field; +} + +jfieldID GetOverlayControlDataFoldablePositionField() { + return s_overlay_control_data_foldable_position_field; +} + +jclass GetPatchClass() { + return s_patch_class; +} + +jmethodID GetPatchConstructor() { + return s_patch_constructor; +} + +jfieldID GetPatchEnabledField() { + return s_patch_enabled_field; +} + +jfieldID GetPatchNameField() { + return s_patch_name_field; +} + +jfieldID GetPatchVersionField() { + return s_patch_version_field; +} + +jfieldID GetPatchTypeField() { + return s_patch_type_field; +} + +jfieldID GetPatchProgramIdField() { + return s_patch_program_id_field; +} + +jfieldID GetPatchTitleIdField() { + return s_patch_title_id_field; +} + +jclass GetDoubleClass() { + return s_double_class; +} + +jmethodID GetDoubleConstructor() { + return s_double_constructor; +} + +jfieldID GetDoubleValueField() { + return s_double_value_field; +} + +jclass GetIntegerClass() { + return s_integer_class; +} + +jmethodID GetIntegerConstructor() { + return s_integer_constructor; +} + +jfieldID GetIntegerValueField() { + return s_integer_value_field; +} + +jclass GetBooleanClass() { + return s_boolean_class; +} + +jmethodID GetBooleanConstructor() { + return s_boolean_constructor; +} + +jfieldID GetBooleanValueField() { + return s_boolean_value_field; +} + +jclass GetPlayerInputClass() { + return s_player_input_class; +} + +jmethodID GetPlayerInputConstructor() { + return s_player_input_constructor; +} + +jfieldID GetPlayerInputConnectedField() { + return s_player_input_connected_field; +} + +jfieldID GetPlayerInputButtonsField() { + return s_player_input_buttons_field; +} + +jfieldID GetPlayerInputAnalogsField() { + return s_player_input_analogs_field; +} + +jfieldID GetPlayerInputMotionsField() { + return s_player_input_motions_field; +} + +jfieldID GetPlayerInputVibrationEnabledField() { + return s_player_input_vibration_enabled_field; +} + +jfieldID GetPlayerInputVibrationStrengthField() { + return s_player_input_vibration_strength_field; +} + +jfieldID GetPlayerInputBodyColorLeftField() { + return s_player_input_body_color_left_field; +} + +jfieldID GetPlayerInputBodyColorRightField() { + return s_player_input_body_color_right_field; +} + +jfieldID GetPlayerInputButtonColorLeftField() { + return s_player_input_button_color_left_field; +} + +jfieldID GetPlayerInputButtonColorRightField() { + return s_player_input_button_color_right_field; +} + +jfieldID GetPlayerInputProfileNameField() { + return s_player_input_profile_name_field; +} + +jfieldID GetPlayerInputUseSystemVibratorField() { + return s_player_input_use_system_vibrator_field; +} + +jclass GetYuzuInputDeviceInterface() { + return s_yuzu_input_device_interface; +} + +jmethodID GetYuzuDeviceGetName() { + return s_yuzu_input_device_get_name; +} + +jmethodID GetYuzuDeviceGetGUID() { + return s_yuzu_input_device_get_guid; +} + +jmethodID GetYuzuDeviceGetPort() { + return s_yuzu_input_device_get_port; +} + +jmethodID GetYuzuDeviceGetSupportsVibration() { + return s_yuzu_input_device_get_supports_vibration; +} + +jmethodID GetYuzuDeviceVibrate() { + return s_yuzu_input_device_vibrate; +} + +jmethodID GetYuzuDeviceGetAxes() { + return s_yuzu_input_device_get_axes; +} + +jmethodID GetYuzuDeviceHasKeys() { + return s_yuzu_input_device_has_keys; +} + +jmethodID GetAddNetPlayMessage() { + return s_add_netplay_message; +} + +jmethodID ClearChat() { + return s_clear_chat; +} #ifdef __cplusplus +extern "C" { +#endif + +jint JNI_OnLoad(JavaVM* vm, void* reserved) { + s_java_vm = vm; + + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) + return JNI_ERR; + + // Initialize Java classes + const jclass native_library_class = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary"); + s_native_library_class = reinterpret_cast(env->NewGlobalRef(native_library_class)); + s_disk_cache_progress_class = reinterpret_cast(env->NewGlobalRef( + env->FindClass("org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress"))); + s_load_callback_stage_class = reinterpret_cast(env->NewGlobalRef(env->FindClass( + "org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage"))); + + const jclass game_dir_class = env->FindClass("org/yuzu/yuzu_emu/model/GameDir"); + s_game_dir_class = reinterpret_cast(env->NewGlobalRef(game_dir_class)); + s_game_dir_constructor = env->GetMethodID(game_dir_class, "", "(Ljava/lang/String;Z)V"); + env->DeleteLocalRef(game_dir_class); + + // Initialize methods + s_exit_emulation_activity = + env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V"); + s_disk_cache_load_progress = + env->GetStaticMethodID(s_disk_cache_progress_class, "loadProgress", "(III)V"); + s_copy_to_storage = env->GetStaticMethodID(s_native_library_class, "copyFileToStorage", + "(Ljava/lang/String;Ljava/lang/String;)Z"); + s_file_exists = + env->GetStaticMethodID(s_native_library_class, "exists", "(Ljava/lang/String;)Z"); + s_file_extension = env->GetStaticMethodID(s_native_library_class, "getFileExtension", + "(Ljava/lang/String;)Ljava/lang/String;"); + s_on_emulation_started = + env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V"); + s_on_emulation_stopped = + env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V"); + s_on_program_changed = + env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V"); + + const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game"); + s_game_class = reinterpret_cast(env->NewGlobalRef(game_class)); + s_game_constructor = env->GetMethodID(game_class, "", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/" + "String;Ljava/lang/String;Ljava/lang/String;Z)V"); + s_game_title_field = env->GetFieldID(game_class, "title", "Ljava/lang/String;"); + s_game_path_field = env->GetFieldID(game_class, "path", "Ljava/lang/String;"); + s_game_program_id_field = env->GetFieldID(game_class, "programId", "Ljava/lang/String;"); + s_game_developer_field = env->GetFieldID(game_class, "developer", "Ljava/lang/String;"); + s_game_version_field = env->GetFieldID(game_class, "version", "Ljava/lang/String;"); + s_game_is_homebrew_field = env->GetFieldID(game_class, "isHomebrew", "Z"); + env->DeleteLocalRef(game_class); + + const jclass string_class = env->FindClass("java/lang/String"); + s_string_class = reinterpret_cast(env->NewGlobalRef(string_class)); + env->DeleteLocalRef(string_class); + + const jclass pair_class = env->FindClass("kotlin/Pair"); + s_pair_class = reinterpret_cast(env->NewGlobalRef(pair_class)); + s_pair_constructor = + env->GetMethodID(pair_class, "", "(Ljava/lang/Object;Ljava/lang/Object;)V"); + s_pair_first_field = env->GetFieldID(pair_class, "first", "Ljava/lang/Object;"); + s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;"); + env->DeleteLocalRef(pair_class); + + const jclass overlay_control_data_class = + env->FindClass("org/yuzu/yuzu_emu/overlay/model/OverlayControlData"); + s_overlay_control_data_class = + reinterpret_cast(env->NewGlobalRef(overlay_control_data_class)); + s_overlay_control_data_constructor = + env->GetMethodID(overlay_control_data_class, "", + "(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;)V"); + s_overlay_control_data_id_field = + env->GetFieldID(overlay_control_data_class, "id", "Ljava/lang/String;"); + s_overlay_control_data_enabled_field = + env->GetFieldID(overlay_control_data_class, "enabled", "Z"); + s_overlay_control_data_landscape_position_field = + env->GetFieldID(overlay_control_data_class, "landscapePosition", "Lkotlin/Pair;"); + s_overlay_control_data_portrait_position_field = + env->GetFieldID(overlay_control_data_class, "portraitPosition", "Lkotlin/Pair;"); + s_overlay_control_data_foldable_position_field = + env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;"); + env->DeleteLocalRef(overlay_control_data_class); + + const jclass patch_class = env->FindClass("org/yuzu/yuzu_emu/model/Patch"); + s_patch_class = reinterpret_cast(env->NewGlobalRef(patch_class)); + s_patch_constructor = env->GetMethodID( + patch_class, "", + "(ZLjava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"); + s_patch_enabled_field = env->GetFieldID(patch_class, "enabled", "Z"); + s_patch_name_field = env->GetFieldID(patch_class, "name", "Ljava/lang/String;"); + s_patch_version_field = env->GetFieldID(patch_class, "version", "Ljava/lang/String;"); + s_patch_type_field = env->GetFieldID(patch_class, "type", "I"); + s_patch_program_id_field = env->GetFieldID(patch_class, "programId", "Ljava/lang/String;"); + s_patch_title_id_field = env->GetFieldID(patch_class, "titleId", "Ljava/lang/String;"); + env->DeleteLocalRef(patch_class); + + const jclass double_class = env->FindClass("java/lang/Double"); + s_double_class = reinterpret_cast(env->NewGlobalRef(double_class)); + s_double_constructor = env->GetMethodID(double_class, "", "(D)V"); + s_double_value_field = env->GetFieldID(double_class, "value", "D"); + env->DeleteLocalRef(double_class); + + const jclass int_class = env->FindClass("java/lang/Integer"); + s_integer_class = reinterpret_cast(env->NewGlobalRef(int_class)); + s_integer_constructor = env->GetMethodID(int_class, "", "(I)V"); + s_integer_value_field = env->GetFieldID(int_class, "value", "I"); + env->DeleteLocalRef(int_class); + + const jclass boolean_class = env->FindClass("java/lang/Boolean"); + s_boolean_class = reinterpret_cast(env->NewGlobalRef(boolean_class)); + s_boolean_constructor = env->GetMethodID(boolean_class, "", "(Z)V"); + s_boolean_value_field = env->GetFieldID(boolean_class, "value", "Z"); + env->DeleteLocalRef(boolean_class); + + const jclass player_input_class = + env->FindClass("org/yuzu/yuzu_emu/features/input/model/PlayerInput"); + s_player_input_class = reinterpret_cast(env->NewGlobalRef(player_input_class)); + s_player_input_constructor = env->GetMethodID( + player_input_class, "", + "(Z[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ZIJJJJLjava/lang/String;Z)V"); + s_player_input_connected_field = env->GetFieldID(player_input_class, "connected", "Z"); + s_player_input_buttons_field = + env->GetFieldID(player_input_class, "buttons", "[Ljava/lang/String;"); + s_player_input_analogs_field = + env->GetFieldID(player_input_class, "analogs", "[Ljava/lang/String;"); + s_player_input_motions_field = + env->GetFieldID(player_input_class, "motions", "[Ljava/lang/String;"); + s_player_input_vibration_enabled_field = + env->GetFieldID(player_input_class, "vibrationEnabled", "Z"); + s_player_input_vibration_strength_field = + env->GetFieldID(player_input_class, "vibrationStrength", "I"); + s_player_input_body_color_left_field = + env->GetFieldID(player_input_class, "bodyColorLeft", "J"); + s_player_input_body_color_right_field = + env->GetFieldID(player_input_class, "bodyColorRight", "J"); + s_player_input_button_color_left_field = + env->GetFieldID(player_input_class, "buttonColorLeft", "J"); + s_player_input_button_color_right_field = + env->GetFieldID(player_input_class, "buttonColorRight", "J"); + s_player_input_profile_name_field = + env->GetFieldID(player_input_class, "profileName", "Ljava/lang/String;"); + s_player_input_use_system_vibrator_field = + env->GetFieldID(player_input_class, "useSystemVibrator", "Z"); + env->DeleteLocalRef(player_input_class); + + const jclass yuzu_input_device_interface = + env->FindClass("org/yuzu/yuzu_emu/features/input/YuzuInputDevice"); + s_yuzu_input_device_interface = + reinterpret_cast(env->NewGlobalRef(yuzu_input_device_interface)); + s_yuzu_input_device_get_name = + env->GetMethodID(yuzu_input_device_interface, "getName", "()Ljava/lang/String;"); + s_yuzu_input_device_get_guid = + env->GetMethodID(yuzu_input_device_interface, "getGUID", "()Ljava/lang/String;"); + s_yuzu_input_device_get_port = env->GetMethodID(yuzu_input_device_interface, "getPort", "()I"); + s_yuzu_input_device_get_supports_vibration = + env->GetMethodID(yuzu_input_device_interface, "getSupportsVibration", "()Z"); + s_yuzu_input_device_vibrate = env->GetMethodID(yuzu_input_device_interface, "vibrate", "(F)V"); + s_yuzu_input_device_get_axes = + env->GetMethodID(yuzu_input_device_interface, "getAxes", "()[Ljava/lang/Integer;"); + s_yuzu_input_device_has_keys = + env->GetMethodID(yuzu_input_device_interface, "hasKeys", "([I)[Z"); + env->DeleteLocalRef(yuzu_input_device_interface); + s_add_netplay_message = env->GetStaticMethodID(s_native_library_class, "addNetPlayMessage", + "(ILjava/lang/String;)V"); + s_clear_chat = env->GetStaticMethodID(s_native_library_class, "clearChat", "()V"); + + // Initialize Android Storage + Common::FS::Android::RegisterCallbacks(env, s_native_library_class); + + // Initialize applets + Common::Android::SoftwareKeyboard::InitJNI(env); + + return JNI_VERSION; +} + +void JNI_OnUnload(JavaVM* vm, void* reserved) { + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) { + return; } + + // UnInitialize Android Storage + Common::FS::Android::UnRegisterCallbacks(); + env->DeleteGlobalRef(s_native_library_class); + env->DeleteGlobalRef(s_disk_cache_progress_class); + env->DeleteGlobalRef(s_load_callback_stage_class); + env->DeleteGlobalRef(s_game_dir_class); + env->DeleteGlobalRef(s_game_class); + env->DeleteGlobalRef(s_string_class); + env->DeleteGlobalRef(s_pair_class); + env->DeleteGlobalRef(s_overlay_control_data_class); + env->DeleteGlobalRef(s_patch_class); + env->DeleteGlobalRef(s_double_class); + env->DeleteGlobalRef(s_integer_class); + env->DeleteGlobalRef(s_boolean_class); + env->DeleteGlobalRef(s_player_input_class); + env->DeleteGlobalRef(s_yuzu_input_device_interface); + + // UnInitialize applets + SoftwareKeyboard::CleanupJNI(env); + + AndroidMultiplayer::NetworkShutdown(); +} + +#ifdef __cplusplus +} #endif } // namespace Common::Android diff --git a/src/common/android/id_cache.h b/src/common/android/id_cache.h index c56ffcf5c6..413a3c2ec5 100644 --- a/src/common/android/id_cache.h +++ b/src/common/android/id_cache.h @@ -118,5 +118,4 @@ jmethodID GetYuzuDeviceHasKeys(); jmethodID GetAddNetPlayMessage(); jmethodID ClearChat(); - } // namespace Common::Android diff --git a/src/common/android/multiplayer/multiplayer.cpp b/src/common/android/multiplayer/multiplayer.cpp index 26bb800ce2..ec7912421a 100644 --- a/src/common/android/multiplayer/multiplayer.cpp +++ b/src/common/android/multiplayer/multiplayer.cpp @@ -6,23 +6,23 @@ #include "common/android/android_common.h" +#include "android/log.h" #include "core/core.h" #include "network/network.h" -#include "android/log.h" #include "common/settings.h" -#include "web_service/web_backend.h" #include "web_service/verify_user_jwt.h" +#include "web_service/web_backend.h" #include "web_service/web_result.h" -#include #include +#include namespace IDCache = Common::Android; -AndroidMultiplayer::AndroidMultiplayer(Core::System &system_, +AndroidMultiplayer::AndroidMultiplayer(Core::System& system_, std::shared_ptr session) - : system{system_}, announce_multiplayer_session(session) {} + : system{system_}, announce_multiplayer_session(session) {} AndroidMultiplayer::~AndroidMultiplayer() = default; @@ -31,8 +31,8 @@ void AndroidMultiplayer::AddNetPlayMessage(jint type, jstring msg) { IDCache::GetAddNetPlayMessage(), type, msg); } -void AndroidMultiplayer::AddNetPlayMessage(int type, const std::string &msg) { - JNIEnv *env = IDCache::GetEnvForThread(); +void AndroidMultiplayer::AddNetPlayMessage(int type, const std::string& msg) { + JNIEnv* env = IDCache::GetEnvForThread(); AddNetPlayMessage(type, Common::Android::ToJString(env, msg)); } @@ -50,91 +50,91 @@ bool AndroidMultiplayer::NetworkInit() { if (auto member = Network::GetRoomMember().lock()) { // register the network structs to use in slots and signals - member->BindOnStateChanged([this](const Network::RoomMember::State &state) { + member->BindOnStateChanged([this](const Network::RoomMember::State& state) { if (state == Network::RoomMember::State::Joined || state == Network::RoomMember::State::Moderator) { NetPlayStatus status; std::string msg; switch (state) { - case Network::RoomMember::State::Joined: - status = NetPlayStatus::ROOM_JOINED; - break; - case Network::RoomMember::State::Moderator: - status = NetPlayStatus::ROOM_MODERATOR; - break; - default: - return; + case Network::RoomMember::State::Joined: + status = NetPlayStatus::ROOM_JOINED; + break; + case Network::RoomMember::State::Moderator: + status = NetPlayStatus::ROOM_MODERATOR; + break; + default: + return; } AddNetPlayMessage(static_cast(status), msg); } }); - member->BindOnError([this](const Network::RoomMember::Error &error) { + member->BindOnError([this](const Network::RoomMember::Error& error) { NetPlayStatus status; std::string msg; switch (error) { - case Network::RoomMember::Error::LostConnection: - status = NetPlayStatus::LOST_CONNECTION; - break; - case Network::RoomMember::Error::HostKicked: - status = NetPlayStatus::HOST_KICKED; - break; - case Network::RoomMember::Error::UnknownError: - status = NetPlayStatus::UNKNOWN_ERROR; - break; - case Network::RoomMember::Error::NameCollision: - status = NetPlayStatus::NAME_COLLISION; - break; - case Network::RoomMember::Error::IpCollision: - status = NetPlayStatus::MAC_COLLISION; - break; - case Network::RoomMember::Error::WrongVersion: - status = NetPlayStatus::WRONG_VERSION; - break; - case Network::RoomMember::Error::WrongPassword: - status = NetPlayStatus::WRONG_PASSWORD; - break; - case Network::RoomMember::Error::CouldNotConnect: - status = NetPlayStatus::COULD_NOT_CONNECT; - break; - case Network::RoomMember::Error::RoomIsFull: - status = NetPlayStatus::ROOM_IS_FULL; - break; - case Network::RoomMember::Error::HostBanned: - status = NetPlayStatus::HOST_BANNED; - break; - case Network::RoomMember::Error::PermissionDenied: - status = NetPlayStatus::PERMISSION_DENIED; - break; - case Network::RoomMember::Error::NoSuchUser: - status = NetPlayStatus::NO_SUCH_USER; - break; + case Network::RoomMember::Error::LostConnection: + status = NetPlayStatus::LOST_CONNECTION; + break; + case Network::RoomMember::Error::HostKicked: + status = NetPlayStatus::HOST_KICKED; + break; + case Network::RoomMember::Error::UnknownError: + status = NetPlayStatus::UNKNOWN_ERROR; + break; + case Network::RoomMember::Error::NameCollision: + status = NetPlayStatus::NAME_COLLISION; + break; + case Network::RoomMember::Error::IpCollision: + status = NetPlayStatus::MAC_COLLISION; + break; + case Network::RoomMember::Error::WrongVersion: + status = NetPlayStatus::WRONG_VERSION; + break; + case Network::RoomMember::Error::WrongPassword: + status = NetPlayStatus::WRONG_PASSWORD; + break; + case Network::RoomMember::Error::CouldNotConnect: + status = NetPlayStatus::COULD_NOT_CONNECT; + break; + case Network::RoomMember::Error::RoomIsFull: + status = NetPlayStatus::ROOM_IS_FULL; + break; + case Network::RoomMember::Error::HostBanned: + status = NetPlayStatus::HOST_BANNED; + break; + case Network::RoomMember::Error::PermissionDenied: + status = NetPlayStatus::PERMISSION_DENIED; + break; + case Network::RoomMember::Error::NoSuchUser: + status = NetPlayStatus::NO_SUCH_USER; + break; } AddNetPlayMessage(static_cast(status), msg); }); member->BindOnStatusMessageReceived( - [this](const Network::StatusMessageEntry &status_message) { - NetPlayStatus status = NetPlayStatus::NO_ERROR; - std::string msg(status_message.nickname); - switch (status_message.type) { - case Network::IdMemberJoin: - status = NetPlayStatus::MEMBER_JOIN; - break; - case Network::IdMemberLeave: - status = NetPlayStatus::MEMBER_LEAVE; - break; - case Network::IdMemberKicked: - status = NetPlayStatus::MEMBER_KICKED; - break; - case Network::IdMemberBanned: - status = NetPlayStatus::MEMBER_BANNED; - break; - case Network::IdAddressUnbanned: - status = NetPlayStatus::ADDRESS_UNBANNED; - break; - } - AddNetPlayMessage(static_cast(status), msg); - }); - member->BindOnChatMessageReceived([this](const Network::ChatEntry &chat) { + [this](const Network::StatusMessageEntry& status_message) { + NetPlayStatus status = NetPlayStatus::NO_ERROR; + std::string msg(status_message.nickname); + switch (status_message.type) { + case Network::IdMemberJoin: + status = NetPlayStatus::MEMBER_JOIN; + break; + case Network::IdMemberLeave: + status = NetPlayStatus::MEMBER_LEAVE; + break; + case Network::IdMemberKicked: + status = NetPlayStatus::MEMBER_KICKED; + break; + case Network::IdMemberBanned: + status = NetPlayStatus::MEMBER_BANNED; + break; + case Network::IdAddressUnbanned: + status = NetPlayStatus::ADDRESS_UNBANNED; + break; + } + AddNetPlayMessage(static_cast(status), msg); + }); + member->BindOnChatMessageReceived([this](const Network::ChatEntry& chat) { NetPlayStatus status = NetPlayStatus::CHAT_MESSAGE; std::string msg(chat.nickname); msg += ": "; @@ -146,13 +146,10 @@ bool AndroidMultiplayer::NetworkInit() { return true; } -NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string &ipaddress, int port, - const std::string &username, - const std::string &preferredGameName, - const u64 &preferredGameId, - const std::string &password, - const std::string &room_name, int max_players, - bool isPublic) { +NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom( + const std::string& ipaddress, int port, const std::string& username, + const std::string& preferredGameName, const u64& preferredGameId, const std::string& password, + const std::string& room_name, int max_players, bool isPublic) { auto member = Network::GetRoomMember().lock(); if (!member) { return NetPlayStatus::NETWORK_ERROR; @@ -173,8 +170,8 @@ NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string &ipaddress // Placeholder game info const AnnounceMultiplayerRoom::GameInfo game{ - .name = preferredGameName, - .id = preferredGameId, + .name = preferredGameName, + .id = preferredGameId, }; port = (port == 0) ? Network::DefaultRoomPort : static_cast(port); @@ -205,8 +202,8 @@ NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string &ipaddress std::string token; // TODO(alekpop): properly handle the compile definition, it's not working right -//#ifdef ENABLE_WEB_SERVICE -// LOG_INFO(WebService, "Web Service enabled"); + // #ifdef ENABLE_WEB_SERVICE + // LOG_INFO(WebService, "Web Service enabled"); if (isPublic) { WebService::Client client(Settings::values.web_api_url.GetValue(), Settings::values.eden_username.GetValue(), @@ -220,9 +217,9 @@ NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string &ipaddress LOG_INFO(WebService, "Successfully requested external JWT: size={}", token.size()); } } -//#else -// LOG_INFO(WebService, "Web Service disabled"); -//#endif + // #else + // LOG_INFO(WebService, "Web Service disabled"); + // #endif member->Join(username, ipaddress.c_str(), static_cast(port), 0, Network::NoPreferredIP, password, token); @@ -241,17 +238,15 @@ NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string &ipaddress return NetPlayStatus::CREATE_ROOM_ERROR; } -NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string &ipaddress, int port, - const std::string &username, - const std::string &password) { +NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string& ipaddress, int port, + const std::string& username, + const std::string& password) { auto member = Network::GetRoomMember().lock(); if (!member) { return NetPlayStatus::NETWORK_ERROR; } - port = - (port == 0) ? Network::DefaultRoomPort : static_cast(port); - + port = (port == 0) ? Network::DefaultRoomPort : static_cast(port); if (member->GetState() == Network::RoomMember::State::Joining || member->IsConnected()) { return NetPlayStatus::ALREADY_IN_ROOM; @@ -275,7 +270,7 @@ NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string &ipaddress, return NetPlayStatus::WRONG_PASSWORD; } -void AndroidMultiplayer::NetPlaySendMessage(const std::string &msg) { +void AndroidMultiplayer::NetPlaySendMessage(const std::string& msg) { if (auto room = Network::GetRoomMember().lock()) { if (room->GetState() != Network::RoomMember::State::Joined && room->GetState() != Network::RoomMember::State::Moderator) { @@ -286,11 +281,11 @@ void AndroidMultiplayer::NetPlaySendMessage(const std::string &msg) { } } -void AndroidMultiplayer::NetPlayKickUser(const std::string &username) { +void AndroidMultiplayer::NetPlayKickUser(const std::string& username) { if (auto room = Network::GetRoomMember().lock()) { auto members = room->GetMemberInformation(); auto it = std::find_if(members.begin(), members.end(), - [&username](const Network::RoomMember::MemberInformation &member) { + [&username](const Network::RoomMember::MemberInformation& member) { return member.nickname == username; }); if (it != members.end()) { @@ -299,11 +294,11 @@ void AndroidMultiplayer::NetPlayKickUser(const std::string &username) { } } -void AndroidMultiplayer::NetPlayBanUser(const std::string &username) { +void AndroidMultiplayer::NetPlayBanUser(const std::string& username) { if (auto room = Network::GetRoomMember().lock()) { auto members = room->GetMemberInformation(); auto it = std::find_if(members.begin(), members.end(), - [&username](const Network::RoomMember::MemberInformation &member) { + [&username](const Network::RoomMember::MemberInformation& member) { return member.nickname == username; }); if (it != members.end()) { @@ -312,7 +307,7 @@ void AndroidMultiplayer::NetPlayBanUser(const std::string &username) { } } -void AndroidMultiplayer::NetPlayUnbanUser(const std::string &username) { +void AndroidMultiplayer::NetPlayUnbanUser(const std::string& username) { if (auto room = Network::GetRoomMember().lock()) { room->SendModerationRequest(Network::RoomMessageTypes::IdModUnban, username); } @@ -327,7 +322,7 @@ std::vector AndroidMultiplayer::NetPlayRoomInfo() { auto room_info = room->GetRoomInformation(); info_list.push_back(room_info.name + "|" + std::to_string(room_info.member_slots)); // all members - for (const auto &member: members) { + for (const auto& member : members) { info_list.push_back(member.nickname); } } @@ -385,30 +380,24 @@ std::vector AndroidMultiplayer::NetPlayGetPublicRooms() { if (auto session = announce_multiplayer_session.lock()) { auto rooms = session->GetRoomList(); - for (const auto &room: rooms) { - room_list.push_back(room.information.name + "|" + - (room.has_password ? "1" : "0") + "|" + - std::to_string(room.information.member_slots) + "|" + - room.ip + "|" + - std::to_string(room.information.port) + "|" + + for (const auto& room : rooms) { + room_list.push_back(room.information.name + "|" + (room.has_password ? "1" : "0") + + "|" + std::to_string(room.information.member_slots) + "|" + + room.ip + "|" + std::to_string(room.information.port) + "|" + room.information.description + "|" + room.information.host_username + "|" + std::to_string(room.information.preferred_game.id) + "|" + room.information.preferred_game.name + "|" + room.information.preferred_game.version); - for (const auto &member: room.members) { - room_list.push_back("MEMBER|" + room.information.name + "|" + - member.username + "|" + - member.nickname + "|" + - std::to_string(member.game.id) + "|" + - member.game.name); + for (const auto& member : room.members) { + room_list.push_back("MEMBER|" + room.information.name + "|" + member.username + + "|" + member.nickname + "|" + std::to_string(member.game.id) + + "|" + member.game.name); } } - } return room_list; - } std::vector AndroidMultiplayer::NetPlayGetBanList() { @@ -417,27 +406,28 @@ std::vector AndroidMultiplayer::NetPlayGetBanList() { auto [username_bans, ip_bans] = room->GetBanList(); // Add username bans - for (const auto &username: username_bans) { + for (const auto& username : username_bans) { ban_list.push_back(username); } // Add IP bans - for (const auto &ip: ip_bans) { + for (const auto& ip : ip_bans) { ban_list.push_back(ip); } } return ban_list; } -std::unique_ptr AndroidMultiplayer::CreateVerifyBackend(bool use_validation) { +std::unique_ptr AndroidMultiplayer::CreateVerifyBackend( + bool use_validation) { std::unique_ptr verify_backend; if (use_validation) { -//#ifdef ENABLE_WEB_SERVICE + // #ifdef ENABLE_WEB_SERVICE verify_backend = std::make_unique(Settings::values.web_api_url.GetValue()); -//#else -// verify_backend = std::make_unique(); -//#endif + // #else + // verify_backend = std::make_unique(); + // #endif } else { verify_backend = std::make_unique(); } diff --git a/src/common/android/multiplayer/multiplayer.h b/src/common/android/multiplayer/multiplayer.h index 39ea80f5b7..0b01a95594 100644 --- a/src/common/android/multiplayer/multiplayer.h +++ b/src/common/android/multiplayer/multiplayer.h @@ -7,13 +7,13 @@ #include #include -#include #include +#include namespace Core { - class System; - class AnnounceMultiplayerSession; -} +class System; +class AnnounceMultiplayerSession; +} // namespace Core enum class NetPlayStatus : s32 { NO_ERROR, @@ -63,13 +63,14 @@ public: void ClearChat(); - NetPlayStatus NetPlayCreateRoom(const std::string &ipaddress, int port, - const std::string &username, const std::string &preferredGameName, - const u64 &preferredGameId, const std::string &password, - const std::string &room_name, int max_players, bool isPublic); + NetPlayStatus NetPlayCreateRoom(const std::string& ipaddress, int port, + const std::string& username, + const std::string& preferredGameName, + const u64& preferredGameId, const std::string& password, + const std::string& room_name, int max_players, bool isPublic); - NetPlayStatus NetPlayJoinRoom(const std::string &ipaddress, int port, - const std::string &username, const std::string &password); + NetPlayStatus NetPlayJoinRoom(const std::string& ipaddress, int port, + const std::string& username, const std::string& password); std::vector NetPlayRoomInfo(); @@ -79,11 +80,11 @@ public: bool NetPlayIsModerator(); - void NetPlaySendMessage(const std::string &msg); + void NetPlaySendMessage(const std::string& msg); - void NetPlayKickUser(const std::string &username); + void NetPlayKickUser(const std::string& username); - void NetPlayBanUser(const std::string &username); + void NetPlayBanUser(const std::string& username); void NetPlayLeaveRoom(); @@ -91,12 +92,12 @@ public: std::vector NetPlayGetBanList(); - void NetPlayUnbanUser(const std::string &username); + void NetPlayUnbanUser(const std::string& username); std::vector NetPlayGetPublicRooms(); private: Core::System& system; - static std::unique_ptr CreateVerifyBackend(bool use_validation) ; + static std::unique_ptr CreateVerifyBackend(bool use_validation); std::weak_ptr announce_multiplayer_session; }; diff --git a/src/common/concepts.h b/src/common/concepts.h index 61df1d32a2..a9acff3e79 100644 --- a/src/common/concepts.h +++ b/src/common/concepts.h @@ -16,9 +16,9 @@ concept IsContiguousContainer = std::contiguous_iterator; // is available on all supported platforms. template concept DerivedFrom = requires { - std::is_base_of_v; - std::is_convertible_v; - }; + std::is_base_of_v; + std::is_convertible_v; +}; // TODO: Replace with std::convertible_to when libc++ implements it. template diff --git a/src/common/device_power_state.cpp b/src/common/device_power_state.cpp index 2dfa7dc305..3da0c1f5d2 100644 --- a/src/common/device_power_state.cpp +++ b/src/common/device_power_state.cpp @@ -27,76 +27,73 @@ extern std::atomic g_has_battery; namespace Common { - PowerStatus GetPowerStatus() - { - PowerStatus info; +PowerStatus GetPowerStatus() { + PowerStatus info; #if defined(_WIN32) - SYSTEM_POWER_STATUS status; - if (GetSystemPowerStatus(&status)) { - if (status.BatteryFlag == 128) { - info.has_battery = false; - } else { - info.percentage = status.BatteryLifePercent; - info.charging = (status.BatteryFlag & 8) != 0; - } - } else { + SYSTEM_POWER_STATUS status; + if (GetSystemPowerStatus(&status)) { + if (status.BatteryFlag == 128) { info.has_battery = false; + } else { + info.percentage = status.BatteryLifePercent; + info.charging = (status.BatteryFlag & 8) != 0; } + } else { + info.has_battery = false; + } #elif defined(__ANDROID__) - info.percentage = g_battery_percentage.load(std::memory_order_relaxed); - info.charging = g_is_charging.load(std::memory_order_relaxed); - info.has_battery = g_has_battery.load(std::memory_order_relaxed); + info.percentage = g_battery_percentage.load(std::memory_order_relaxed); + info.charging = g_is_charging.load(std::memory_order_relaxed); + info.has_battery = g_has_battery.load(std::memory_order_relaxed); #elif defined(__APPLE__) && TARGET_OS_MAC - CFTypeRef info_ref = IOPSCopyPowerSourcesInfo(); - CFArrayRef sources = IOPSCopyPowerSourcesList(info_ref); - if (CFArrayGetCount(sources) > 0) { - CFDictionaryRef battery = - IOPSGetPowerSourceDescription(info_ref, CFArrayGetValueAtIndex(sources, 0)); + CFTypeRef info_ref = IOPSCopyPowerSourcesInfo(); + CFArrayRef sources = IOPSCopyPowerSourcesList(info_ref); + if (CFArrayGetCount(sources) > 0) { + CFDictionaryRef battery = + IOPSGetPowerSourceDescription(info_ref, CFArrayGetValueAtIndex(sources, 0)); - CFNumberRef curNum = - (CFNumberRef)CFDictionaryGetValue(battery, CFSTR(kIOPSCurrentCapacityKey)); - CFNumberRef maxNum = - (CFNumberRef)CFDictionaryGetValue(battery, CFSTR(kIOPSMaxCapacityKey)); - int cur = 0, max = 0; - CFNumberGetValue(curNum, kCFNumberIntType, &cur); - CFNumberGetValue(maxNum, kCFNumberIntType, &max); + CFNumberRef curNum = + (CFNumberRef)CFDictionaryGetValue(battery, CFSTR(kIOPSCurrentCapacityKey)); + CFNumberRef maxNum = (CFNumberRef)CFDictionaryGetValue(battery, CFSTR(kIOPSMaxCapacityKey)); + int cur = 0, max = 0; + CFNumberGetValue(curNum, kCFNumberIntType, &cur); + CFNumberGetValue(maxNum, kCFNumberIntType, &max); - if (max > 0) - info.percentage = (cur * 100) / max; + if (max > 0) + info.percentage = (cur * 100) / max; - CFBooleanRef isCharging = - (CFBooleanRef)CFDictionaryGetValue(battery, CFSTR(kIOPSIsChargingKey)); - info.charging = CFBooleanGetValue(isCharging); - } else { - info.has_battery = false; - } - CFRelease(sources); - CFRelease(info_ref); + CFBooleanRef isCharging = + (CFBooleanRef)CFDictionaryGetValue(battery, CFSTR(kIOPSIsChargingKey)); + info.charging = CFBooleanGetValue(isCharging); + } else { + info.has_battery = false; + } + CFRelease(sources); + CFRelease(info_ref); #elif defined(__linux__) - const char* battery_path = "/sys/class/power_supply/BAT0/"; + const char* battery_path = "/sys/class/power_supply/BAT0/"; - std::ifstream capFile(std::string(battery_path) + "capacity"); - if (capFile) { - capFile >> info.percentage; - } - else { - info.has_battery = false; - } - - std::ifstream statFile(std::string(battery_path) + "status"); - if (statFile) { - std::string status; - std::getline(statFile, status); - info.charging = (status == "Charging"); - } -#else + std::ifstream capFile(std::string(battery_path) + "capacity"); + if (capFile) { + capFile >> info.percentage; + } else { info.has_battery = false; + } + + std::ifstream statFile(std::string(battery_path) + "status"); + if (statFile) { + std::string status; + std::getline(statFile, status); + info.charging = (status == "Charging"); + } +#else + info.has_battery = false; #endif - return info; - } + return info; } +} // namespace Common diff --git a/src/common/expected.h b/src/common/expected.h index 5fccfbcbdd..c62e43164d 100644 --- a/src/common/expected.h +++ b/src/common/expected.h @@ -598,14 +598,14 @@ public: template >* = nullptr, std::enable_if_t>* = nullptr> constexpr explicit Expected(Unexpected&& e) noexcept(std::is_nothrow_constructible_v) - : impl_base{unexpect_t{}, std::move(e.value())}, ctor_base{ - detail::default_constructor_tag{}} {} + : impl_base{unexpect_t{}, std::move(e.value())}, + ctor_base{detail::default_constructor_tag{}} {} template >* = nullptr, std::enable_if_t>* = nullptr> constexpr Expected(Unexpected&& e) noexcept(std::is_nothrow_constructible_v) - : impl_base{unexpect_t{}, std::move(e.value())}, ctor_base{ - detail::default_constructor_tag{}} {} + : impl_base{unexpect_t{}, std::move(e.value())}, + ctor_base{detail::default_constructor_tag{}} {} template >* = nullptr> constexpr explicit Expected(unexpect_t, Args&&... args) diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp index e032360961..eb0950ec33 100644 --- a/src/common/fs/path_util.cpp +++ b/src/common/fs/path_util.cpp @@ -88,9 +88,8 @@ public: } void CreateEdenPaths() { - std::for_each(eden_paths.begin(), eden_paths.end(), [](auto &path) { - void(FS::CreateDir(path.second)); - }); + std::for_each(eden_paths.begin(), eden_paths.end(), + [](auto& path) { void(FS::CreateDir(path.second)); }); } void SetEdenPathImpl(EdenPath eden_path, const fs::path& new_path) { @@ -116,9 +115,13 @@ public: eden_path_cache = eden_path / CACHE_DIR; eden_path_config = eden_path / CONFIG_DIR; -#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetAppDataRoamingDirectory() / upperName##_DIR); \ - GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetAppDataRoamingDirectory() / upperName##_DIR / CONFIG_DIR); \ - GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetAppDataRoamingDirectory() / upperName##_DIR / CACHE_DIR); +#define LEGACY_PATH(titleName, upperName) \ + GenerateLegacyPath(LegacyPath::titleName##Dir, \ + GetAppDataRoamingDirectory() / upperName##_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##ConfigDir, \ + GetAppDataRoamingDirectory() / upperName##_DIR / CONFIG_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##CacheDir, \ + GetAppDataRoamingDirectory() / upperName##_DIR / CACHE_DIR); LEGACY_PATH(Citron, CITRON) LEGACY_PATH(Sudachi, SUDACHI) @@ -143,9 +146,13 @@ public: eden_path_config = GetDataDirectory("XDG_CONFIG_HOME") / EDEN_DIR; } -#define LEGACY_PATH(titleName, upperName) GenerateLegacyPath(LegacyPath::titleName##Dir, GetDataDirectory("XDG_DATA_HOME") / upperName##_DIR); \ - GenerateLegacyPath(LegacyPath::titleName##ConfigDir, GetDataDirectory("XDG_CONFIG_HOME") / upperName##_DIR); \ - GenerateLegacyPath(LegacyPath::titleName##CacheDir, GetDataDirectory("XDG_CACHE_HOME") / upperName##_DIR); +#define LEGACY_PATH(titleName, upperName) \ + GenerateLegacyPath(LegacyPath::titleName##Dir, \ + GetDataDirectory("XDG_DATA_HOME") / upperName##_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##ConfigDir, \ + GetDataDirectory("XDG_CONFIG_HOME") / upperName##_DIR); \ + GenerateLegacyPath(LegacyPath::titleName##CacheDir, \ + GetDataDirectory("XDG_CACHE_HOME") / upperName##_DIR); LEGACY_PATH(Citron, CITRON) LEGACY_PATH(Sudachi, SUDACHI) @@ -301,8 +308,7 @@ void SetEdenPath(EdenPath eden_path, const fs::path& new_path) { PathManagerImpl::GetInstance().SetEdenPathImpl(eden_path, new_path); } -void CreateEdenPaths() -{ +void CreateEdenPaths() { PathManagerImpl::GetInstance().CreateEdenPaths(); } diff --git a/src/common/heap_tracker.cpp b/src/common/heap_tracker.cpp index 6832087959..abdd200c45 100644 --- a/src/common/heap_tracker.cpp +++ b/src/common/heap_tracker.cpp @@ -34,6 +34,8 @@ HeapTracker::~HeapTracker() = default; void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm, bool is_separate_heap) { + bool rebuild_required = false; + // When mapping other memory, map pages immediately. if (!is_separate_heap) { m_buffer.Map(virtual_offset, host_offset, length, perm, false); @@ -55,11 +57,29 @@ void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length, // Insert into mappings. m_map_count++; - m_mappings.insert(*map); + const auto it = m_mappings.insert(*map); + + // Update tick before possible rebuild. + it->tick = m_tick++; + + // Check if we need to rebuild. + if (m_resident_map_count >= m_max_resident_map_count) { + rebuild_required = true; + } + + // Map the area. + m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false); + + // This map is now resident. + it->is_resident = true; + m_resident_map_count++; + m_resident_mappings.insert(*it); } - // Finally, map. - this->DeferredMapSeparateHeap(virtual_offset); + if (rebuild_required) { + // A rebuild was required, so perform it now. + this->RebuildSeparateHeapAddressSpace(); + } } void HeapTracker::Unmap(size_t virtual_offset, size_t size, bool is_separate_heap) { @@ -157,51 +177,6 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p } } -bool HeapTracker::DeferredMapSeparateHeap(u8* fault_address) { - if (m_buffer.IsInVirtualRange(fault_address)) { - return this->DeferredMapSeparateHeap(fault_address - m_buffer.VirtualBasePointer()); - } - - return false; -} - -bool HeapTracker::DeferredMapSeparateHeap(size_t virtual_offset) { - bool rebuild_required = false; - - { - std::scoped_lock lk{m_lock}; - - // Check to ensure this was a non-resident separate heap mapping. - const auto it = this->GetNearestHeapMapLocked(virtual_offset); - if (it == m_mappings.end() || it->is_resident) { - return false; - } - - // Update tick before possible rebuild. - it->tick = m_tick++; - - // Check if we need to rebuild. - if (m_resident_map_count > m_max_resident_map_count) { - rebuild_required = true; - } - - // Map the area. - m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false); - - // This map is now resident. - it->is_resident = true; - m_resident_map_count++; - m_resident_mappings.insert(*it); - } - - if (rebuild_required) { - // A rebuild was required, so perform it now. - this->RebuildSeparateHeapAddressSpace(); - } - - return true; -} - void HeapTracker::RebuildSeparateHeapAddressSpace() { std::scoped_lock lk{m_rebuild_lock, m_lock}; diff --git a/src/common/intrusive_list.h b/src/common/intrusive_list.h index d330dc1c22..56eee8839f 100644 --- a/src/common/intrusive_list.h +++ b/src/common/intrusive_list.h @@ -538,7 +538,7 @@ public: template > class IntrusiveListMemberTraits; -template +template class IntrusiveListMemberTraits { public: using ListType = IntrusiveList; @@ -566,7 +566,7 @@ private: template > class IntrusiveListMemberTraitsByNonConstexprOffsetOf; -template +template class IntrusiveListMemberTraitsByNonConstexprOffsetOf { public: using ListType = IntrusiveList; diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h index bc2940fa0a..27ce59cd0c 100644 --- a/src/common/intrusive_red_black_tree.h +++ b/src/common/intrusive_red_black_tree.h @@ -238,10 +238,8 @@ public: template concept HasRedBlackKeyType = requires { - { - std::is_same::value - } -> std::convertible_to; - }; + { std::is_same::value } -> std::convertible_to; +}; namespace impl { @@ -497,7 +495,7 @@ public: template > class IntrusiveRedBlackTreeMemberTraits; -template +template class IntrusiveRedBlackTreeMemberTraits { public: template @@ -530,7 +528,7 @@ private: template > class IntrusiveRedBlackTreeMemberTraitsDeferredAssert; -template +template class IntrusiveRedBlackTreeMemberTraitsDeferredAssert { public: template diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index ff07ab68eb..921778e18e 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -90,8 +90,8 @@ public: auto old_filename = filename; old_filename += ".old.txt"; - // Existence checks are done within the functions themselves. - // We don't particularly care if these succeed or not. + // Existence checks are done within the functions themselves. + // We don't particularly care if these succeed or not. static_cast(FS::RemoveFile(old_filename)); static_cast(FS::RenameFile(filename, old_filename)); diff --git a/src/common/minicoro.h b/src/common/minicoro.h index 9f1dbcafb3..f4113dcbe5 100644 --- a/src/common/minicoro.h +++ b/src/common/minicoro.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* Minimal asymmetric stackful cross-platform coroutine library in pure C. minicoro - v0.2.0 - 15/Nov/2023 @@ -467,7 +470,7 @@ extern "C" { #ifdef MCO_NO_MULTITHREAD #define MCO_THREAD_LOCAL #else -#ifdef thread_local +#if defined(thread_local) || __STDC_VERSION__ >= 202311L || defined(__sun__) #define MCO_THREAD_LOCAL thread_local #elif __STDC_VERSION__ >= 201112 && !defined(__STDC_NO_THREADS__) #define MCO_THREAD_LOCAL _Thread_local diff --git a/src/common/multi_level_page_table.h b/src/common/multi_level_page_table.h index 31f6676a06..4eefb4d5f8 100644 --- a/src/common/multi_level_page_table.h +++ b/src/common/multi_level_page_table.h @@ -25,12 +25,12 @@ public: MultiLevelPageTable(MultiLevelPageTable&& other) noexcept : address_space_bits{std::exchange(other.address_space_bits, 0)}, - first_level_bits{std::exchange(other.first_level_bits, 0)}, page_bits{std::exchange( - other.page_bits, 0)}, + first_level_bits{std::exchange(other.first_level_bits, 0)}, + page_bits{std::exchange(other.page_bits, 0)}, first_level_shift{std::exchange(other.first_level_shift, 0)}, first_level_chunk_size{std::exchange(other.first_level_chunk_size, 0)}, - first_level_map{std::move(other.first_level_map)}, base_ptr{std::exchange(other.base_ptr, - nullptr)} {} + first_level_map{std::move(other.first_level_map)}, + base_ptr{std::exchange(other.base_ptr, nullptr)} {} MultiLevelPageTable& operator=(MultiLevelPageTable&& other) noexcept { address_space_bits = std::exchange(other.address_space_bits, 0); diff --git a/src/common/parent_of_member.h b/src/common/parent_of_member.h index 8e03f17d8b..f141b33ac7 100644 --- a/src/common/parent_of_member.h +++ b/src/common/parent_of_member.h @@ -92,7 +92,7 @@ struct OffsetOfCalculator { } template - static constexpr std::ptrdiff_t OffsetOfImpl(MemberType ParentType::*member, + static constexpr std::ptrdiff_t OffsetOfImpl(MemberType ParentType::* member, CurUnion& cur_union) { constexpr size_t Offset = CurUnion::GetOffset(); const auto target = std::addressof(GetPointer(U.parent)->*member); @@ -111,7 +111,7 @@ struct OffsetOfCalculator { Offset); } - static constexpr std::ptrdiff_t OffsetOf(MemberType ParentType::*member) { + static constexpr std::ptrdiff_t OffsetOf(MemberType ParentType::* member) { return OffsetOfImpl(member, U.first_union); } }; diff --git a/src/common/point.h b/src/common/point.h index 6491856ea8..329f5a424a 100644 --- a/src/common/point.h +++ b/src/common/point.h @@ -34,12 +34,12 @@ struct Point { .y = static_cast(value op rhs.y), \ }; \ } \ - friend constexpr Point& operator compound_op(Point& lhs, const Point& rhs) noexcept { \ + friend constexpr Point& operator compound_op(Point & lhs, const Point & rhs) noexcept { \ lhs.x = static_cast(lhs.x op rhs.x); \ lhs.y = static_cast(lhs.y op rhs.y); \ return lhs; \ } \ - friend constexpr Point& operator compound_op(Point& lhs, T value) noexcept { \ + friend constexpr Point& operator compound_op(Point & lhs, T value) noexcept { \ lhs.x = static_cast(lhs.x op value); \ lhs.y = static_cast(lhs.y op value); \ return lhs; \ diff --git a/src/common/polyfill_ranges.h b/src/common/polyfill_ranges.h index 512dbcbcb7..ea542fe120 100644 --- a/src/common/polyfill_ranges.h +++ b/src/common/polyfill_ranges.h @@ -18,9 +18,9 @@ namespace ranges { template concept range = requires(T& t) { - begin(t); - end(t); - }; + begin(t); + end(t); +}; template concept input_range = range; diff --git a/src/common/polyfill_thread.h b/src/common/polyfill_thread.h index 12e59a8939..ca04810554 100644 --- a/src/common/polyfill_thread.h +++ b/src/common/polyfill_thread.h @@ -339,7 +339,9 @@ void CondvarWait(Condvar& cv, std::unique_lock& lk, std::stop_token token, } std::stop_callback callback(token, [&] { - { std::scoped_lock lk2{*lk.mutex()}; } + { + std::scoped_lock lk2{*lk.mutex()}; + } cv.notify_all(); }); diff --git a/src/common/settings.h b/src/common/settings.h index 551e66c57e..468452da23 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -150,7 +150,7 @@ struct Values { Setting net_connect_applet_mode{linkage, AppletMode::LLE, "net_connect_applet_mode", Category::LibraryApplet}; Setting player_select_applet_mode{ - linkage, AppletMode::LLE, "player_select_applet_mode", Category::LibraryApplet}; + linkage, AppletMode::LLE, "player_select_applet_mode", Category::LibraryApplet}; Setting swkbd_applet_mode{linkage, AppletMode::HLE, "swkbd_applet_mode", Category::LibraryApplet}; Setting mii_edit_applet_mode{linkage, AppletMode::LLE, "mii_edit_applet_mode", @@ -160,13 +160,13 @@ struct Values { Setting shop_applet_mode{linkage, AppletMode::HLE, "shop_applet_mode", Category::LibraryApplet}; Setting photo_viewer_applet_mode{ - linkage, AppletMode::LLE, "photo_viewer_applet_mode", Category::LibraryApplet}; + linkage, AppletMode::LLE, "photo_viewer_applet_mode", Category::LibraryApplet}; Setting offline_web_applet_mode{linkage, AppletMode::LLE, "offline_web_applet_mode", Category::LibraryApplet}; Setting login_share_applet_mode{linkage, AppletMode::HLE, "login_share_applet_mode", Category::LibraryApplet}; Setting wifi_web_auth_applet_mode{ - linkage, AppletMode::HLE, "wifi_web_auth_applet_mode", Category::LibraryApplet}; + linkage, AppletMode::HLE, "wifi_web_auth_applet_mode", Category::LibraryApplet}; Setting my_page_applet_mode{linkage, AppletMode::LLE, "my_page_applet_mode", Category::LibraryApplet}; @@ -174,13 +174,13 @@ struct Values { SwitchableSetting sink_id{linkage, AudioEngine::Auto, "output_engine", Category::Audio, Specialization::RuntimeList}; SwitchableSetting audio_output_device_id{ - linkage, "auto", "output_device", Category::Audio, Specialization::RuntimeList}; + linkage, "auto", "output_device", Category::Audio, Specialization::RuntimeList}; SwitchableSetting audio_input_device_id{ - linkage, "auto", "input_device", Category::Audio, Specialization::RuntimeList}; + linkage, "auto", "input_device", Category::Audio, Specialization::RuntimeList}; SwitchableSetting sound_index{ - linkage, AudioMode::Stereo, AudioMode::Mono, AudioMode::Surround, - "sound_index", Category::SystemAudio, Specialization::Default, true, - true}; + linkage, AudioMode::Stereo, AudioMode::Mono, AudioMode::Surround, + "sound_index", Category::SystemAudio, Specialization::Default, true, + true}; SwitchableSetting volume{linkage, 100, 0, @@ -191,9 +191,9 @@ struct Values { true, true}; Setting audio_muted{ - linkage, false, "audio_muted", Category::Audio, Specialization::Default, true, true}; + linkage, false, "audio_muted", Category::Audio, Specialization::Default, true, true}; Setting dump_audio_commands{ - linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false}; + linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false}; // Core SwitchableSetting use_multi_core{linkage, true, "use_multi_core", Category::Core}; @@ -206,7 +206,7 @@ struct Values { Specialization::Default, true}; SwitchableSetting use_speed_limit{ - linkage, true, "use_speed_limit", Category::Core, Specialization::Paired, true, true}; + linkage, true, "use_speed_limit", Category::Core, Specialization::Paired, true, true}; SwitchableSetting speed_limit{linkage, 100, 0, @@ -217,7 +217,8 @@ struct Values { true, true, &use_speed_limit}; - SwitchableSetting sync_core_speed{linkage, false, "sync_core_speed", Category::Core, Specialization::Default}; + SwitchableSetting sync_core_speed{linkage, false, "sync_core_speed", Category::Core, + Specialization::Default}; // Memory #ifdef HAS_NCE @@ -243,29 +244,14 @@ struct Values { CpuAccuracy::Auto, CpuAccuracy::Paranoid, "cpu_accuracy", Category::Cpu}; - SwitchableSetting use_fast_cpu_time{linkage, - false, - "use_fast_cpu_time", - Category::Cpu, - Specialization::Paired, - true, - true}; - SwitchableSetting fast_cpu_time{linkage, - CpuClock::Boost, - "fast_cpu_time", - Category::Cpu, - Specialization::Default, - true, - true, - &use_fast_cpu_time}; + SwitchableSetting use_fast_cpu_time{ + linkage, false, "use_fast_cpu_time", Category::Cpu, Specialization::Paired, true, true}; + SwitchableSetting fast_cpu_time{ + linkage, CpuClock::Boost, "fast_cpu_time", Category::Cpu, Specialization::Default, true, + true, &use_fast_cpu_time}; - SwitchableSetting use_custom_cpu_ticks{linkage, - false, - "use_custom_cpu_ticks", - Category::Cpu, - Specialization::Paired, - true, - true}; + SwitchableSetting use_custom_cpu_ticks{ + linkage, false, "use_custom_cpu_ticks", Category::Cpu, Specialization::Paired, true, true}; SwitchableSetting cpu_ticks{linkage, 16000, @@ -302,29 +288,29 @@ struct Values { SwitchableSetting cpuopt_unsafe_unfuse_fma{linkage, true, "cpuopt_unsafe_unfuse_fma", Category::CpuUnsafe}; SwitchableSetting cpuopt_unsafe_reduce_fp_error{ - linkage, true, "cpuopt_unsafe_reduce_fp_error", Category::CpuUnsafe}; + linkage, true, "cpuopt_unsafe_reduce_fp_error", Category::CpuUnsafe}; SwitchableSetting cpuopt_unsafe_ignore_standard_fpcr{ - linkage, true, "cpuopt_unsafe_ignore_standard_fpcr", Category::CpuUnsafe}; + linkage, true, "cpuopt_unsafe_ignore_standard_fpcr", Category::CpuUnsafe}; SwitchableSetting cpuopt_unsafe_inaccurate_nan{ - linkage, true, "cpuopt_unsafe_inaccurate_nan", Category::CpuUnsafe}; + linkage, true, "cpuopt_unsafe_inaccurate_nan", Category::CpuUnsafe}; SwitchableSetting cpuopt_unsafe_fastmem_check{ - linkage, true, "cpuopt_unsafe_fastmem_check", Category::CpuUnsafe}; + linkage, true, "cpuopt_unsafe_fastmem_check", Category::CpuUnsafe}; SwitchableSetting cpuopt_unsafe_ignore_global_monitor{ - linkage, true, "cpuopt_unsafe_ignore_global_monitor", Category::CpuUnsafe}; + linkage, true, "cpuopt_unsafe_ignore_global_monitor", Category::CpuUnsafe}; // Renderer SwitchableSetting renderer_backend{ - linkage, RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, - "backend", Category::Renderer}; + linkage, RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, + "backend", Category::Renderer}; SwitchableSetting shader_backend{ - linkage, ShaderBackend::SpirV, ShaderBackend::Glsl, ShaderBackend::SpirV, - "shader_backend", Category::Renderer, Specialization::RuntimeList}; + linkage, ShaderBackend::SpirV, ShaderBackend::Glsl, ShaderBackend::SpirV, + "shader_backend", Category::Renderer, Specialization::RuntimeList}; SwitchableSetting vulkan_device{linkage, 0, "vulkan_device", Category::Renderer, Specialization::RuntimeList}; SwitchableSetting enable_raii{linkage, false, "enable_raii", Category::Renderer}; #ifdef __ANDROID__ - SwitchableSetting frame_interpolation{linkage, true, "frame_interpolation", Category::Renderer, - Specialization::RuntimeList}; + SwitchableSetting frame_interpolation{linkage, true, "frame_interpolation", + Category::Renderer, Specialization::RuntimeList}; SwitchableSetting frame_skipping{linkage, false, "frame_skipping", Category::Renderer, Specialization::RuntimeList}; #endif @@ -337,7 +323,7 @@ struct Values { "optimize_spirv_output", Category::Renderer}; SwitchableSetting use_asynchronous_gpu_emulation{ - linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer}; + linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer}; SwitchableSetting accelerate_astc{linkage, #ifdef ANDROID AstcDecodeMode::Cpu, @@ -349,9 +335,9 @@ struct Values { "accelerate_astc", Category::Renderer}; SwitchableSetting vsync_mode{ - linkage, VSyncMode::Fifo, VSyncMode::Immediate, VSyncMode::FifoRelaxed, - "use_vsync", Category::Renderer, Specialization::RuntimeList, true, - true}; + linkage, VSyncMode::Fifo, VSyncMode::Immediate, VSyncMode::FifoRelaxed, + "use_vsync", Category::Renderer, Specialization::RuntimeList, true, + true}; SwitchableSetting nvdec_emulation{linkage, NvdecEmulation::Gpu, "nvdec_emulation", Category::Renderer}; // *nix platforms may have issues with the borderless windowed fullscreen mode. @@ -408,11 +394,11 @@ struct Values { true}; SwitchableSetting bg_red{ - linkage, 0, "bg_red", Category::Renderer, Specialization::Default, true, true}; + linkage, 0, "bg_red", Category::Renderer, Specialization::Default, true, true}; SwitchableSetting bg_green{ - linkage, 0, "bg_green", Category::Renderer, Specialization::Default, true, true}; + linkage, 0, "bg_green", Category::Renderer, Specialization::Default, true, true}; SwitchableSetting bg_blue{ - linkage, 0, "bg_blue", Category::Renderer, Specialization::Default, true, true}; + linkage, 0, "bg_blue", Category::Renderer, Specialization::Default, true, true}; SwitchableSetting gpu_accuracy{linkage, #ifdef ANDROID @@ -476,13 +462,9 @@ struct Values { Category::RendererAdvanced}; SwitchableSetting use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders", Category::RendererAdvanced}; - SwitchableSetting use_fast_gpu_time{linkage, - true, - "use_fast_gpu_time", - Category::RendererAdvanced, - Specialization::Paired, - true, - true}; + SwitchableSetting use_fast_gpu_time{ + linkage, true, "use_fast_gpu_time", Category::RendererAdvanced, Specialization::Paired, + true, true}; SwitchableSetting fast_gpu_time{linkage, GpuOverclock::Low, @@ -507,17 +489,15 @@ struct Values { SwitchableSetting barrier_feedback_loops{linkage, true, "barrier_feedback_loops", Category::RendererAdvanced}; - SwitchableSetting dyna_state{linkage, - 0, - 0, - 3, - "dyna_state", - Category::RendererExtensions, - Specialization::Scalar}; + SwitchableSetting dyna_state{ + linkage, 0, 0, 3, "dyna_state", Category::RendererExtensions, Specialization::Scalar}; - SwitchableSetting provoking_vertex{linkage, false, "provoking_vertex", Category::RendererExtensions}; - SwitchableSetting descriptor_indexing{linkage, false, "descriptor_indexing", Category::RendererExtensions}; - SwitchableSetting sample_shading{linkage, false, "sample_shading", Category::RendererExtensions}; + SwitchableSetting provoking_vertex{linkage, false, "provoking_vertex", + Category::RendererExtensions}; + SwitchableSetting descriptor_indexing{linkage, false, "descriptor_indexing", + Category::RendererExtensions}; + SwitchableSetting sample_shading{linkage, false, "sample_shading", + Category::RendererExtensions}; Setting renderer_debug{linkage, false, "debug", Category::RendererDebug}; Setting renderer_shader_feedback{linkage, false, "shader_feedback", @@ -525,19 +505,16 @@ struct Values { Setting enable_nsight_aftermath{linkage, false, "nsight_aftermath", Category::RendererDebug}; Setting disable_shader_loop_safety_checks{ - linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug}; + linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug}; Setting enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey", Category::RendererDebug}; Setting disable_buffer_reorder{linkage, false, "disable_buffer_reorder", Category::RendererDebug}; // System - SwitchableSetting language_index{linkage, - Language::EnglishAmerican, - Language::Japanese, - Language::Serbian, - "language_index", - Category::System}; + SwitchableSetting language_index{ + linkage, Language::EnglishAmerican, Language::Japanese, + Language::Serbian, "language_index", Category::System}; SwitchableSetting region_index{linkage, Region::Usa, Region::Japan, Region::Taiwan, "region_index", Category::System}; SwitchableSetting time_zone_index{linkage, TimeZone::Auto, @@ -545,10 +522,10 @@ struct Values { "time_zone_index", Category::System}; // Measured in seconds since epoch SwitchableSetting custom_rtc_enabled{ - linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true}; + linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true}; SwitchableSetting custom_rtc{ - linkage, 0, "custom_rtc", Category::System, Specialization::Time, - false, true, &custom_rtc_enabled}; + linkage, 0, "custom_rtc", Category::System, Specialization::Time, + false, true, &custom_rtc_enabled}; SwitchableSetting custom_rtc_offset{linkage, 0, std::numeric_limits::min(), @@ -559,12 +536,12 @@ struct Values { true, true}; SwitchableSetting rng_seed_enabled{ - linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true}; + linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true}; SwitchableSetting rng_seed{ - linkage, 0, "rng_seed", Category::System, Specialization::Hex, - true, true, &rng_seed_enabled}; + linkage, 0, "rng_seed", Category::System, Specialization::Hex, + true, true, &rng_seed_enabled}; Setting device_name{ - linkage, "eden", "device_name", Category::System, Specialization::Default, true, true}; + linkage, "eden", "device_name", Category::System, Specialization::Default, true, true}; Setting current_user{linkage, 0, "current_user", Category::System}; @@ -615,21 +592,21 @@ struct Values { Setting tas_loop{linkage, false, "tas_loop", Category::Controls}; Setting mouse_panning{ - linkage, false, "mouse_panning", Category::Controls, Specialization::Default, false}; + linkage, false, "mouse_panning", Category::Controls, Specialization::Default, false}; Setting mouse_panning_sensitivity{ - linkage, 50, 1, 100, "mouse_panning_sensitivity", Category::Controls}; + linkage, 50, 1, 100, "mouse_panning_sensitivity", Category::Controls}; Setting mouse_enabled{linkage, false, "mouse_enabled", Category::Controls}; Setting mouse_panning_x_sensitivity{ - linkage, 50, 1, 100, "mouse_panning_x_sensitivity", Category::Controls}; + linkage, 50, 1, 100, "mouse_panning_x_sensitivity", Category::Controls}; Setting mouse_panning_y_sensitivity{ - linkage, 50, 1, 100, "mouse_panning_y_sensitivity", Category::Controls}; + linkage, 50, 1, 100, "mouse_panning_y_sensitivity", Category::Controls}; Setting mouse_panning_deadzone_counterweight{ - linkage, 20, 0, 100, "mouse_panning_deadzone_counterweight", Category::Controls}; + linkage, 20, 0, 100, "mouse_panning_deadzone_counterweight", Category::Controls}; Setting mouse_panning_decay_strength{ - linkage, 18, 0, 100, "mouse_panning_decay_strength", Category::Controls}; + linkage, 18, 0, 100, "mouse_panning_decay_strength", Category::Controls}; Setting mouse_panning_min_decay{ - linkage, 6, 0, 100, "mouse_panning_min_decay", Category::Controls}; + linkage, 6, 0, 100, "mouse_panning_min_decay", Category::Controls}; Setting emulate_analog_keyboard{linkage, false, "emulate_analog_keyboard", Category::Controls}; @@ -672,23 +649,22 @@ struct Values { Setting dump_exefs{linkage, false, "dump_exefs", Category::Debugging}; Setting dump_nso{linkage, false, "dump_nso", Category::Debugging}; Setting dump_shaders{ - linkage, false, "dump_shaders", Category::DebuggingGraphics, Specialization::Default, - false}; + linkage, false, "dump_shaders", Category::DebuggingGraphics, Specialization::Default, + false}; Setting dump_macros{ - linkage, false, "dump_macros", Category::DebuggingGraphics, Specialization::Default, false}; + linkage, false, "dump_macros", Category::DebuggingGraphics, Specialization::Default, false}; Setting enable_fs_access_log{linkage, false, "enable_fs_access_log", Category::Debugging}; Setting reporting_services{ - linkage, false, "reporting_services", Category::Debugging, Specialization::Default, false}; + linkage, false, "reporting_services", Category::Debugging, Specialization::Default, false}; Setting quest_flag{linkage, false, "quest_flag", Category::Debugging}; Setting disable_macro_jit{linkage, false, "disable_macro_jit", Category::DebuggingGraphics}; Setting disable_macro_hle{linkage, false, "disable_macro_hle", Category::DebuggingGraphics}; Setting extended_logging{ - linkage, false, "extended_logging", Category::Debugging, Specialization::Default, false}; + linkage, false, "extended_logging", Category::Debugging, Specialization::Default, false}; Setting use_debug_asserts{linkage, false, "use_debug_asserts", Category::Debugging}; - Setting use_auto_stub{ - linkage, false, "use_auto_stub", Category::Debugging}; + Setting use_auto_stub{linkage, false, "use_auto_stub", Category::Debugging}; Setting enable_all_controllers{linkage, false, "enable_all_controllers", Category::Debugging}; Setting perform_vulkan_check{linkage, true, "perform_vulkan_check", Category::Debugging}; diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index c2347f74d0..a038bc4b6a 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -150,19 +150,8 @@ ENUM(FullscreenMode, Borderless, Exclusive); ENUM(NvdecEmulation, Off, Cpu, Gpu); -ENUM(ResolutionSetup, - Res1_4X, - Res1_2X, - Res3_4X, - Res1X, - Res3_2X, - Res2X, - Res3X, - Res4X, - Res5X, - Res6X, - Res7X, - Res8X); +ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, + Res7X, Res8X); ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, ScaleForce, Fsr, Area, MaxEnum); diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 1909aced54..12f4791d67 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -4,9 +4,8 @@ #include #include -#include -#include #include +#include #include "common/string_util.h" @@ -142,18 +141,15 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st } std::string UTF16ToUTF8(std::u16string_view input) { - std::wstring_convert, char16_t> convert; - return convert.to_bytes(input.data(), input.data() + input.size()); + return boost::locale::conv::utf_to_utf(input.data(), input.data() + input.size()); } std::u16string UTF8ToUTF16(std::string_view input) { - std::wstring_convert, char16_t> convert; - return convert.from_bytes(input.data(), input.data() + input.size()); + return boost::locale::conv::utf_to_utf(input.data(), input.data() + input.size()); } std::u32string UTF8ToUTF32(std::string_view input) { - std::wstring_convert, char32_t> convert; - return convert.from_bytes(input.data(), input.data() + input.size()); + return boost::locale::conv::utf_to_utf(input.data(), input.data() + input.size()); } #ifdef _WIN32 diff --git a/src/common/tree.h b/src/common/tree.h index f4fc43de36..a260e83a32 100644 --- a/src/common/tree.h +++ b/src/common/tree.h @@ -103,9 +103,9 @@ concept IsRBEntry = CheckRBEntry::value; template concept HasRBEntry = requires(T& t, const T& ct) { - { t.GetRBEntry() } -> std::same_as&>; - { ct.GetRBEntry() } -> std::same_as&>; - }; + { t.GetRBEntry() } -> std::same_as&>; + { ct.GetRBEntry() } -> std::same_as&>; +}; template requires HasRBEntry diff --git a/src/common/vector_math.h b/src/common/vector_math.h index b4885835df..720e89f491 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -362,7 +362,9 @@ public: // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all // component names (x<->r) and permutations (xy<->yx) #define _DEFINE_SWIZZLER2(a, b, name) \ - [[nodiscard]] constexpr Vec2 name() const { return Vec2(a, b); } + [[nodiscard]] constexpr Vec2 name() const { \ + return Vec2(a, b); \ + } #define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ _DEFINE_SWIZZLER2(a, b, a##b); \ _DEFINE_SWIZZLER2(a, b, a2##b2); \ @@ -555,7 +557,9 @@ public: // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and // permutations (xy<->yx) #define _DEFINE_SWIZZLER2(a, b, name) \ - [[nodiscard]] constexpr Vec2 name() const { return Vec2(a, b); } + [[nodiscard]] constexpr Vec2 name() const { \ + return Vec2(a, b); \ + } #define DEFINE_SWIZZLER2_COMP1(a, a2) \ _DEFINE_SWIZZLER2(a, a, a##a); \ _DEFINE_SWIZZLER2(a, a, a2##a2) @@ -580,7 +584,9 @@ public: #undef _DEFINE_SWIZZLER2 #define _DEFINE_SWIZZLER3(a, b, c, name) \ - [[nodiscard]] constexpr Vec3 name() const { return Vec3(a, b, c); } + [[nodiscard]] constexpr Vec3 name() const { \ + return Vec3(a, b, c); \ + } #define DEFINE_SWIZZLER3_COMP1(a, a2) \ _DEFINE_SWIZZLER3(a, a, a, a##a##a); \ _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2) diff --git a/src/common/virtual_buffer.h b/src/common/virtual_buffer.h index 4f6e3e6e5c..a6cf25baa2 100644 --- a/src/common/virtual_buffer.h +++ b/src/common/virtual_buffer.h @@ -33,8 +33,8 @@ public: VirtualBuffer& operator=(const VirtualBuffer&) = delete; VirtualBuffer(VirtualBuffer&& other) noexcept - : alloc_size{std::exchange(other.alloc_size, 0)}, base_ptr{std::exchange(other.base_ptr), - nullptr} {} + : alloc_size{std::exchange(other.alloc_size, 0)}, + base_ptr{std::exchange(other.base_ptr), nullptr} {} VirtualBuffer& operator=(VirtualBuffer&& other) noexcept { alloc_size = std::exchange(other.alloc_size, 0); diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index d2d27fafea..80d6e2bc5c 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -8,8 +8,8 @@ namespace Common::X64 { NativeClock::NativeClock(u64 rdtsc_frequency_) - : rdtsc_frequency{rdtsc_frequency_}, ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, - rdtsc_frequency)}, + : rdtsc_frequency{rdtsc_frequency_}, + ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency)}, us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)}, ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)}, cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)}, diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d830cc381d..fb9bda5b03 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1150,18 +1150,19 @@ add_library(core STATIC tools/renderdoc.h ) -if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") +if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ENABLE_WIFI_SCAN) # find_package(libiw REQUIRED) + target_compile_definitions(core PRIVATE -DENABLE_WIFI_SCAN) target_link_libraries(core PRIVATE iw) endif() if (WIN32) target_compile_definitions(core PRIVATE _WIN32_WINNT=0x0A00 WINVER=0x0A00) - if(TARGET iw) - target_link_libraries(core PRIVATE iw) - message(STATUS "Linking 'core' with iw on Linux.") - endif() + # if(TARGET iw) + # target_link_libraries(core PRIVATE iw) + # message(STATUS "Linking 'core' with iw on Linux.") + # endif() endif() if (MSVC) @@ -1216,7 +1217,6 @@ endif() if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) target_sources(core PRIVATE - arm/dynarmic/arm_dynarmic.cpp arm/dynarmic/arm_dynarmic.h arm/dynarmic/arm_dynarmic_64.cpp arm/dynarmic/arm_dynarmic_64.h diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 34acec9ebf..b1cb2b8984 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -14,7 +14,8 @@ void ArmInterface::LogBacktrace(Kernel::KProcess* process) const { this->GetContext(ctx); LOG_ERROR(Core_ARM, "Backtrace, sp={:016X}, pc={:016X}", ctx.sp, ctx.pc); - LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address", "Offset", "Symbol"); + LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address", + "Offset", "Symbol"); LOG_ERROR(Core_ARM, ""); const auto backtrace = GetBacktraceFromContext(process, ctx); diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp deleted file mode 100644 index e6e9fc45be..0000000000 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#ifdef __linux__ - -#include "common/signal_chain.h" - -#include "core/arm/dynarmic/arm_dynarmic.h" -#include "core/hle/kernel/k_process.h" -#include "core/memory.h" - -namespace Core { - -namespace { - -thread_local Core::Memory::Memory* g_current_memory{}; -std::once_flag g_registered{}; -struct sigaction g_old_segv {}; - -void HandleSigSegv(int sig, siginfo_t* info, void* ctx) { - if (g_current_memory && g_current_memory->InvalidateSeparateHeap(info->si_addr)) { - return; - } - - return g_old_segv.sa_sigaction(sig, info, ctx); -} - -} // namespace - -ScopedJitExecution::ScopedJitExecution(Kernel::KProcess* process) { - g_current_memory = std::addressof(process->GetMemory()); -} - -ScopedJitExecution::~ScopedJitExecution() { - g_current_memory = nullptr; -} - -void ScopedJitExecution::RegisterHandler() { - std::call_once(g_registered, [] { - struct sigaction sa {}; - sa.sa_sigaction = &HandleSigSegv; - sa.sa_flags = SA_SIGINFO | SA_ONSTACK; - Common::SigAction(SIGSEGV, std::addressof(sa), std::addressof(g_old_segv)); - }); -} - -} // namespace Core - -#endif diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 53dd188151..eef7c31160 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -26,24 +26,4 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) { return static_cast(hr); } -#ifdef __linux__ - -class ScopedJitExecution { -public: - explicit ScopedJitExecution(Kernel::KProcess* process); - ~ScopedJitExecution(); - static void RegisterHandler(); -}; - -#else - -class ScopedJitExecution { -public: - explicit ScopedJitExecution(Kernel::KProcess* process) {} - ~ScopedJitExecution() {} - static void RegisterHandler() {} -}; - -#endif - } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index afbf178349..01ac659ab8 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -19,8 +19,8 @@ using namespace Common::Literals; class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { public: explicit DynarmicCallbacks32(ArmDynarmic32& parent, Kernel::KProcess* process) - : m_parent{parent}, m_memory(process->GetMemory()), - m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()}, + : m_parent{parent}, m_memory(process->GetMemory()), m_process(process), + m_debugger_enabled{parent.m_system.DebuggerEnabled()}, m_check_memory_access{m_debugger_enabled || !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} @@ -195,11 +195,12 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; config.only_detect_misalignment_via_page_table_on_page_boundary = true; - config.fastmem_pointer = page_table->fastmem_arena ? - std::optional{reinterpret_cast(page_table->fastmem_arena)} : - std::nullopt; + config.fastmem_pointer = + page_table->fastmem_arena + ? std::optional{reinterpret_cast(page_table->fastmem_arena)} + : std::nullopt; - config.fastmem_exclusive_access = config.fastmem_pointer != std::nullopt; + config.fastmem_exclusive_access = config.fastmem_pointer != std::nullopt; config.recompile_on_exclusive_fastmem_failure = true; } @@ -336,15 +337,11 @@ bool ArmDynarmic32::IsInThumbMode() const { } HaltReason ArmDynarmic32::RunThread(Kernel::KThread* thread) { - ScopedJitExecution sj(thread->GetOwnerProcess()); - m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Run()); } HaltReason ArmDynarmic32::StepThread(Kernel::KThread* thread) { - ScopedJitExecution sj(thread->GetOwnerProcess()); - m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Step()); } @@ -386,7 +383,6 @@ ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProc m_cp15(std::make_shared(*this)), m_core_index{core_index} { auto& page_table_impl = process->GetPageTable().GetBasePageTable().GetImpl(); m_jit = MakeJit(&page_table_impl); - ScopedJitExecution::RegisterHandler(); } ArmDynarmic32::~ArmDynarmic32() = default; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 99a80644ad..e62d3c566a 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -19,8 +19,8 @@ using namespace Common::Literals; class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { public: explicit DynarmicCallbacks64(ArmDynarmic64& parent, Kernel::KProcess* process) - : m_parent{parent}, m_memory(process->GetMemory()), - m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()}, + : m_parent{parent}, m_memory(process->GetMemory()), m_process(process), + m_debugger_enabled{parent.m_system.DebuggerEnabled()}, m_check_memory_access{m_debugger_enabled || !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} @@ -242,9 +242,10 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; config.only_detect_misalignment_via_page_table_on_page_boundary = true; - config.fastmem_pointer = page_table->fastmem_arena ? - std::optional{reinterpret_cast(page_table->fastmem_arena)} : - std::nullopt; + config.fastmem_pointer = + page_table->fastmem_arena + ? std::optional{reinterpret_cast(page_table->fastmem_arena)} + : std::nullopt; config.fastmem_address_space_bits = std::uint32_t(address_space_bits); config.silently_mirror_fastmem = false; @@ -367,15 +368,11 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa } HaltReason ArmDynarmic64::RunThread(Kernel::KThread* thread) { - ScopedJitExecution sj(thread->GetOwnerProcess()); - m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Run()); } HaltReason ArmDynarmic64::StepThread(Kernel::KThread* thread) { - ScopedJitExecution sj(thread->GetOwnerProcess()); - m_jit->ClearExclusiveState(); return TranslateHaltReason(m_jit->Step()); } @@ -415,7 +412,6 @@ ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProc auto& page_table = process->GetPageTable().GetBasePageTable(); auto& page_table_impl = page_table.GetImpl(); m_jit = MakeJit(&page_table_impl, page_table.GetAddressSpaceWidth()); - ScopedJitExecution::RegisterHandler(); } ArmDynarmic64::~ArmDynarmic64() = default; diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp index 877e8ac3c7..8115743322 100644 --- a/src/core/arm/nce/arm_nce.cpp +++ b/src/core/arm/nce/arm_nce.cpp @@ -302,7 +302,7 @@ void ArmNce::Initialize() { sigaddset(&signal_mask, GuestAlignmentFaultSignal); sigaddset(&signal_mask, GuestAccessFaultSignal); - struct sigaction return_to_run_code_action {}; + struct sigaction return_to_run_code_action{}; return_to_run_code_action.sa_flags = SA_SIGINFO | SA_ONSTACK; return_to_run_code_action.sa_sigaction = reinterpret_cast( &ArmNce::ReturnToRunCodeByExceptionLevelChangeSignalHandler); @@ -310,21 +310,21 @@ void ArmNce::Initialize() { Common::SigAction(ReturnToRunCodeByExceptionLevelChangeSignal, &return_to_run_code_action, nullptr); - struct sigaction break_from_run_code_action {}; + struct sigaction break_from_run_code_action{}; break_from_run_code_action.sa_flags = SA_SIGINFO | SA_ONSTACK; break_from_run_code_action.sa_sigaction = reinterpret_cast(&ArmNce::BreakFromRunCodeSignalHandler); break_from_run_code_action.sa_mask = signal_mask; Common::SigAction(BreakFromRunCodeSignal, &break_from_run_code_action, nullptr); - struct sigaction alignment_fault_action {}; + struct sigaction alignment_fault_action{}; alignment_fault_action.sa_flags = SA_SIGINFO | SA_ONSTACK; alignment_fault_action.sa_sigaction = reinterpret_cast(&ArmNce::GuestAlignmentFaultSignalHandler); alignment_fault_action.sa_mask = signal_mask; Common::SigAction(GuestAlignmentFaultSignal, &alignment_fault_action, nullptr); - struct sigaction access_fault_action {}; + struct sigaction access_fault_action{}; access_fault_action.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART; access_fault_action.sa_sigaction = reinterpret_cast(&ArmNce::GuestAccessFaultSignalHandler); @@ -405,19 +405,19 @@ void ArmNce::ClearInstructionCache() { } void ArmNce::InvalidateCacheRange(u64 addr, std::size_t size) { - #if defined(__GNUC__) || defined(__clang__) - // Align the start address to cache line boundary for better performance - const size_t CACHE_LINE_SIZE = 64; - addr &= ~(CACHE_LINE_SIZE - 1); +#if defined(__GNUC__) || defined(__clang__) + // Align the start address to cache line boundary for better performance + const size_t CACHE_LINE_SIZE = 64; + addr &= ~(CACHE_LINE_SIZE - 1); - // Round up size to nearest cache line - size = (size + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1); + // Round up size to nearest cache line + size = (size + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1); - // Prefetch the range to be invalidated - for (size_t offset = 0; offset < size; offset += CACHE_LINE_SIZE) { - __builtin_prefetch((void*)(addr + offset), 1, 3); - } - #endif + // Prefetch the range to be invalidated + for (size_t offset = 0; offset < size; offset += CACHE_LINE_SIZE) { + __builtin_prefetch((void*)(addr + offset), 1, 3); + } +#endif this->ClearInstructionCache(); } diff --git a/src/core/arm/nce/interpreter_visitor.cpp b/src/core/arm/nce/interpreter_visitor.cpp index bbe0289f8e..afc2bb4e27 100644 --- a/src/core/arm/nce/interpreter_visitor.cpp +++ b/src/core/arm/nce/interpreter_visitor.cpp @@ -10,7 +10,7 @@ namespace Core { namespace { // Prefetch tuning parameters constexpr size_t CACHE_LINE_SIZE = 64; -constexpr size_t PREFETCH_STRIDE = 128; // 2 cache lines ahead +constexpr size_t PREFETCH_STRIDE = 128; // 2 cache lines ahead constexpr size_t SIMD_PREFETCH_THRESHOLD = 32; // Bytes } // namespace diff --git a/src/core/arm/nce/lru_cache.h b/src/core/arm/nce/lru_cache.h index 1bc00c8f14..517c121442 100644 --- a/src/core/arm/nce/lru_cache.h +++ b/src/core/arm/nce/lru_cache.h @@ -13,28 +13,34 @@ template class LRUCache { public: - using key_type = KeyType; + using key_type = KeyType; using value_type = ValueType; - using size_type = std::size_t; + using size_type = std::size_t; struct Statistics { - size_type hits = 0; + size_type hits = 0; size_type misses = 0; - void reset() noexcept { hits = misses = 0; } + void reset() noexcept { + hits = misses = 0; + } }; explicit LRUCache(size_type capacity, bool enabled = true) : enabled_{enabled}, capacity_{capacity} { cache_map_.reserve(capacity_); - LOG_WARNING(Core, "LRU Cache initialised (state: {} | capacity: {})", enabled_ ? "enabled" : "disabled", capacity_); + LOG_WARNING(Core, "LRU Cache initialised (state: {} | capacity: {})", + enabled_ ? "enabled" : "disabled", capacity_); } // Non-movable copy semantics - LRUCache(const LRUCache&) = delete; + LRUCache(const LRUCache&) = delete; LRUCache& operator=(const LRUCache&) = delete; - LRUCache(LRUCache&& other) noexcept { *this = std::move(other); } + LRUCache(LRUCache&& other) noexcept { + *this = std::move(other); + } LRUCache& operator=(LRUCache&& other) noexcept { - if (this == &other) return *this; + if (this == &other) + return *this; std::unique_lock this_lock(mutex_, std::defer_lock); std::unique_lock other_lock(other.mutex_, std::defer_lock); std::lock(this_lock, other_lock); @@ -48,7 +54,8 @@ public: ~LRUCache() = default; [[nodiscard]] value_type* get(const key_type& key) { - if (!enabled_) [[unlikely]] return nullptr; + if (!enabled_) [[unlikely]] + return nullptr; std::unique_lock lock(mutex_); auto it = cache_map_.find(key); if (it == cache_map_.end()) { @@ -61,7 +68,8 @@ public: } [[nodiscard]] value_type* peek(const key_type& key) const { - if (!enabled_) [[unlikely]] return nullptr; + if (!enabled_) [[unlikely]] + return nullptr; std::shared_lock lock(mutex_); auto it = cache_map_.find(key); return it == cache_map_.end() ? nullptr : &it->second.second; @@ -69,7 +77,8 @@ public: template void put(const key_type& key, V&& value) { - if (!enabled_) [[unlikely]] return; + if (!enabled_) [[unlikely]] + return; std::unique_lock lock(mutex_); insert_or_update(key, std::forward(value)); } @@ -88,16 +97,19 @@ public: } [[nodiscard]] bool contains(const key_type& key) const { - if (!enabled_) return false; + if (!enabled_) + return false; std::shared_lock lock(mutex_); return cache_map_.find(key) != cache_map_.end(); } bool erase(const key_type& key) { - if (!enabled_) return false; + if (!enabled_) + return false; std::unique_lock lock(mutex_); auto it = cache_map_.find(key); - if (it == cache_map_.end()) return false; + if (it == cache_map_.end()) + return false; cache_list_.erase(it->second.first); cache_map_.erase(it); return true; @@ -111,15 +123,19 @@ public: } [[nodiscard]] size_type size() const { - if (!enabled_) return 0; + if (!enabled_) + return 0; std::shared_lock lock(mutex_); return cache_map_.size(); } - [[nodiscard]] size_type get_capacity() const { return capacity_; } + [[nodiscard]] size_type get_capacity() const { + return capacity_; + } void resize(size_type new_capacity) { - if (!enabled_) return; + if (!enabled_) + return; std::unique_lock lock(mutex_); capacity_ = new_capacity; shrink_if_needed(); @@ -130,10 +146,13 @@ public: std::unique_lock lock(mutex_); enabled_ = state; LOG_WARNING(Core, "LRU Cache state changed to: {}", state ? "enabled" : "disabled"); - if (!enabled_) clear(); + if (!enabled_) + clear(); } - [[nodiscard]] bool isEnabled() const { return enabled_; } + [[nodiscard]] bool isEnabled() const { + return enabled_; + } [[nodiscard]] Statistics stats() const { std::shared_lock lock(mutex_); @@ -141,10 +160,10 @@ public: } private: - using list_type = std::list; - using list_iterator = typename list_type::iterator; + using list_type = std::list; + using list_iterator = typename list_type::iterator; using map_value_type = std::pair; - using map_type = std::unordered_map; + using map_type = std::unordered_map; template void insert_or_update(const key_type& key, V&& value) { diff --git a/src/core/arm/nce/patcher.cpp b/src/core/arm/nce/patcher.cpp index b8387ce7cb..a3c5cdc7a0 100644 --- a/src/core/arm/nce/patcher.cpp +++ b/src/core/arm/nce/patcher.cpp @@ -16,21 +16,16 @@ namespace Core::NCE { Patcher::Patcher(Patcher&& other) noexcept : patch_cache(std::move(other.patch_cache)), - m_patch_instructions(std::move(other.m_patch_instructions)), - c(m_patch_instructions), - m_save_context(other.m_save_context), - m_load_context(other.m_load_context), - mode(other.mode), + m_patch_instructions(std::move(other.m_patch_instructions)), c(m_patch_instructions), + m_save_context(other.m_save_context), m_load_context(other.m_load_context), mode(other.mode), total_program_size(other.total_program_size), - m_relocate_module_index(other.m_relocate_module_index), - modules(std::move(other.modules)), + m_relocate_module_index(other.m_relocate_module_index), modules(std::move(other.modules)), curr_patch(nullptr) { if (!modules.empty()) { curr_patch = &modules.back(); } } - using namespace Common::Literals; using namespace oaknut::util; @@ -41,7 +36,7 @@ constexpr u32 ModuleCodeIndex = 0x24 / sizeof(u32); Patcher::Patcher() : c(m_patch_instructions) { LOG_WARNING(Core_ARM, "Patcher initialized with LRU cache {}", - patch_cache.isEnabled() ? "enabled" : "disabled"); + patch_cache.isEnabled() ? "enabled" : "disabled"); // The first word of the patch section is always a branch to the first instruction of the // module. c.dw(0); diff --git a/src/core/arm/nce/patcher.h b/src/core/arm/nce/patcher.h index 53a923138c..2e92d13906 100644 --- a/src/core/arm/nce/patcher.h +++ b/src/core/arm/nce/patcher.h @@ -9,13 +9,13 @@ #include #include +#include #include "common/common_types.h" #include "common/settings.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_typed_address.h" #include "core/hle/kernel/physical_memory.h" #include "lru_cache.h" -#include namespace Core::NCE { @@ -67,8 +67,9 @@ private: void WriteCntpctHandler(ModuleDestLabel module_dest, oaknut::XReg dest_reg); private: - static constexpr size_t CACHE_SIZE = 16384; // Cache size for patch entries - LRUCache patch_cache{CACHE_SIZE, Settings::values.lru_cache_enabled.GetValue()}; + static constexpr size_t CACHE_SIZE = 16384; // Cache size for patch entries + LRUCache patch_cache{ + CACHE_SIZE, Settings::values.lru_cache_enabled.GetValue()}; void BranchToPatch(uintptr_t module_dest) { if (patch_cache.isEnabled()) { @@ -79,14 +80,16 @@ private: curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), *cached_patch}); return; } - LOG_DEBUG(Core_ARM, "LRU cache miss for address {:#x}, creating new patch", module_dest); + LOG_DEBUG(Core_ARM, "LRU cache miss for address {:#x}, creating new patch", + module_dest); // If not in cache, create new entry and cache it const auto patch_addr = c.offset(); curr_patch->m_branch_to_patch_relocations.push_back({patch_addr, module_dest}); patch_cache.put(module_dest, patch_addr); } else { - LOG_DEBUG(Core_ARM, "LRU cache disabled - creating direct patch for address {:#x}", module_dest); + LOG_DEBUG(Core_ARM, "LRU cache disabled - creating direct patch for address {:#x}", + module_dest); // LRU disabled - use pre-LRU approach curr_patch->m_branch_to_patch_relocations.push_back({c.offset(), module_dest}); } diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index c4ea15c1dd..0c82831f89 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -17,8 +17,8 @@ #include "common/x64/cpu_wait.h" #endif -#include "common/settings.h" #include "common/microprofile.h" +#include "common/settings.h" #include "core/core_timing.h" #include "core/hardware_properties.h" @@ -175,9 +175,9 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr& event_type, } void CoreTiming::AddTicks(u64 ticks_to_add) { - cpu_ticks = Settings::values.use_custom_cpu_ticks.GetValue() - ? Settings::values.cpu_ticks.GetValue() - : cpu_ticks + ticks_to_add; + cpu_ticks = Settings::values.use_custom_cpu_ticks.GetValue() + ? Settings::values.cpu_ticks.GetValue() + : cpu_ticks + ticks_to_add; downcount -= static_cast(cpu_ticks); } @@ -193,22 +193,22 @@ u64 CoreTiming::GetClockTicks() const { u64 fres; if (is_multicore) [[likely]] { fres = clock->GetCNTPCT(); - } else { - fres = Common::WallClock::CPUTickToCNTPCT(cpu_ticks); - } + } else { + fres = Common::WallClock::CPUTickToCNTPCT(cpu_ticks); + } - if (Settings::values.use_fast_cpu_time) { - fres = (u64) ((double) fres - * (1.7 + 0.3 * (u32) Settings::values.fast_cpu_time.GetValue())); - } + if (Settings::values.use_fast_cpu_time) { + fres = (u64)((double)fres * (1.7 + 0.3 * (u32)Settings::values.fast_cpu_time.GetValue())); + } - if (Settings::values.sync_core_speed.GetValue()) { - const double ticks = static_cast(fres); - const double speed_limit = static_cast(Settings::values.speed_limit.GetValue())*0.01; - return static_cast(ticks/speed_limit); - } else { - return fres; - } + if (Settings::values.sync_core_speed.GetValue()) { + const double ticks = static_cast(fres); + const double speed_limit = + static_cast(Settings::values.speed_limit.GetValue()) * 0.01; + return static_cast(ticks / speed_limit); + } else { + return fres; + } } u64 CoreTiming::GetGPUTicks() const { diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index 84c846bab2..c115f23c86 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -4,12 +4,8 @@ #include #include -#include -#if BOOST_VERSION > 108300 && !defined(_WINDOWS) && !defined(ANDROID) -#include -#else #include -#endif +#include #include "common/logging/log.h" #include "common/polyfill_thread.h" @@ -329,11 +325,7 @@ private: struct ConnectionState { boost::asio::ip::tcp::socket client_socket; -#if BOOST_VERSION > 108300 && !defined(_WINDOWS) && !defined(ANDROID) - boost::process::v1::async_pipe signal_pipe; -#else boost::process::async_pipe signal_pipe; -#endif SignalInfo info; Kernel::KScopedAutoObject active_thread; diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 0bcf40cf86..396a40d013 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -29,8 +29,8 @@ constexpr std::array partition_names{ XCI::XCI(VirtualFile file_, u64 program_id, size_t program_index) : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, - partitions(partition_names.size()), - partitions_raw(partition_names.size()), keys{Core::Crypto::KeyManager::Instance()} { + partitions(partition_names.size()), partitions_raw(partition_names.size()), + keys{Core::Crypto::KeyManager::Instance()} { const auto header_status = TryReadHeader(); if (header_status != Loader::ResultStatus::Success) { status = header_status; diff --git a/src/core/file_sys/fs_path_utility.h b/src/core/file_sys/fs_path_utility.h index cdfd8c7729..b59636f386 100644 --- a/src/core/file_sys/fs_path_utility.h +++ b/src/core/file_sys/fs_path_utility.h @@ -87,12 +87,15 @@ private: u32 m_value; public: - constexpr PathFlags() : m_value(0) { /* ... */ - } + constexpr PathFlags() : m_value(0) { /* ... */ } #define DECLARE_PATH_FLAG_HANDLER(__WHICH__) \ - constexpr bool Is##__WHICH__##Allowed() const { return (m_value & __WHICH__##Flag) != 0; } \ - constexpr void Allow##__WHICH__() { m_value |= __WHICH__##Flag; } + constexpr bool Is##__WHICH__##Allowed() const { \ + return (m_value & __WHICH__##Flag) != 0; \ + } \ + constexpr void Allow##__WHICH__() { \ + m_value |= __WHICH__##Flag; \ + } DECLARE_PATH_FLAG_HANDLER(WindowsPath) DECLARE_PATH_FLAG_HANDLER(RelativePath) diff --git a/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp b/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp index 046571e9ef..9960e394fc 100644 --- a/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp +++ b/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp @@ -4,23 +4,18 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/file_sys/fssystem/fssystem_integrity_verification_storage.h" #include "common/alignment.h" +#include "core/file_sys/fssystem/fssystem_integrity_verification_storage.h" namespace FileSys { -constexpr inline u32 ILog2(u32 val) -{ +constexpr inline u32 ILog2(u32 val) { ASSERT(val > 0); return static_cast((sizeof(u32) * 8) - 1 - std::countl_zero(val)); } -void IntegrityVerificationStorage::Initialize(VirtualFile hs, - VirtualFile ds, - s64 verif_block_size, - s64 upper_layer_verif_block_size, - bool is_real_data) -{ +void IntegrityVerificationStorage::Initialize(VirtualFile hs, VirtualFile ds, s64 verif_block_size, + s64 upper_layer_verif_block_size, bool is_real_data) { // Validate preconditions. ASSERT(verif_block_size >= HashSize); @@ -54,14 +49,12 @@ void IntegrityVerificationStorage::Initialize(VirtualFile hs, m_is_real_data = is_real_data; } -void IntegrityVerificationStorage::Finalize() -{ +void IntegrityVerificationStorage::Finalize() { m_hash_storage = VirtualFile(); m_data_storage = VirtualFile(); } -size_t IntegrityVerificationStorage::Read(u8* buffer, size_t size, size_t offset) const -{ +size_t IntegrityVerificationStorage::Read(u8* buffer, size_t size, size_t offset) const { // Succeed if zero size. if (size == 0) { return size; @@ -104,8 +97,7 @@ size_t IntegrityVerificationStorage::Read(u8* buffer, size_t size, size_t offset return m_data_storage->Read(buffer, read_size, offset); } -size_t IntegrityVerificationStorage::GetSize() const -{ +size_t IntegrityVerificationStorage::GetSize() const { return m_data_storage->GetSize(); } diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 85d30543c1..18a515015e 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -790,7 +790,9 @@ InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFuncti if (GetFileAtID(id) != nullptr) { LOG_WARNING(Loader, "Overwriting existing NCA..."); VirtualDir c_dir; - { c_dir = dir->GetFileRelative(path)->GetContainingDirectory(); } + { + c_dir = dir->GetFileRelative(path)->GetContainingDirectory(); + } c_dir->DeleteFile(Common::FS::GetFilename(path)); } diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index f3e2e21f4c..9ff4b2b2dc 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -15,9 +15,7 @@ SDMCFactory::SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_) : sd_dir(std::move(sd_dir_)), sd_mod_dir(std::move(sd_mod_dir_)), contents(std::make_unique( GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents/registered"), - [](const VirtualFile& file, const NcaID& id) { - return NAX{file, id}.GetDecrypted(); - })), + [](const VirtualFile& file, const NcaID& id) { return NAX{file, id}.GetDecrypted(); })), placeholder(std::make_unique( GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents/placehld"))) {} diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index 68e8ec22fc..59173c6170 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -19,9 +19,9 @@ namespace FileSys { NSP::NSP(VirtualFile file_, u64 title_id_, std::size_t program_index_) - : file(std::move(file_)), expected_program_id(title_id_), - program_index(program_index_), status{Loader::ResultStatus::Success}, - pfs(std::make_shared(file)), keys{Core::Crypto::KeyManager::Instance()} { + : file(std::move(file_)), expected_program_id(title_id_), program_index(program_index_), + status{Loader::ResultStatus::Success}, pfs(std::make_shared(file)), + keys{Core::Crypto::KeyManager::Instance()} { if (pfs->GetStatus() != Loader::ResultStatus::Success) { status = pfs->GetStatus(); return; diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp index 6692211e1d..64fa442826 100644 --- a/src/core/file_sys/xts_archive.cpp +++ b/src/core/file_sys/xts_archive.cpp @@ -44,8 +44,8 @@ static bool CalculateHMAC256(Destination* out, const SourceKey* key, std::size_t } NAX::NAX(VirtualFile file_) - : header(std::make_unique()), - file(std::move(file_)), keys{Core::Crypto::KeyManager::Instance()} { + : header(std::make_unique()), file(std::move(file_)), + keys{Core::Crypto::KeyManager::Instance()} { std::string path = Common::FS::SanitizePath(file->GetFullPath()); static const std::regex nax_path_regex("/registered/(000000[0-9A-F]{2})/([0-9A-F]{32})\\.nca", std::regex_constants::ECMAScript | @@ -62,8 +62,8 @@ NAX::NAX(VirtualFile file_) } NAX::NAX(VirtualFile file_, std::array nca_id) - : header(std::make_unique()), - file(std::move(file_)), keys{Core::Crypto::KeyManager::Instance()} { + : header(std::make_unique()), file(std::move(file_)), + keys{Core::Crypto::KeyManager::Instance()} { Core::Crypto::SHA256Hash hash{}; mbedtls_sha256_ret(nca_id.data(), nca_id.size(), hash.data(), 0); status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0], diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 8d4e0df44f..fa6e16164b 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -24,7 +24,9 @@ private: friend class ::Kernel::KClassTokenGenerator; \ static constexpr inline auto ObjectType = ::Kernel::KClassTokenGenerator::ObjectType::CLASS; \ static constexpr inline const char* const TypeName = #CLASS; \ - static constexpr inline ClassTokenType ClassToken() { return ::Kernel::ClassToken; } \ + static constexpr inline ClassTokenType ClassToken() { \ + return ::Kernel::ClassToken; \ + } \ \ public: \ YUZU_NON_COPYABLE(CLASS); \ @@ -35,9 +37,15 @@ public: constexpr ClassTokenType Token = ClassToken(); \ return TypeObj(TypeName, Token); \ } \ - static constexpr const char* GetStaticTypeName() { return TypeName; } \ - virtual TypeObj GetTypeObj() ATTRIBUTE { return GetStaticTypeObj(); } \ - virtual const char* GetTypeName() ATTRIBUTE { return GetStaticTypeName(); } \ + static constexpr const char* GetStaticTypeName() { \ + return TypeName; \ + } \ + virtual TypeObj GetTypeObj() ATTRIBUTE { \ + return GetStaticTypeObj(); \ + } \ + virtual const char* GetTypeName() ATTRIBUTE { \ + return GetStaticTypeName(); \ + } \ \ private: \ constexpr bool operator!=(const TypeObj& rhs) diff --git a/src/core/hle/kernel/k_memory_layout.cpp b/src/core/hle/kernel/k_memory_layout.cpp index bec7146688..8aec520010 100644 --- a/src/core/hle/kernel/k_memory_layout.cpp +++ b/src/core/hle/kernel/k_memory_layout.cpp @@ -128,8 +128,8 @@ KVirtualAddress KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t al KMemoryLayout::KMemoryLayout() : m_virtual_tree{m_memory_region_allocator}, m_physical_tree{m_memory_region_allocator}, - m_virtual_linear_tree{m_memory_region_allocator}, m_physical_linear_tree{ - m_memory_region_allocator} {} + m_virtual_linear_tree{m_memory_region_allocator}, + m_physical_linear_tree{m_memory_region_allocator} {} void KMemoryLayout::InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start, KVirtualAddress linear_virtual_start) { diff --git a/src/core/hle/kernel/k_priority_queue.h b/src/core/hle/kernel/k_priority_queue.h index 26677ec65c..b250700293 100644 --- a/src/core/hle/kernel/k_priority_queue.h +++ b/src/core/hle/kernel/k_priority_queue.h @@ -17,38 +17,32 @@ namespace Kernel { class KThread; template -concept KPriorityQueueAffinityMask = ! -std::is_reference_v&& requires(T& t) { - { t.GetAffinityMask() } -> Common::ConvertibleTo; - { t.SetAffinityMask(0) }; +concept KPriorityQueueAffinityMask = !std::is_reference_v && requires(T& t) { + { t.GetAffinityMask() } -> Common::ConvertibleTo; + { t.SetAffinityMask(0) }; - { t.GetAffinity(0) } -> std::same_as; - { t.SetAffinity(0, false) }; - { t.SetAll() }; - }; + { t.GetAffinity(0) } -> std::same_as; + { t.SetAffinity(0, false) }; + { t.SetAll() }; +}; template -concept KPriorityQueueMember = ! -std::is_reference_v&& requires(T& t) { - { typename T::QueueEntry() }; - { (typename T::QueueEntry()).Initialize() }; - { (typename T::QueueEntry()).SetPrev(std::addressof(t)) }; - { (typename T::QueueEntry()).SetNext(std::addressof(t)) }; - { (typename T::QueueEntry()).GetNext() } -> std::same_as; - { (typename T::QueueEntry()).GetPrev() } -> std::same_as; - { - t.GetPriorityQueueEntry(0) - } -> std::same_as; +concept KPriorityQueueMember = !std::is_reference_v && requires(T& t) { + { typename T::QueueEntry() }; + { (typename T::QueueEntry()).Initialize() }; + { (typename T::QueueEntry()).SetPrev(std::addressof(t)) }; + { (typename T::QueueEntry()).SetNext(std::addressof(t)) }; + { (typename T::QueueEntry()).GetNext() } -> std::same_as; + { (typename T::QueueEntry()).GetPrev() } -> std::same_as; + { t.GetPriorityQueueEntry(0) } -> std::same_as; - { t.GetAffinityMask() }; - { - std::remove_cvref_t() - } -> KPriorityQueueAffinityMask; + { t.GetAffinityMask() }; + { std::remove_cvref_t() } -> KPriorityQueueAffinityMask; - { t.GetActiveCore() } -> Common::ConvertibleTo; - { t.GetPriority() } -> Common::ConvertibleTo; - { t.IsDummyThread() } -> Common::ConvertibleTo; - }; + { t.GetActiveCore() } -> Common::ConvertibleTo; + { t.GetPriority() } -> Common::ConvertibleTo; + { t.IsDummyThread() } -> Common::ConvertibleTo; +}; template requires KPriorityQueueMember diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 80566b7e77..cf03353f84 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -1266,10 +1266,6 @@ void KProcess::InitializeInterfaces() { #ifdef HAS_NCE if (this->IsApplication() && Settings::IsNceEnabled()) { - // Register the scoped JIT handler before creating any NCE instances - // so that its signal handler will appear first in the signal chain. - Core::ScopedJitExecution::RegisterHandler(); - for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { m_arm_interfaces[i] = std::make_unique(m_kernel.System(), true, i); } diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index df3e540dc2..7b997bb5e7 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -84,7 +84,7 @@ private: std::array m_entropy{}; bool m_is_signaled{}; bool m_is_initialized{}; - u32 m_pointer_buffer_size = 0x8000; // Default pointer buffer size (can be game-specific later) + u32 m_pointer_buffer_size = 0x8000; // Default pointer buffer size (can be game-specific later) bool m_is_application{}; bool m_is_default_application_system_resource{}; bool m_is_hbl{}; diff --git a/src/core/hle/kernel/k_scoped_lock.h b/src/core/hle/kernel/k_scoped_lock.h index 629a7d20dd..bc9830b4da 100644 --- a/src/core/hle/kernel/k_scoped_lock.h +++ b/src/core/hle/kernel/k_scoped_lock.h @@ -10,11 +10,10 @@ namespace Kernel { template -concept KLockable = ! -std::is_reference_v&& requires(T& t) { - { t.Lock() } -> std::same_as; - { t.Unlock() } -> std::same_as; - }; +concept KLockable = !std::is_reference_v && requires(T& t) { + { t.Lock() } -> std::same_as; + { t.Unlock() } -> std::same_as; +}; template requires KLockable diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp index 1814f5e90e..f6e2cece81 100644 --- a/src/core/hle/kernel/svc/svc_info.cpp +++ b/src/core/hle/kernel/svc/svc_info.cpp @@ -37,8 +37,8 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle case InfoType::TotalNonSystemMemorySize: case InfoType::UsedNonSystemMemorySize: case InfoType::IsApplication: - case InfoType::FreeThreadCount: - case InfoType::AliasRegionExtraSize: { + case InfoType::FreeThreadCount: + case InfoType::AliasRegionExtraSize: { R_UNLESS(info_sub_id == 0, ResultInvalidEnumValue); const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable(); @@ -135,10 +135,10 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle } R_SUCCEED(); - case InfoType::AliasRegionExtraSize: - // TODO (jarrodnorwell): do this when KIP's NPDM header is finished - R_SUCCEED(); - + case InfoType::AliasRegionExtraSize: + // TODO (jarrodnorwell): do this when KIP's NPDM header is finished + R_SUCCEED(); + default: break; } diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index d02548ba73..985e95e3fa 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h @@ -153,7 +153,7 @@ enum class InfoType : u32 { ThreadTickCount = 25, IsSvcPermitted = 26, IoRegionHint = 27, - AliasRegionExtraSize = 28, + AliasRegionExtraSize = 28, MesosphereMeta = 65000, MesosphereCurrentProcess = 65001, diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 316370266d..ad27898114 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -458,9 +458,13 @@ constexpr inline Result __TmpCurrentResultReference = ResultSuccess; if (true) #define R_CONVERT(catch_type, convert_type) \ - R_CATCH(catch_type) { R_THROW(static_cast(convert_type)); } + R_CATCH(catch_type) { \ + R_THROW(static_cast(convert_type)); \ + } #define R_CONVERT_ALL(convert_type) \ - R_CATCH_ALL() { R_THROW(static_cast(convert_type)); } + R_CATCH_ALL() { \ + R_THROW(static_cast(convert_type)); \ + } #define R_ASSERT(res_expr) ASSERT(R_SUCCEEDED(res_expr)) diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 80a2b0b72b..2b014d99c9 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -496,5 +496,4 @@ void ProfileManager::SetUserPosition(u64 position, Common::UUID uuid) { WriteUserSaveFile(); } - }; // namespace Service::Account diff --git a/src/core/hle/service/am/applet.cpp b/src/core/hle/service/am/applet.cpp index 59ade29c8e..1c9f811104 100644 --- a/src/core/hle/service/am/applet.cpp +++ b/src/core/hle/service/am/applet.cpp @@ -26,7 +26,7 @@ void Applet::UpdateSuspensionStateLocked(bool force_message) { // Remove any forced resumption. lifecycle_manager.RemoveForceResumeIfPossible(); - const bool update_requested_focus_state = lifecycle_manager.UpdateRequestedFocusState(); + const bool update_requested_focus_state = lifecycle_manager.UpdateRequestedFocusState(); const bool curr_activity_runnable = lifecycle_manager.IsRunnable(); const bool prev_activity_runnable = is_activity_runnable; const bool was_changed = curr_activity_runnable != prev_activity_runnable; @@ -36,7 +36,7 @@ void Applet::UpdateSuspensionStateLocked(bool force_message) { process->Suspend(false); } else { process->Suspend(true); - lifecycle_manager.RequestResumeNotification(); + lifecycle_manager.RequestResumeNotification(); } is_activity_runnable = curr_activity_runnable; diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index 571904fab4..835cfe6ec8 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h @@ -92,6 +92,7 @@ struct Applet { // Channels std::deque> user_channel_launch_parameter{}; std::deque> preselected_user_launch_parameter{}; + std::deque> friend_invitation_storage_channel{}; // Caller applet std::weak_ptr caller_applet{}; diff --git a/src/core/hle/service/am/frontend/applet_cabinet.cpp b/src/core/hle/service/am/frontend/applet_cabinet.cpp index 4cbc80d639..2fb9a83531 100644 --- a/src/core/hle/service/am/frontend/applet_cabinet.cpp +++ b/src/core/hle/service/am/frontend/applet_cabinet.cpp @@ -18,9 +18,8 @@ namespace Service::AM::Frontend { Cabinet::Cabinet(Core::System& system_, std::shared_ptr applet_, LibraryAppletMode applet_mode_, const Core::Frontend::CabinetApplet& frontend_) - : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_}, service_context{ - system_, - "CabinetApplet"} { + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_}, + service_context{system_, "CabinetApplet"} { availability_change_event = service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent"); diff --git a/src/core/hle/service/am/frontend/applet_net_connect.cpp b/src/core/hle/service/am/frontend/applet_net_connect.cpp index 91ba664b7a..1bd81f7b41 100644 --- a/src/core/hle/service/am/frontend/applet_net_connect.cpp +++ b/src/core/hle/service/am/frontend/applet_net_connect.cpp @@ -15,7 +15,9 @@ namespace Service::AM::Frontend { -NetConnect::NetConnect(Core::System& system_, std::shared_ptr applet_, LibraryAppletMode applet_mode_, const Core::Frontend::NetConnectApplet& frontend_) +NetConnect::NetConnect(Core::System& system_, std::shared_ptr applet_, + LibraryAppletMode applet_mode_, + const Core::Frontend::NetConnectApplet& frontend_) : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} NetConnect::~NetConnect() = default; diff --git a/src/core/hle/service/am/frontend/applet_net_connect.h b/src/core/hle/service/am/frontend/applet_net_connect.h index d5d503ed41..4c667fa64e 100644 --- a/src/core/hle/service/am/frontend/applet_net_connect.h +++ b/src/core/hle/service/am/frontend/applet_net_connect.h @@ -14,8 +14,8 @@ namespace Service::AM::Frontend { class NetConnect final : public FrontendApplet { public: explicit NetConnect(Core::System& system_, std::shared_ptr applet_, - LibraryAppletMode applet_mode_, - const Core::Frontend::NetConnectApplet& frontend_); + LibraryAppletMode applet_mode_, + const Core::Frontend::NetConnectApplet& frontend_); ~NetConnect() override; void Initialize() override; diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index bb69869ade..2fd731c919 100644 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp @@ -85,7 +85,8 @@ FrontendAppletSet::FrontendAppletSet(CabinetApplet cabinet_applet, MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_, ProfileSelect profile_select_, - SoftwareKeyboard software_keyboard_, WebBrowser web_browser_, NetConnect net_connect_) + SoftwareKeyboard software_keyboard_, WebBrowser web_browser_, + NetConnect net_connect_) : cabinet{std::move(cabinet_applet)}, controller{std::move(controller_applet)}, error{std::move(error_applet)}, mii_edit{std::move(mii_edit_)}, parental_controls{std::move(parental_controls_applet)}, diff --git a/src/core/hle/service/am/frontend/applets.h b/src/core/hle/service/am/frontend/applets.h index 8eb08ea77b..73387cfc63 100644 --- a/src/core/hle/service/am/frontend/applets.h +++ b/src/core/hle/service/am/frontend/applets.h @@ -10,8 +10,8 @@ #include #include "common/swap.h" -#include "core/hle/service/am/applet.h" #include "core/frontend/applets/net_connect.h" +#include "core/hle/service/am/applet.h" union Result; diff --git a/src/core/hle/service/am/process_creation.cpp b/src/core/hle/service/am/process_creation.cpp index b5e31353a2..a1c6d8a5da 100644 --- a/src/core/hle/service/am/process_creation.cpp +++ b/src/core/hle/service/am/process_creation.cpp @@ -106,7 +106,7 @@ std::unique_ptr CreateApplicationProcess(std::vector& out_control, out_control = nacp.GetRawBytes(); } else { out_control.resize(sizeof(FileSys::RawNACP)); - std::fill(out_control.begin(), out_control.end(), (u8) 0); + std::fill(out_control.begin(), out_control.end(), (u8)0); } auto& storage = system.GetContentProviderUnion(); diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index 3bab5ac5f1..560244c714 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -456,8 +456,21 @@ Result IApplicationFunctions::GetFriendInvitationStorageChannelEvent( Result IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( Out> out_storage) { - LOG_INFO(Service_AM, "(STUBBED) called"); - R_THROW(AM::ResultNoDataInChannel); + LOG_DEBUG(Service_AM, "called"); + + std::scoped_lock lk{m_applet->lock}; + + auto& channel = m_applet->friend_invitation_storage_channel; + + if (channel.empty()) { + return AM::ResultNoDataInChannel; + } + + auto data = channel.back(); + channel.pop_back(); + + *out_storage = std::make_shared(system, std::move(data)); + R_SUCCEED(); } Result IApplicationFunctions::GetNotificationStorageChannelEvent( diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp index 6e1328fee7..633f2c2bbd 100644 --- a/src/core/hle/service/am/service/application_proxy.cpp +++ b/src/core/hle/service/am/service/application_proxy.cpp @@ -18,8 +18,8 @@ namespace Service::AM { IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr applet, Kernel::KProcess* process, WindowSystem& window_system) - : ServiceFramework{system_, "IApplicationProxy"}, - m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { + : ServiceFramework{system_, "IApplicationProxy"}, m_window_system{window_system}, + m_process{process}, m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, diff --git a/src/core/hle/service/am/service/display_controller.h b/src/core/hle/service/am/service/display_controller.h index 171feace6e..6e0cfff2db 100644 --- a/src/core/hle/service/am/service/display_controller.h +++ b/src/core/hle/service/am/service/display_controller.h @@ -20,7 +20,7 @@ public: private: Result GetLastForegroundCaptureImageEx(Out out_was_written, - OutBuffer out_image_data); + OutBuffer out_image_data); Result GetCallerAppletCaptureImageEx(Out out_was_written, OutBuffer out_image_data); Result TakeScreenShotOfOwnLayer(bool unknown0, s32 fbshare_layer_index); diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp index 5ce96a1e3f..e7e2398649 100644 --- a/src/core/hle/service/am/service/library_applet_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_accessor.cpp @@ -101,12 +101,12 @@ Result ILibraryAppletAccessor::PushInData(SharedPointer storage) { Result ILibraryAppletAccessor::PopOutData(Out> out_storage) { LOG_DEBUG(Service_AM, "called"); - if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet) { - Event m_system_event = caller_applet->lifecycle_manager.GetSystemEvent(); - m_system_event.Signal(); - caller_applet->lifecycle_manager.RequestResumeNotification(); - m_system_event.Clear(); - } + if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet) { + Event m_system_event = caller_applet->lifecycle_manager.GetSystemEvent(); + m_system_event.Signal(); + caller_applet->lifecycle_manager.RequestResumeNotification(); + m_system_event.Clear(); + } R_RETURN(m_broker->GetOutData().Pop(out_storage.Get())); } diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index 413388d40a..63124bf050 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp @@ -167,8 +167,8 @@ std::shared_ptr CreateFrontendApplet(Core::System& syste ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr applet, WindowSystem& window_system) - : ServiceFramework{system_, "ILibraryAppletCreator"}, - m_window_system{window_system}, m_applet{std::move(applet)} { + : ServiceFramework{system_, "ILibraryAppletCreator"}, m_window_system{window_system}, + m_applet{std::move(applet)} { static const FunctionInfo functions[] = { {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"}, {1, nullptr, "TerminateAllLibraryApplets"}, diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp index f9cfb82a90..655dd69b29 100644 --- a/src/core/hle/service/am/service/library_applet_proxy.cpp +++ b/src/core/hle/service/am/service/library_applet_proxy.cpp @@ -20,8 +20,8 @@ namespace Service::AM { ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr applet, Kernel::KProcess* process, WindowSystem& window_system) - : ServiceFramework{system_, "ILibraryAppletProxy"}, - m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { + : ServiceFramework{system_, "ILibraryAppletProxy"}, m_window_system{window_system}, + m_process{process}, m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 1db02b88fd..67851d3afb 100644 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp @@ -16,8 +16,8 @@ namespace Service::AM { ISelfController::ISelfController(Core::System& system_, std::shared_ptr applet, Kernel::KProcess* process) - : ServiceFramework{system_, "ISelfController"}, m_process{process}, m_applet{ - std::move(applet)} { + : ServiceFramework{system_, "ISelfController"}, m_process{process}, + m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&ISelfController::Exit>, "Exit"}, diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp index c435288a26..609c4aad3e 100644 --- a/src/core/hle/service/am/service/system_applet_proxy.cpp +++ b/src/core/hle/service/am/service/system_applet_proxy.cpp @@ -20,8 +20,8 @@ namespace Service::AM { ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr applet, Kernel::KProcess* process, WindowSystem& window_system) - : ServiceFramework{system_, "ISystemAppletProxy"}, - m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { + : ServiceFramework{system_, "ISystemAppletProxy"}, m_window_system{window_system}, + m_process{process}, m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp index 54396affbe..6b1759f037 100644 --- a/src/core/hle/service/am/service/window_controller.cpp +++ b/src/core/hle/service/am/service/window_controller.cpp @@ -11,8 +11,8 @@ namespace Service::AM { IWindowController::IWindowController(Core::System& system_, std::shared_ptr applet, WindowSystem& window_system) - : ServiceFramework{system_, "IWindowController"}, - m_window_system{window_system}, m_applet{std::move(applet)} { + : ServiceFramework{system_, "IWindowController"}, m_window_system{window_system}, + m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "CreateWindow"}, diff --git a/src/core/hle/service/aoc/purchase_event_manager.cpp b/src/core/hle/service/aoc/purchase_event_manager.cpp index 9e718510b4..1192263f8a 100644 --- a/src/core/hle/service/aoc/purchase_event_manager.cpp +++ b/src/core/hle/service/aoc/purchase_event_manager.cpp @@ -9,8 +9,8 @@ namespace Service::AOC { constexpr Result ResultNoPurchasedProductInfoAvailable{ErrorModule::NIMShop, 400}; IPurchaseEventManager::IPurchaseEventManager(Core::System& system_) - : ServiceFramework{system_, "IPurchaseEventManager"}, service_context{system, - "IPurchaseEventManager"} { + : ServiceFramework{system_, "IPurchaseEventManager"}, + service_context{system, "IPurchaseEventManager"} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IPurchaseEventManager::SetDefaultDeliveryTarget>, "SetDefaultDeliveryTarget"}, diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp index 416803acc3..9240cc3363 100644 --- a/src/core/hle/service/audio/audio_in.cpp +++ b/src/core/hle/service/audio/audio_in.cpp @@ -12,9 +12,8 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id, const std::string& device_name, const AudioInParameter& in_params, Kernel::KProcess* handle, u64 applet_resource_user_id) : ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"}, - event{service_context.CreateEvent("AudioInEvent")}, impl{std::make_shared(system_, - manager, event, - session_id)} { + event{service_context.CreateEvent("AudioInEvent")}, + impl{std::make_shared(system_, manager, event, session_id)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IAudioIn::GetAudioInState>, "GetAudioInState"}, diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp index 2675a57735..d55da17c84 100644 --- a/src/core/hle/service/audio/audio_in_manager.cpp +++ b/src/core/hle/service/audio/audio_in_manager.cpp @@ -10,8 +10,8 @@ namespace Service::Audio { using namespace AudioCore::AudioIn; IAudioInManager::IAudioInManager(Core::System& system_) - : ServiceFramework{system_, "audin:u"}, impl{std::make_unique( - system_)} { + : ServiceFramework{system_, "audin:u"}, + impl{std::make_unique(system_)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IAudioInManager::ListAudioIns>, "ListAudioIns"}, diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp index fc4aad2339..b78660cea6 100644 --- a/src/core/hle/service/audio/audio_renderer.cpp +++ b/src/core/hle/service/audio/audio_renderer.cpp @@ -14,8 +14,8 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, s32 session_id) : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, - impl{std::make_unique(system_, manager, rendered_event)}, process_handle{ - process_handle_} { + impl{std::make_unique(system_, manager, rendered_event)}, + process_handle{process_handle_} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IAudioRenderer::GetSampleRate>, "GetSampleRate"}, diff --git a/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp index ed393f7a26..8d64bd697a 100644 --- a/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp +++ b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp @@ -7,9 +7,8 @@ namespace Service::News { INewlyArrivedEventHolder::INewlyArrivedEventHolder(Core::System& system_) - : ServiceFramework{system_, "INewlyArrivedEventHolder"}, service_context{ - system_, - "INewlyArrivedEventHolder"} { + : ServiceFramework{system_, "INewlyArrivedEventHolder"}, + service_context{system_, "INewlyArrivedEventHolder"} { // clang-format off static const FunctionInfo functions[] = { {0, D<&INewlyArrivedEventHolder::Get>, "Get"}, diff --git a/src/core/hle/service/bcat/news/overwrite_event_holder.cpp b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp index 1712971e4d..33ea7c8951 100644 --- a/src/core/hle/service/bcat/news/overwrite_event_holder.cpp +++ b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp @@ -7,8 +7,8 @@ namespace Service::News { IOverwriteEventHolder::IOverwriteEventHolder(Core::System& system_) - : ServiceFramework{system_, "IOverwriteEventHolder"}, service_context{system_, - "IOverwriteEventHolder"} { + : ServiceFramework{system_, "IOverwriteEventHolder"}, + service_context{system_, "IOverwriteEventHolder"} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IOverwriteEventHolder::Get>, "Get"}, diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp index e636d90bc4..1825d345a6 100644 --- a/src/core/hle/service/caps/caps_manager.cpp +++ b/src/core/hle/service/caps/caps_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -440,8 +443,8 @@ Result AlbumManager::SaveImage(ApplicationAlbumEntry& out_entry, std::span( - dir_)}, + : ServiceFramework{system_, "IFileSystem"}, + backend{std::make_unique(dir_)}, size_getter{std::move(size_getter_)} { static const FunctionInfo functions[] = { {0, D<&IFileSystem::CreateFile>, "CreateFile"}, diff --git a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp index ff823586b3..9a603e89a2 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp @@ -12,8 +12,8 @@ namespace Service::FileSystem { ISaveDataInfoReader::ISaveDataInfoReader(Core::System& system_, std::shared_ptr save_data_controller_, FileSys::SaveDataSpaceId space) - : ServiceFramework{system_, "ISaveDataInfoReader"}, save_data_controller{ - save_data_controller_} { + : ServiceFramework{system_, "ISaveDataInfoReader"}, + save_data_controller{save_data_controller_} { static const FunctionInfo functions[] = { {0, D<&ISaveDataInfoReader::ReadSaveDataInfo>, "ReadSaveDataInfo"}, }; diff --git a/src/core/hle/service/glue/time/alarm_worker.cpp b/src/core/hle/service/glue/time/alarm_worker.cpp index 3ff071f4a0..21ace76936 100644 --- a/src/core/hle/service/glue/time/alarm_worker.cpp +++ b/src/core/hle/service/glue/time/alarm_worker.cpp @@ -11,8 +11,8 @@ namespace Service::Glue::Time { AlarmWorker::AlarmWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource) - : m_system{system}, m_ctx{system, "Glue:AlarmWorker"}, m_steady_clock_resource{ - steady_clock_resource} {} + : m_system{system}, m_ctx{system, "Glue:AlarmWorker"}, + m_steady_clock_resource{steady_clock_resource} {} AlarmWorker::~AlarmWorker() { m_system.CoreTiming().UnscheduleEvent(m_timer_timing_event); diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index 77bf8896cd..c1faf8eaab 100644 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp @@ -87,10 +87,8 @@ static Service::PSC::Time::LocationName GetTimeZoneString( } TimeManager::TimeManager(Core::System& system) - : m_steady_clock_resource{system}, m_time_zone_binary{system}, m_worker{ - system, - m_steady_clock_resource, - m_file_timestamp_worker} { + : m_steady_clock_resource{system}, m_time_zone_binary{system}, + m_worker{system, m_steady_clock_resource, m_file_timestamp_worker} { m_time_m = system.ServiceManager().GetService("time:m", true); diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp index b2e8159653..a89df753a4 100644 --- a/src/core/hle/service/glue/time/time_zone.cpp +++ b/src/core/hle/service/glue/time/time_zone.cpp @@ -22,9 +22,9 @@ TimeZoneService::TimeZoneService( std::shared_ptr time_zone_service) : ServiceFramework{system_, "ITimeZoneService"}, m_system{system}, m_can_write_timezone_device_location{can_write_timezone_device_location}, - m_file_timestamp_worker{file_timestamp_worker}, m_wrapped_service{std::move( - time_zone_service)}, - m_operation_event{m_system}, m_time_zone_binary{time_zone_binary} { + m_file_timestamp_worker{file_timestamp_worker}, + m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system}, + m_time_zone_binary{time_zone_binary} { // clang-format off static const FunctionInfo functions[] = { {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"}, diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp index 1dab3e9dcb..90cfe0a973 100644 --- a/src/core/hle/service/glue/time/worker.cpp +++ b/src/core/hle/service/glue/time/worker.cpp @@ -19,11 +19,11 @@ namespace Service::Glue::Time { TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource, FileTimestampWorker& file_timestamp_worker) - : m_system{system}, m_ctx{m_system, "Glue:TimeWorker"}, m_event{m_ctx.CreateEvent( - "Glue:TimeWorker:Event")}, + : m_system{system}, m_ctx{m_system, "Glue:TimeWorker"}, + m_event{m_ctx.CreateEvent("Glue:TimeWorker:Event")}, m_steady_clock_resource{steady_clock_resource}, - m_file_timestamp_worker{file_timestamp_worker}, m_timer_steady_clock{m_ctx.CreateEvent( - "Glue:TimeWorker:SteadyClockTimerEvent")}, + m_file_timestamp_worker{file_timestamp_worker}, + m_timer_steady_clock{m_ctx.CreateEvent("Glue:TimeWorker:SteadyClockTimerEvent")}, m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")}, m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} { m_timer_steady_clock_timing_event = Core::Timing::CreateEvent( diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp index 738c6d9ae2..9a9a188eca 100644 --- a/src/core/hle/service/hid/hid_debug_server.cpp +++ b/src/core/hle/service/hid/hid_debug_server.cpp @@ -17,8 +17,8 @@ namespace Service::HID { IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr resource, std::shared_ptr settings) - : ServiceFramework{system_, "hid:dbg"}, resource_manager{resource}, firmware_settings{ - settings} { + : ServiceFramework{system_, "hid:dbg"}, resource_manager{resource}, + firmware_settings{settings} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "DeactivateDebugPad"}, diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index ebda7fc3f2..bbd541cb82 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -587,10 +587,8 @@ Result IHidServer::ActivateGesture(u32 basic_gesture_id, ClientAppletResourceUse Result IHidServer::SetGestureOutputRanges(u32 param1, u32 param2, u32 param3, u32 param4) { // https://switchbrew.org/wiki/HID_services , Undocumented. 92 [18.0.0+] SetGestureOutputRanges - LOG_WARNING( - Service_HID, - "(STUBBED) called, param1={}, param2={}, param3={}, param4={}", - param1, param2, param3, param4); + LOG_WARNING(Service_HID, "(STUBBED) called, param1={}, param2={}, param3={}, param4={}", param1, + param2, param3, param4); R_SUCCEED(); } diff --git a/src/core/hle/service/ipc_helpers.h b/src/core/hle/service/ipc_helpers.h index 4b02872fba..97b46d5889 100644 --- a/src/core/hle/service/ipc_helpers.h +++ b/src/core/hle/service/ipc_helpers.h @@ -72,8 +72,8 @@ public: u32 num_handles_to_copy_ = 0, u32 num_objects_to_move_ = 0, Flags flags = Flags::None) : RequestHelperBase(ctx), normal_params_size(normal_params_size_), - num_handles_to_copy(num_handles_to_copy_), - num_objects_to_move(num_objects_to_move_), kernel{ctx.kernel} { + num_handles_to_copy(num_handles_to_copy_), num_objects_to_move(num_objects_to_move_), + kernel{ctx.kernel} { memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 0090e8568d..8df63f9e26 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -40,8 +40,8 @@ class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { public: explicit DynarmicCallbacks64(Core::Memory::Memory& memory_, std::vector& local_memory_, IntervalSet& mapped_ranges_, JITContextImpl& parent_) - : memory{memory_}, local_memory{local_memory_}, - mapped_ranges{mapped_ranges_}, parent{parent_} {} + : memory{memory_}, local_memory{local_memory_}, mapped_ranges{mapped_ranges_}, + parent{parent_} {} u8 MemoryRead8(u64 vaddr) override { return ReadMemory(vaddr); diff --git a/src/core/hle/service/ldn/lan_discovery.cpp b/src/core/hle/service/ldn/lan_discovery.cpp index 7d677e6664..e24a8fb28c 100644 --- a/src/core/hle/service/ldn/lan_discovery.cpp +++ b/src/core/hle/service/ldn/lan_discovery.cpp @@ -37,7 +37,7 @@ void LanStation::OverrideInfo() { } LANDiscovery::LANDiscovery() - : stations({{{1, this}, {2, this}, {3, this}, {4, this}, {5, this}, {6, this}, {7, this}}}){} + : stations({{{1, this}, {2, this}, {3, this}, {4, this}, {5, this}, {6, this}, {7, this}}}) {} LANDiscovery::~LANDiscovery() { if (inited) { diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp index 69170a879d..743244b996 100644 --- a/src/core/hle/service/ldn/user_local_communication_service.cpp +++ b/src/core/hle/service/ldn/user_local_communication_service.cpp @@ -24,8 +24,7 @@ namespace Service::LDN { IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& system_) : ServiceFramework{system_, "IUserLocalCommunicationService"}, - service_context{system, "IUserLocalCommunicationService"}, - lan_discovery{} { + service_context{system, "IUserLocalCommunicationService"}, lan_discovery{} { // clang-format off static const FunctionInfo functions[] = { {0, C<&IUserLocalCommunicationService::GetState>, "GetState"}, diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index adaaea571a..5232bcd050 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -23,8 +23,8 @@ class IDatabaseService final : public ServiceFramework { public: explicit IDatabaseService(Core::System& system_, std::shared_ptr mii_manager, bool is_system_) - : ServiceFramework{system_, "IDatabaseService"}, manager{mii_manager}, is_system{ - is_system_} { + : ServiceFramework{system_, "IDatabaseService"}, manager{mii_manager}, + is_system{is_system_} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IDatabaseService::IsUpdated>, "IsUpdated"}, diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp index 8fa2341ffb..da9fbc98fc 100644 --- a/src/core/hle/service/mm/mm_u.cpp +++ b/src/core/hle/service/mm/mm_u.cpp @@ -7,43 +7,43 @@ #include "core/hle/service/server_manager.h" #include "core/hle/service/sm/sm.h" -#include - -namespace Service::MM { -enum class Module : u32 { - CPU = 0, - GPU = 1, - EMC = 2, - SYS_BUS = 3, - M_SELECT = 4, - NVDEC = 5, - NVENC = 6, - NVJPG = 7, - TEST = 8 -}; - -class Session { -public: - Session(Module module_, u32 request_id_, bool is_auto_clear_event_) { - this->module = module_; - this->request_id = request_id_; - this->is_auto_clear_event = is_auto_clear_event_; - this->min = 0; - this->max = -1; - }; - -public: - Module module; - u32 request_id, min; - s32 max; - bool is_auto_clear_event; +#include + +namespace Service::MM { +enum class Module : u32 { + CPU = 0, + GPU = 1, + EMC = 2, + SYS_BUS = 3, + M_SELECT = 4, + NVDEC = 5, + NVENC = 6, + NVJPG = 7, + TEST = 8 +}; + +class Session { +public: + Session(Module module_, u32 request_id_, bool is_auto_clear_event_) { + this->module = module_; + this->request_id = request_id_; + this->is_auto_clear_event = is_auto_clear_event_; + this->min = 0; + this->max = -1; + }; + +public: + Module module; + u32 request_id, min; + s32 max; + bool is_auto_clear_event; + + void SetAndWait(u32 min_, s32 max_) { + this->min = min_; + this->max = max_; + } +}; - void SetAndWait(u32 min_, s32 max_) { - this->min = min_; - this->max = max_; - } -}; - class MM_U final : public ServiceFramework { public: explicit MM_U(Core::System& system_) : ServiceFramework{system_, "mm:u"} { @@ -65,53 +65,53 @@ public: private: void InitializeOld(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - rp.Pop(); - const auto event_clear_mode = rp.Pop(); + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + rp.Pop(); + const auto event_clear_mode = rp.Pop(); + + const bool is_auto_clear_event = event_clear_mode == 1; + + sessions.push_back({module, request_id++, is_auto_clear_event}); - const bool is_auto_clear_event = event_clear_mode == 1; - - sessions.push_back({module, request_id++, is_auto_clear_event}); - IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void FinalizeOld(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - - for (auto it = sessions.begin(); it != sessions.end(); ++it) { - if (it->module == module) { - sessions.erase(it); - break; - } - } + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + + for (auto it = sessions.begin(); it != sessions.end(); ++it) { + if (it->module == module) { + sessions.erase(it); + break; + } + } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void SetAndWaitOld(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - const auto min = rp.Pop(); - const auto max = rp.Pop(); + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + const auto min = rp.Pop(); + const auto max = rp.Pop(); + + for (auto& session : sessions) { + if (session.module == module) { + session.SetAndWait(min, max); + break; + } + } - for (auto& session : sessions) { - if (session.module == module) { - session.SetAndWait(min, max); - break; - } - } - IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -119,72 +119,72 @@ private: void GetOld(HLERequestContext& ctx) { LOG_DEBUG(Service_MM, "(STUBBED) called"); - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - - for (const auto& session : sessions) { - if (session.module == module) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - rb.Push(session.min); - return; - } - } - + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + + for (const auto& session : sessions) { + if (session.module == module) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + rb.Push(session.min); + return; + } + } + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(0); + rb.Push(0); } void Initialize(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - rp.Pop(); - const auto event_clear_mode = rp.Pop(); - - const bool is_auto_clear_event = event_clear_mode == 1; - - sessions.push_back({module, request_id++, is_auto_clear_event}); + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + rp.Pop(); + const auto event_clear_mode = rp.Pop(); + + const bool is_auto_clear_event = event_clear_mode == 1; + + sessions.push_back({module, request_id++, is_auto_clear_event}); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(request_id - 1); + rb.Push(request_id - 1); } void Finalize(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto id = rp.Pop(); + + for (auto it = sessions.begin(); it != sessions.end(); ++it) { + if (it->request_id == id) { + sessions.erase(it); + break; + } + } - IPC::RequestParser rp{ctx}; - const auto id = rp.Pop(); - - for (auto it = sessions.begin(); it != sessions.end(); ++it) { - if (it->request_id == id) { - sessions.erase(it); - break; - } - } - IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void SetAndWait(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto id = rp.Pop(); - const auto min = rp.Pop(); - const auto max = rp.Pop(); + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto id = rp.Pop(); + const auto min = rp.Pop(); + const auto max = rp.Pop(); + + for (auto& session : sessions) { + if (session.request_id == id) { + session.SetAndWait(min, max); + break; + } + } - for (auto& session : sessions) { - if (session.request_id == id) { - session.SetAndWait(min, max); - break; - } - } - IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -192,25 +192,25 @@ private: void Get(HLERequestContext& ctx) { LOG_DEBUG(Service_MM, "(STUBBED) called"); - IPC::RequestParser rp{ctx}; - const auto id = rp.Pop(); - - for (const auto& session : sessions) { - if (session.request_id == id) { - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(session.min); - return; - } - } - + IPC::RequestParser rp{ctx}; + const auto id = rp.Pop(); + + for (const auto& session : sessions) { + if (session.request_id == id) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(session.min); + return; + } + } + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(0); + rb.Push(0); } - std::vector sessions; - u32 request_id{1}; + std::vector sessions; + u32 request_id{1}; }; void LoopProcess(Core::System& system) { diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index e18afdb88b..4710167364 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -67,7 +67,6 @@ static u128 MakeUuidFromName(std::string_view name) { return {h1, h2}; } - // This is nn::nifm::RequestState enum class RequestState : u32 { NotSubmitted = 1, @@ -217,7 +216,6 @@ struct PendingProfile { std::array passphrase{}; }; - constexpr Result ResultPendingConnection{ErrorModule::NIFM, 111}; constexpr Result ResultInvalidInput{ErrorModule::NIFM, 112}; constexpr Result ResultNetworkCommunicationDisabled{ErrorModule::NIFM, 1111}; @@ -278,8 +276,7 @@ private: IPC::ResponseBuilder{ctx, 2}.Push(ResultSuccess); } - void IsProcessing(HLERequestContext& ctx) - { + void IsProcessing(HLERequestContext& ctx) { const bool processing = state.load() == State::Processing; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); @@ -306,7 +303,7 @@ private: enum class State { Idle, Processing, Finished }; - void WorkerThread() { + void WorkerThread() { using namespace std::chrono_literals; scan_results = Network::ScanWifiNetworks(3s); @@ -321,7 +318,6 @@ private: Finish(ok ? ResultSuccess : ResultPendingConnection); } - void Finish(Result rc) { worker_result.store(rc); state.store(State::Finished); @@ -546,6 +542,7 @@ void IGeneralService::CreateRequest(HLERequestContext& ctx) { void IGeneralService::GetCurrentNetworkProfile(HLERequestContext& ctx) { Network::RefreshFromHost(); + const auto net_iface = Network::GetSelectedNetworkInterface(); const auto& st = Network::EmuNetState::Get(); SfNetworkProfileData profile{}; @@ -559,7 +556,7 @@ void IGeneralService::GetCurrentNetworkProfile(HLERequestContext& ctx) { profile.ip_setting_data.dns_setting.is_automatic = true; profile.ip_setting_data.dns_setting.primary_dns = {1, 1, 1, 1}; - profile.ip_setting_data.dns_setting.secondary_dns = {8, 8, 8, 8}; + profile.ip_setting_data.dns_setting.secondary_dns = {1, 0, 0, 1}, profile.uuid = MakeUuidFromName(st.ssid); profile.profile_type = static_cast(NetworkProfileType::User); @@ -568,6 +565,14 @@ void IGeneralService::GetCurrentNetworkProfile(HLERequestContext& ctx) { std::strncpy(profile.network_name.data(), st.ssid, sizeof(profile.network_name) - 1); + if (auto room_member = Network::GetRoomMember().lock()) { + if (room_member->IsConnected()) { + profile.ip_setting_data.ip_address_setting.ip_address = + room_member->GetFakeIpAddress(); + } + profile.ip_setting_data.dns_setting.secondary_dns = {8, 8, 8, 8}; + } + if (st.via_wifi) { profile.wireless_setting_data.ssid_length = static_cast(std::strlen(st.ssid)); std::memcpy(profile.wireless_setting_data.ssid.data(), st.ssid, @@ -665,8 +670,9 @@ void IGeneralService::GetNetworkProfile(HLERequestContext& ctx) { std::memcpy(net_name.data(), net_state.ssid, ssid_len); SfWirelessSettingData wifi{}; - wifi.ssid_length = static_cast(std::min(std::strlen(net_state.ssid), net_name.size())); - wifi.is_secured = !net_state.secure; //somehow reversed + wifi.ssid_length = + static_cast(std::min(std::strlen(net_state.ssid), net_name.size())); + wifi.is_secured = !net_state.secure; // somehow reversed wifi.passphrase = {"password"}; std::memcpy(wifi.ssid.data(), net_state.ssid, wifi.ssid_length); @@ -693,16 +699,21 @@ void IGeneralService::GetNetworkProfile(HLERequestContext& ctx) { .uuid{MakeUuidFromName(net_state.ssid)}, .network_name{net_name}, .profile_type = static_cast(NetworkProfileType::User), - .interface_type = - static_cast(net_iface->kind == - Network::HostAdapterKind::Wifi ? NetworkInterfaceType::WiFi_Ieee80211 : NetworkInterfaceType::Ethernet), - .wireless_setting_data{wifi} - }; + .interface_type = static_cast(net_iface->kind == Network::HostAdapterKind::Wifi + ? NetworkInterfaceType::WiFi_Ieee80211 + : NetworkInterfaceType::Ethernet), + .wireless_setting_data{wifi}}; }(); + if (auto room_member = Network::GetRoomMember().lock()) { + if (room_member->IsConnected()) { + profile.ip_setting_data.ip_address_setting.ip_address = room_member->GetFakeIpAddress(); + } + } + ctx.WriteBuffer(profile); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); rb.PushIpcInterface(system); } @@ -732,7 +743,6 @@ void IGeneralService::SetNetworkProfile(HLERequestContext& ctx) { IPC::ResponseBuilder{ctx, 2}.Push(ResultSuccess); } - void IGeneralService::RemoveNetworkProfile(HLERequestContext& ctx) { LOG_WARNING(Service_NIFM, "(STUBBED) called"); @@ -759,7 +769,6 @@ void IGeneralService::GetScanDataV2(HLERequestContext& ctx) { const std::size_t max_rows = guest_bytes / sizeof(AccessPointDataV3); const std::size_t rows_copy = std::min(scans.size(), max_rows); - std::vector rows; rows.resize(rows_copy); @@ -776,7 +785,7 @@ void IGeneralService::GetScanDataV2(HLERequestContext& ctx) { ap.strength = to_bars(s.quality); bool is_connected = std::strncmp(net_state.ssid, ap.ssid, ap.ssid_len) == 0 && - net_state.ssid[ap.ssid_len] == '\0'; + net_state.ssid[ap.ssid_len] == '\0'; ap.visible = (is_connected) ? 0 : 1; ap.has_password = (s.flags & 2) ? 2 : 1; @@ -886,7 +895,16 @@ void IGeneralService::GetCurrentIpConfigInfo(HLERequestContext& ctx) { info.dns.secondary_dns = {8, 8, 8, 8}; } - IPC::ResponseBuilder rb{ctx, 2 + (sizeof(IpConfigInfo) + 3) / 4}; + if (auto room_member = Network::GetRoomMember().lock()) { + if (room_member->IsConnected()) { + info.ip.ip_address = room_member->GetFakeIpAddress(); + } + info.dns.is_automatic = true; + info.dns.primary_dns = {1, 1, 1, 1}; + info.dns.secondary_dns = {8, 8, 8, 8}; + } + + IPC::ResponseBuilder rb{ctx, 2 + (sizeof(IpConfigInfo) + 3) / sizeof(u32)}; rb.Push(ResultSuccess); rb.PushRaw(info); } diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 8210fd92a6..8963f86c78 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -241,7 +241,7 @@ public: private: void CreateServerInterface(HLERequestContext& ctx) { - LOG_DEBUG(Service_NIM, "(STUBBED) called"); + LOG_DEBUG(Service_NIM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); rb.PushIpcInterface(system); @@ -258,14 +258,14 @@ private: rb.Push(ResultSuccess); rb.Push(false); } - - void CreateServerInterface2(HLERequestContext& ctx) { - LOG_DEBUG(Service_NIM, "(STUBBED) called."); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system); - } + + void CreateServerInterface2(HLERequestContext& ctx) { + LOG_DEBUG(Service_NIM, "(STUBBED) called."); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } }; class NIM_SHP final : public ServiceFramework { diff --git a/src/core/hle/service/ns/application_manager_interface.cpp b/src/core/hle/service/ns/application_manager_interface.cpp index f1ddba8231..6f16f39bb6 100644 --- a/src/core/hle/service/ns/application_manager_interface.cpp +++ b/src/core/hle/service/ns/application_manager_interface.cpp @@ -315,7 +315,8 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ IApplicationManagerInterface::~IApplicationManagerInterface() = default; -Result IApplicationManagerInterface::UnregisterNetworkServiceAccountWithUserSaveDataDeletion(Common::UUID user_id) { +Result IApplicationManagerInterface::UnregisterNetworkServiceAccountWithUserSaveDataDeletion( + Common::UUID user_id) { LOG_DEBUG(Service_NS, "called, user_id={}", user_id.FormattedString()); R_SUCCEED(); } diff --git a/src/core/hle/service/ns/dynamic_rights_interface.cpp b/src/core/hle/service/ns/dynamic_rights_interface.cpp index b5a507d6e9..8ba8e5fd66 100644 --- a/src/core/hle/service/ns/dynamic_rights_interface.cpp +++ b/src/core/hle/service/ns/dynamic_rights_interface.cpp @@ -63,8 +63,8 @@ Result IDynamicRightsInterface::VerifyActivatedRightsOwners(u64 rights_handle) { R_SUCCEED(); } -Result IDynamicRightsInterface::HasAccountRestrictedRightsInRunningApplications( - Out out_status, u64 rights_handle) { +Result IDynamicRightsInterface::HasAccountRestrictedRightsInRunningApplications(Out out_status, + u64 rights_handle) { LOG_WARNING(Service_NS, "(STUBBED) called, rights_handle={:#x}", rights_handle); *out_status = 0; R_SUCCEED(); diff --git a/src/core/hle/service/ns/dynamic_rights_interface.h b/src/core/hle/service/ns/dynamic_rights_interface.h index e9429ea915..fbf44053bc 100644 --- a/src/core/hle/service/ns/dynamic_rights_interface.h +++ b/src/core/hle/service/ns/dynamic_rights_interface.h @@ -20,8 +20,7 @@ private: Result NotifyApplicationRightsCheckStart(); Result GetRunningApplicationStatus(Out out_status, u64 rights_handle); Result VerifyActivatedRightsOwners(u64 rights_handle); - Result HasAccountRestrictedRightsInRunningApplications(Out out_status, - u64 rights_handle); + Result HasAccountRestrictedRightsInRunningApplications(Out out_status, u64 rights_handle); }; } // namespace Service::NS diff --git a/src/core/hle/service/nvdrv/core/container.cpp b/src/core/hle/service/nvdrv/core/container.cpp index 9edce03f64..8857276800 100644 --- a/src/core/hle/service/nvdrv/core/container.cpp +++ b/src/core/hle/service/nvdrv/core/container.cpp @@ -102,11 +102,11 @@ SessionId Container::OpenSession(Kernel::KProcess* process) { cur_addr = next_address; } session.has_preallocated_area = false; - auto start_region = region_size >= 32_MiB ? smmu.Allocate(region_size) : 0; - if (start_region != 0) { - session.mapper = std::make_unique(region_start, start_region, region_size, - asid, impl->host1x); - smmu.TrackContinuity(start_region, region_start, region_size, asid); + auto device_region_start = region_size >= 32_MiB ? smmu.Allocate(region_size) : 0; + if (device_region_start != 0) { + session.mapper = std::make_unique(region_start, device_region_start, + region_size, asid, impl->host1x); + smmu.TrackContinuity(device_region_start, region_start, region_size, asid); session.has_preallocated_area = true; LOG_DEBUG(Debug, "Preallocation created!"); } diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index 453cb58319..5f85d20b48 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp @@ -2,10 +2,7 @@ // SPDX-FileCopyrightText: 2022 Skyline Team and Contributors // SPDX-License-Identifier: GPL-3.0-or-later -#include - #include "common/alignment.h" -#include "common/assert.h" #include "common/logging/log.h" #include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/heap_mapper.h" @@ -22,21 +19,21 @@ NvMap::Handle::Handle(u64 size_, Id id_) flags.raw = 0; } -NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, - NvCore::SessionId pSessionId) { +NvResult NvMap::Handle::Alloc(Flags flags_, u32 align_, u8 kind_, u64 address_, + NvCore::SessionId session_id_) { std::scoped_lock lock(mutex); // Handles cannot be allocated twice if (allocated) { return NvResult::AccessDenied; } - flags = pFlags; - kind = pKind; - align = pAlign < YUZU_PAGESIZE ? YUZU_PAGESIZE : pAlign; - session_id = pSessionId; + flags = flags_; + kind = kind_; + align = align_ < YUZU_PAGESIZE ? YUZU_PAGESIZE : align_; + session_id = session_id_; // This flag is only applicable for handles with an address passed - if (pAddress) { + if (address_) { flags.keep_uncached_after_free.Assign(0); } else { LOG_CRITICAL(Service_NVDRV, @@ -45,7 +42,7 @@ NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size = Common::AlignUp(size, YUZU_PAGESIZE); aligned_size = Common::AlignUp(size, align); - address = pAddress; + address = address_; allocated = true; return NvResult::Success; @@ -181,7 +178,7 @@ DAddr NvMap::PinHandle(NvMap::Handle::Id handle, bool low_area_pin) { { // Lock now to prevent our queue entry from being removed for allocation in-between the // following check and erase - std::scoped_lock queueLock(unmap_queue_lock); + std::scoped_lock queue_lock(unmap_queue_lock); if (handle_description->unmap_queue_entry) { unmap_queue.erase(*handle_description->unmap_queue_entry); handle_description->unmap_queue_entry.reset(); @@ -211,13 +208,13 @@ DAddr NvMap::PinHandle(NvMap::Handle::Id handle, bool low_area_pin) { size_t aligned_up = Common::AlignUp(map_size, BIG_PAGE_SIZE); while ((address = smmu.Allocate(aligned_up)) == 0) { // Free handles until the allocation succeeds - std::scoped_lock queueLock(unmap_queue_lock); - if (auto freeHandleDesc{unmap_queue.front()}) { + std::scoped_lock queue_lock(unmap_queue_lock); + if (auto free_handle_desc{unmap_queue.front()}) { // Handles in the unmap queue are guaranteed not to be pinned so don't bother // checking if they are before unmapping - std::scoped_lock freeLock(freeHandleDesc->mutex); + std::scoped_lock free_lock(free_handle_desc->mutex); if (handle_description->d_address) - UnmapHandle(*freeHandleDesc); + UnmapHandle(*free_handle_desc); } else { LOG_CRITICAL(Service_NVDRV, "Ran out of SMMU address space!"); } @@ -248,9 +245,9 @@ void NvMap::UnpinHandle(Handle::Id handle) { std::scoped_lock lock(handle_description->mutex); if (--handle_description->pins < 0) { - LOG_WARNING(Service_NVDRV, "Pin count imbalance detected!"); - } else if (!handle_description->pins) { - std::scoped_lock queueLock(unmap_queue_lock); + LOG_WARNING(Service_NVDRV, "Handle {} has negative pin count", handle); + } else if (handle_description->pins == 0) { + std::scoped_lock queue_lock(unmap_queue_lock); // Add to the unmap queue allowing this handle's memory to be freed if needed unmap_queue.push_back(handle_description); @@ -272,20 +269,21 @@ void NvMap::DuplicateHandle(Handle::Id handle, bool internal_session) { } std::optional NvMap::FreeHandle(Handle::Id handle, bool internal_session) { - std::weak_ptr hWeak{GetHandle(handle)}; - FreeInfo freeInfo; + std::weak_ptr weak_handle{GetHandle(handle)}; + FreeInfo free_info; // We use a weak ptr here so we can tell when the handle has been freed and report that back to // guest - if (auto handle_description = hWeak.lock()) { + if (auto handle_description = weak_handle.lock()) { std::scoped_lock lock(handle_description->mutex); if (internal_session) { if (--handle_description->internal_dupes < 0) - LOG_WARNING(Service_NVDRV, "Internal duplicate count imbalance detected!"); + LOG_WARNING(Service_NVDRV, "Internal duplicate count of handle {} is negative", + handle); } else { if (--handle_description->dupes < 0) { - LOG_WARNING(Service_NVDRV, "User duplicate count imbalance detected!"); + LOG_WARNING(Service_NVDRV, "User duplicate count of handle {} is negative", handle); } else if (handle_description->dupes == 0) { // Force unmap the handle if (handle_description->d_address) { @@ -307,7 +305,7 @@ std::optional NvMap::FreeHandle(Handle::Id handle, bool interna handle); } - freeInfo = { + free_info = { .address = handle_description->address, .size = handle_description->size, .was_uncached = handle_description->flags.map_uncached.Value() != 0, @@ -318,12 +316,12 @@ std::optional NvMap::FreeHandle(Handle::Id handle, bool interna } // If the handle hasn't been freed from memory, mark that - if (!hWeak.expired()) { + if (!weak_handle.expired()) { LOG_DEBUG(Service_NVDRV, "nvmap handle: {} wasn't freed as it is still in use", handle); - freeInfo.can_unlock = false; + free_info.can_unlock = false; } - return freeInfo; + return free_info; } void NvMap::UnmapAllHandles(NvCore::SessionId session_id) { diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h index b8be599ae9..7f88120efb 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.h +++ b/src/core/hle/service/nvdrv/core/nvmap.h @@ -83,8 +83,8 @@ public: * @brief Sets up the handle with the given memory config, can allocate memory from the tmem * if a 0 address is passed */ - [[nodiscard]] NvResult Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, - NvCore::SessionId pSessionId); + [[nodiscard]] NvResult Alloc(Flags flags_, u32 align_, u8 kind_, u64 address_, + NvCore::SessionId session_id_); /** * @brief Increases the dupe counter of the handle for the given session diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.h b/src/core/hle/service/nvdrv/core/syncpoint_manager.h index 7728ff5967..12cdf6b19b 100644 --- a/src/core/hle/service/nvdrv/core/syncpoint_manager.h +++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.h @@ -97,7 +97,7 @@ public: 0x0, // `Display` is unimplemented 0x37, // `NvJpg` 0x0, // `TSec` is unimplemented - }; //!< Maps each channel ID to a constant syncpoint + }; //!< Maps each channel ID to a constant syncpoint private: /** diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 68fe388741..6947bcec0b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -327,7 +327,7 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { try { auto mapping{mapping_map.at(params.offset)}; - if (mapping->size < params.mapping_size) { + if (mapping->size < params.buffer_offset + params.mapping_size) { LOG_WARNING(Service_NVDRV, "Cannot remap a partially mapped GPU address space region: 0x{:X}", params.offset); @@ -335,7 +335,7 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { } u64 gpu_address{static_cast(params.offset + params.buffer_offset)}; - VAddr device_address{mapping->ptr + params.buffer_offset}; + DAddr device_address{mapping->ptr + params.buffer_offset}; gmmu->Map(gpu_address, device_address, params.mapping_size, static_cast(params.kind), mapping->big_page); @@ -355,7 +355,7 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { DAddr device_address{ static_cast(nvmap.PinHandle(params.handle, false) + params.buffer_offset)}; - u64 size{params.mapping_size ? params.mapping_size : handle->orig_size}; + u64 size{params.mapping_size ? params.mapping_size : handle->orig_size - params.buffer_offset}; bool big_page{[&]() { if (Common::IsAligned(handle->align, vm.big_page_size)) { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index d2ab05b214..5cb711eac9 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -149,7 +149,7 @@ private: u64_le gpu_time{}; INSERT_PADDING_WORDS(2); }; - static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); + static_assert(sizeof(IoctlGetGpuTime) == 16, "IoctlGetGpuTime is incorrect size"); NvResult GetCharacteristics1(IoctlCharacteristics& params); NvResult GetCharacteristics3(IoctlCharacteristics& params, diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index efc9cca1cc..630ca3c038 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -75,6 +75,8 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu return WrapFixed(this, &nvhost_gpu::SetErrorNotifier, input, output); case 0xd: return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); + case 0x18: + return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx, input, output, fd); case 0x1a: return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output, fd); case 0x1b: @@ -167,12 +169,36 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) { return NvResult::Success; } -NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) { - LOG_WARNING(Service_NVDRV, - "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " - "unk1={:X}, unk2={:X}, unk3={:X}", - params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, - params.unk3); +NvResult nvhost_gpu::AllocGPFIFOEx(IoctlAllocGpfifoEx& params, DeviceFD fd) { + LOG_DEBUG(Service_NVDRV, + "called, num_entries={:X}, flags={:X}, reserved1={:X}, " + "reserved2={:X}, reserved3={:X}", + params.num_entries, params.flags, params.reserved[0], params.reserved[1], + params.reserved[2]); + + if (channel_state->initialized) { + LOG_CRITICAL(Service_NVDRV, "Already allocated!"); + return NvResult::AlreadyAllocated; + } + + u64 program_id{}; + if (auto* const session = core.GetSession(sessions[fd]); session != nullptr) { + program_id = session->process->GetProgramId(); + } + + system.GPU().InitChannel(*channel_state, program_id); + + params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); + + return NvResult::Success; +} + +NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx& params, DeviceFD fd) { + LOG_DEBUG(Service_NVDRV, + "called, num_entries={:X}, flags={:X}, reserved1={:X}, " + "reserved2={:X}, reserved3={:X}", + params.num_entries, params.flags, params.reserved[0], params.reserved[1], + params.reserved[2]); if (channel_state->initialized) { LOG_CRITICAL(Service_NVDRV, "Already allocated!"); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index e0aeef9536..b4ea1e5f60 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -128,27 +128,13 @@ private: static_assert(sizeof(NvFence) == 8, "Fence is incorrect size"); struct IoctlAllocGpfifoEx { - u32_le num_entries{}; - u32_le flags{}; - u32_le unk0{}; - u32_le unk1{}; - u32_le unk2{}; - u32_le unk3{}; - u32_le unk4{}; - u32_le unk5{}; - }; - static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx is incorrect size"); - - struct IoctlAllocGpfifoEx2 { u32_le num_entries{}; // in + u32_le num_jobs{}; // in u32_le flags{}; // in - u32_le unk0{}; // in (1 works) NvFence fence_out{}; // out - u32_le unk1{}; // in - u32_le unk2{}; // in - u32_le unk3{}; // in + std::array reserved{}; // in and ingored (for now) according to switch brew }; - static_assert(sizeof(IoctlAllocGpfifoEx2) == 32, "IoctlAllocGpfifoEx2 is incorrect size"); + static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx2 is incorrect size"); struct IoctlAllocObjCtx { u32_le class_num{}; // 0x902D=2d, 0xB197=3d, 0xB1C0=compute, 0xA140=kepler, 0xB0B5=DMA, @@ -192,7 +178,8 @@ private: NvResult ZCullBind(IoctlZCullBind& params); NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); NvResult SetChannelPriority(IoctlChannelSetPriority& params); - NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd); + NvResult AllocGPFIFOEx(IoctlAllocGpfifoEx& params, DeviceFD fd); + NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx& params, DeviceFD fd); NvResult AllocateObjectContext(IoctlAllocObjCtx& params); NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h index 63e6377603..0e26b6fef6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h @@ -38,7 +38,7 @@ protected: u32_le offset{}; u32_le count{}; }; - static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC, + static_assert(sizeof(IoctlSubmitCommandBuffer) == 12, "IoctlSubmitCommandBuffer is incorrect size"); struct IoctlSubmit { u32_le cmd_buffer_count{}; @@ -53,7 +53,7 @@ protected: u32 offset{}; s32 word_count{}; }; - static_assert(sizeof(CommandBuffer) == 0xC, "CommandBuffer has incorrect size"); + static_assert(sizeof(CommandBuffer) == 12, "CommandBuffer has incorrect size"); struct Reloc { s32 cmdbuffer_memory{}; @@ -61,7 +61,7 @@ protected: s32 target{}; s32 target_offset{}; }; - static_assert(sizeof(Reloc) == 0x10, "Reloc has incorrect size"); + static_assert(sizeof(Reloc) == 16, "Reloc has incorrect size"); struct SyncptIncr { u32 id{}; @@ -70,7 +70,7 @@ protected: u32 unk1{}; u32 unk2{}; }; - static_assert(sizeof(SyncptIncr) == 0x14, "SyncptIncr has incorrect size"); + static_assert(sizeof(SyncptIncr) == 20, "SyncptIncr has incorrect size"); struct IoctlGetSyncpoint { // Input @@ -84,14 +84,14 @@ protected: u32_le unknown{}; // seems to be ignored? Nintendo added this u32_le value{}; }; - static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size"); + static_assert(sizeof(IoctlGetWaitbase) == 8, "IoctlGetWaitbase is incorrect size"); struct IoctlMapBuffer { u32_le num_entries{}; u32_le data_address{}; // Ignored by the driver. u32_le attach_host_ch_das{}; }; - static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); + static_assert(sizeof(IoctlMapBuffer) == 12, "IoctlMapBuffer is incorrect size"); struct IocGetIdParams { // Input @@ -106,7 +106,7 @@ protected: u32_le map_handle{}; u32_le map_address{}; }; - static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); + static_assert(sizeof(MapBufferEntry) == 8, "MapBufferEntry is incorrect size"); /// Ioctl command implementations NvResult SetNVMAPfd(IoctlSetNvmapFD&); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index f87d53f12c..a854b5167d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp @@ -48,7 +48,7 @@ void nvhost_nvjpg::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {} void nvhost_nvjpg::OnClose(DeviceFD fd) {} NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) { - LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); + LOG_DEBUG(Service_NVDRV, "params: (fd={})", params.nvmap_fd); nvmap_fd = params.nvmap_fd; return NvResult::Success; diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index da61a3bfeb..4e3dd0986c 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -89,7 +89,6 @@ NvResult nvmap::IocCreate(IocCreateParams& params) { } handle_description->orig_size = params.size; // Orig size is the unaligned size params.handle = handle_description->id; - LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size); return NvResult::Success; } @@ -103,7 +102,7 @@ NvResult nvmap::IocAlloc(IocAllocParams& params, DeviceFD fd) { } if ((params.align - 1) & params.align) { - LOG_CRITICAL(Service_NVDRV, "Incorrect alignment used, alignment={:08X}", params.align); + LOG_CRITICAL(Service_NVDRV, "Incorrect alignment used, alignment={:08x}", params.align); return NvResult::BadValue; } @@ -114,19 +113,19 @@ NvResult nvmap::IocAlloc(IocAllocParams& params, DeviceFD fd) { auto handle_description{file.GetHandle(params.handle)}; if (!handle_description) { - LOG_CRITICAL(Service_NVDRV, "Object does not exist, handle={:08X}", params.handle); + LOG_CRITICAL(Service_NVDRV, "Object does not exist, handle={}", params.handle); return NvResult::BadValue; } if (handle_description->allocated) { - LOG_CRITICAL(Service_NVDRV, "Object is already allocated, handle={:08X}", params.handle); + LOG_CRITICAL(Service_NVDRV, "Object is already allocated, handle={}", params.handle); return NvResult::InsufficientMemory; } const auto result = handle_description->Alloc(params.flags, params.align, params.kind, params.address, sessions[fd]); if (result != NvResult::Success) { - LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle); + LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={}", params.handle); return result; } bool is_out_io{}; @@ -140,17 +139,17 @@ NvResult nvmap::IocAlloc(IocAllocParams& params, DeviceFD fd) { } NvResult nvmap::IocGetId(IocGetIdParams& params) { - LOG_DEBUG(Service_NVDRV, "called"); + LOG_DEBUG(Service_NVDRV, "called, handle={}", params.handle); // See the comment in FromId for extra info on this function if (!params.handle) { - LOG_CRITICAL(Service_NVDRV, "Error!"); + LOG_CRITICAL(Service_NVDRV, "Handle is 0"); return NvResult::BadValue; } auto handle_description{file.GetHandle(params.handle)}; if (!handle_description) { - LOG_CRITICAL(Service_NVDRV, "Error!"); + LOG_CRITICAL(Service_NVDRV, "No such handle"); return NvResult::AccessDenied; // This will always return EPERM irrespective of if the // handle exists or not } @@ -160,26 +159,26 @@ NvResult nvmap::IocGetId(IocGetIdParams& params) { } NvResult nvmap::IocFromId(IocFromIdParams& params) { - LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id); + LOG_DEBUG(Service_NVDRV, "called, id={}", params.id); // Handles and IDs are always the same value in nvmap however IDs can be used globally given the // right permissions. // Since we don't plan on ever supporting multiprocess we can skip implementing handle refs and // so this function just does simple validation and passes through the handle id. if (!params.id) { - LOG_CRITICAL(Service_NVDRV, "Zero Id is invalid!"); + LOG_CRITICAL(Service_NVDRV, "Id is 0"); return NvResult::BadValue; } auto handle_description{file.GetHandle(params.id)}; if (!handle_description) { - LOG_CRITICAL(Service_NVDRV, "Unregistered handle!"); + LOG_CRITICAL(Service_NVDRV, "No such handle"); return NvResult::BadValue; } auto result = handle_description->Duplicate(false); if (result != NvResult::Success) { - LOG_CRITICAL(Service_NVDRV, "Could not duplicate handle!"); + LOG_CRITICAL(Service_NVDRV, "Could not duplicate handle"); return result; } params.handle = handle_description->id; @@ -189,16 +188,16 @@ NvResult nvmap::IocFromId(IocFromIdParams& params) { NvResult nvmap::IocParam(IocParamParams& params) { enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; - LOG_DEBUG(Service_NVDRV, "called type={}", params.param); + LOG_DEBUG(Service_NVDRV, "called, type={}", params.param); if (!params.handle) { - LOG_CRITICAL(Service_NVDRV, "Invalid handle!"); + LOG_CRITICAL(Service_NVDRV, "Handle is 0"); return NvResult::BadValue; } auto handle_description{file.GetHandle(params.handle)}; if (!handle_description) { - LOG_CRITICAL(Service_NVDRV, "Not registered handle!"); + LOG_CRITICAL(Service_NVDRV, "No such handle"); return NvResult::BadValue; } @@ -232,24 +231,24 @@ NvResult nvmap::IocParam(IocParamParams& params) { } NvResult nvmap::IocFree(IocFreeParams& params, DeviceFD fd) { - LOG_DEBUG(Service_NVDRV, "called"); + LOG_DEBUG(Service_NVDRV, "called, handle={}", params.handle); if (!params.handle) { - LOG_CRITICAL(Service_NVDRV, "Handle null freed?"); + LOG_CRITICAL(Service_NVDRV, "Freeing null handle"); return NvResult::Success; } - if (auto freeInfo{file.FreeHandle(params.handle, false)}) { + if (auto free_info{file.FreeHandle(params.handle, false)}) { auto process = container.GetSession(sessions[fd])->process; - if (freeInfo->can_unlock) { + if (free_info->can_unlock) { ASSERT(process->GetPageTable() - .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) + .UnlockForDeviceAddressSpace(free_info->address, free_info->size) .IsSuccess()); } - params.address = freeInfo->address; - params.size = static_cast(freeInfo->size); + params.address = free_info->address; + params.size = static_cast(free_info->size); params.flags.raw = 0; - params.flags.map_uncached.Assign(freeInfo->was_uncached); + params.flags.map_uncached.Assign(free_info->was_uncached); } else { // This is possible when there's internal dups or other duplicates. } diff --git a/src/core/hle/service/psc/time/alarms.cpp b/src/core/hle/service/psc/time/alarms.cpp index 5e52c19f82..64af6db573 100644 --- a/src/core/hle/service/psc/time/alarms.cpp +++ b/src/core/hle/service/psc/time/alarms.cpp @@ -30,8 +30,8 @@ Alarm::~Alarm() { Alarms::Alarms(Core::System& system, StandardSteadyClockCore& steady_clock, PowerStateRequestManager& power_state_request_manager) : m_system{system}, m_ctx{system, "Psc:Alarms"}, m_steady_clock{steady_clock}, - m_power_state_request_manager{power_state_request_manager}, m_event{m_ctx.CreateEvent( - "Psc:Alarms:Event")} {} + m_power_state_request_manager{power_state_request_manager}, + m_event{m_ctx.CreateEvent("Psc:Alarms:Event")} {} Alarms::~Alarms() { m_ctx.CloseEvent(m_event); diff --git a/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp b/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp index 31ed273966..aa5b4c33c2 100644 --- a/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp +++ b/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp @@ -11,8 +11,8 @@ StandardUserSystemClockCore::StandardUserSystemClockCore( StandardNetworkSystemClockCore& network_clock) : SystemClockCore{local_clock.GetSteadyClock()}, m_system{system}, m_ctx{m_system, "Psc:StandardUserSystemClockCore"}, m_local_system_clock{local_clock}, - m_network_system_clock{network_clock}, m_event{m_ctx.CreateEvent( - "Psc:StandardUserSystemClockCore:Event")} {} + m_network_system_clock{network_clock}, + m_event{m_ctx.CreateEvent("Psc:StandardUserSystemClockCore:Event")} {} StandardUserSystemClockCore::~StandardUserSystemClockCore() { m_ctx.CloseEvent(m_event); diff --git a/src/core/hle/service/psc/time/common.cpp b/src/core/hle/service/psc/time/common.cpp index a6d9f02ca3..1728c84499 100644 --- a/src/core/hle/service/psc/time/common.cpp +++ b/src/core/hle/service/psc/time/common.cpp @@ -6,8 +6,8 @@ namespace Service::PSC::Time { OperationEvent::OperationEvent(Core::System& system) - : m_ctx{system, "Time:OperationEvent"}, m_event{ - m_ctx.CreateEvent("Time:OperationEvent:Event")} {} + : m_ctx{system, "Time:OperationEvent"}, + m_event{m_ctx.CreateEvent("Time:OperationEvent:Event")} {} OperationEvent::~OperationEvent() { m_ctx.CloseEvent(m_event); diff --git a/src/core/hle/service/psc/time/common.h b/src/core/hle/service/psc/time/common.h index a03322d347..954aed666a 100644 --- a/src/core/hle/service/psc/time/common.h +++ b/src/core/hle/service/psc/time/common.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -206,9 +209,9 @@ template <> struct fmt::formatter : fmt::formatter { template auto format(const Service::PSC::Time::CalendarTime& calendar, FormatContext& ctx) const { - return fmt::format_to(ctx.out(), "[{:02}/{:02}/{:04} {:02}:{:02}:{:02}]", calendar.day, - calendar.month, calendar.year, calendar.hour, calendar.minute, - calendar.second); + return fmt::format_to(ctx.out(), "[{:02}/{:02}/{:04} {:02}:{:02}:{:02}]", u8(calendar.day), + u8(calendar.month), u16(calendar.year), u8(calendar.hour), u8(calendar.minute), + u8(calendar.second)); } }; diff --git a/src/core/hle/service/psc/time/manager.h b/src/core/hle/service/psc/time/manager.h index 62ded12475..57c682c690 100644 --- a/src/core/hle/service/psc/time/manager.h +++ b/src/core/hle/service/psc/time/manager.h @@ -29,8 +29,8 @@ public: m_standard_user_system_clock{m_system, m_standard_local_system_clock, m_standard_network_system_clock}, m_ephemeral_network_clock{m_tick_based_steady_clock}, m_shared_memory{m_system}, - m_power_state_request_manager{m_system}, m_alarms{m_system, m_standard_steady_clock, - m_power_state_request_manager}, + m_power_state_request_manager{m_system}, + m_alarms{m_system, m_standard_steady_clock, m_power_state_request_manager}, m_local_system_clock_context_writer{m_system, m_shared_memory}, m_network_system_clock_context_writer{m_system, m_shared_memory, m_standard_user_system_clock}, diff --git a/src/core/hle/service/psc/time/power_state_service.cpp b/src/core/hle/service/psc/time/power_state_service.cpp index ab1d32c703..6fe03dc2e8 100644 --- a/src/core/hle/service/psc/time/power_state_service.cpp +++ b/src/core/hle/service/psc/time/power_state_service.cpp @@ -8,8 +8,8 @@ namespace Service::PSC::Time { IPowerStateRequestHandler::IPowerStateRequestHandler( Core::System& system_, PowerStateRequestManager& power_state_request_manager) - : ServiceFramework{system_, "time:p"}, m_system{system}, m_power_state_request_manager{ - power_state_request_manager} { + : ServiceFramework{system_, "time:p"}, m_system{system}, + m_power_state_request_manager{power_state_request_manager} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle>, "GetPowerStateRequestEventReadableHandle"}, diff --git a/src/core/hle/service/psc/time/static.cpp b/src/core/hle/service/psc/time/static.cpp index 9a0adb2955..591849813e 100644 --- a/src/core/hle/service/psc/time/static.cpp +++ b/src/core/hle/service/psc/time/static.cpp @@ -37,8 +37,8 @@ StaticService::StaticService(Core::System& system_, StaticServiceSetupInfo setup m_user_system_clock{m_time->m_standard_user_system_clock}, m_network_system_clock{m_time->m_standard_network_system_clock}, m_time_zone{m_time->m_time_zone}, - m_ephemeral_network_clock{m_time->m_ephemeral_network_clock}, m_shared_memory{ - m_time->m_shared_memory} { + m_ephemeral_network_clock{m_time->m_ephemeral_network_clock}, + m_shared_memory{m_time->m_shared_memory} { // clang-format off static const FunctionInfo functions[] = { {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"}, diff --git a/src/core/hle/service/psc/time/steady_clock.cpp b/src/core/hle/service/psc/time/steady_clock.cpp index 78dcf532ce..cb10024f2f 100644 --- a/src/core/hle/service/psc/time/steady_clock.cpp +++ b/src/core/hle/service/psc/time/steady_clock.cpp @@ -12,8 +12,8 @@ SteadyClock::SteadyClock(Core::System& system_, std::shared_ptr man bool can_write_steady_clock, bool can_write_uninitialized_clock) : ServiceFramework{system_, "ISteadyClock"}, m_system{system}, m_clock_core{manager->m_standard_steady_clock}, - m_can_write_steady_clock{can_write_steady_clock}, m_can_write_uninitialized_clock{ - can_write_uninitialized_clock} { + m_can_write_steady_clock{can_write_steady_clock}, + m_can_write_uninitialized_clock{can_write_uninitialized_clock} { // clang-format off static const FunctionInfo functions[] = { {0, D<&SteadyClock::GetCurrentTimePoint>, "GetCurrentTimePoint"}, diff --git a/src/core/hle/service/psc/time/system_clock.cpp b/src/core/hle/service/psc/time/system_clock.cpp index 9f841d8e04..ed9f098045 100644 --- a/src/core/hle/service/psc/time/system_clock.cpp +++ b/src/core/hle/service/psc/time/system_clock.cpp @@ -11,8 +11,8 @@ namespace Service::PSC::Time { SystemClock::SystemClock(Core::System& system_, SystemClockCore& clock_core, bool can_write_clock, bool can_write_uninitialized_clock) : ServiceFramework{system_, "ISystemClock"}, m_system{system}, m_clock_core{clock_core}, - m_can_write_clock{can_write_clock}, m_can_write_uninitialized_clock{ - can_write_uninitialized_clock} { + m_can_write_clock{can_write_clock}, + m_can_write_uninitialized_clock{can_write_uninitialized_clock} { // clang-format off static const FunctionInfo functions[] = { {0, D<&SystemClock::GetCurrentTime>, "GetCurrentTime"}, diff --git a/src/core/hle/service/psc/time/time_zone_service.cpp b/src/core/hle/service/psc/time/time_zone_service.cpp index 9e0674f275..92e695a326 100644 --- a/src/core/hle/service/psc/time/time_zone_service.cpp +++ b/src/core/hle/service/psc/time/time_zone_service.cpp @@ -13,8 +13,8 @@ namespace Service::PSC::Time { TimeZoneService::TimeZoneService(Core::System& system_, StandardSteadyClockCore& clock_core, TimeZone& time_zone, bool can_write_timezone_device_location) : ServiceFramework{system_, "ITimeZoneService"}, m_system{system}, m_clock_core{clock_core}, - m_time_zone{time_zone}, m_can_write_timezone_device_location{ - can_write_timezone_device_location} { + m_time_zone{time_zone}, + m_can_write_timezone_device_location{can_write_timezone_device_location} { // clang-format off static const FunctionInfo functions[] = { {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"}, diff --git a/src/core/hle/service/set/settings_server.cpp b/src/core/hle/service/set/settings_server.cpp index aa873bc8c5..5e235b66d8 100644 --- a/src/core/hle/service/set/settings_server.cpp +++ b/src/core/hle/service/set/settings_server.cpp @@ -240,7 +240,8 @@ Result ISettingsServer::GetDeviceNickName( R_SUCCEED(); } -Result ISettingsServer::GetKeyCodeMapByPort(OutLargeData out_key_code_map, u32 port) { +Result ISettingsServer::GetKeyCodeMapByPort( + OutLargeData out_key_code_map, u32 port) { LOG_DEBUG(Service_SET, "called, port={}", port); // Similar to other key code map functions, just pass through to the main implementation diff --git a/src/core/hle/service/set/settings_server.h b/src/core/hle/service/set/settings_server.h index a9cee5f626..5d47dcd70c 100644 --- a/src/core/hle/service/set/settings_server.h +++ b/src/core/hle/service/set/settings_server.h @@ -46,8 +46,9 @@ private: Result GetDeviceNickName( OutLargeData, BufferAttr_HipcMapAlias> out_device_name); - - Result GetKeyCodeMapByPort(OutLargeData out_key_code_map, u32 port); + + Result GetKeyCodeMapByPort(OutLargeData out_key_code_map, + u32 port); }; } // namespace Service::Set diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 1095dcf6c3..1373da17fa 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -251,8 +251,8 @@ void SM::UnregisterService(HLERequestContext& ctx) { } SM::SM(ServiceManager& service_manager_, Core::System& system_) - : ServiceFramework{system_, "sm:", 4}, - service_manager{service_manager_}, kernel{system_.Kernel()} { + : ServiceFramework{system_, "sm:", 4}, service_manager{service_manager_}, + kernel{system_.Kernel()} { RegisterHandlers({ {0, &SM::Initialize, "Initialize"}, {1, &SM::GetServiceCmif, "GetService"}, diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index 9e25eae4d4..b9d3990c43 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp @@ -101,13 +101,13 @@ void Controller::SetPointerBufferSize(HLERequestContext& ctx) { process->SetPointerBufferSize(requested_size); - LOG_INFO(Service, "Pointer buffer size dynamically updated to {:#x} bytes by process", requested_size); + LOG_INFO(Service, "Pointer buffer size dynamically updated to {:#x} bytes by process", + requested_size); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } - // https://switchbrew.org/wiki/IPC_Marshalling Controller::Controller(Core::System& system_) : ServiceFramework{system_, "IpcController"} { static const FunctionInfo functions[] = { diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index a5e1378197..5fe7d97653 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -11,6 +11,7 @@ #include +#include #include "common/microprofile.h" #include "common/socket_types.h" #include "core/core.h" @@ -22,7 +23,6 @@ #include "core/internal_network/socket_proxy.h" #include "core/internal_network/sockets.h" #include "network/network.h" -#include using Common::Expected; using Common::Unexpected; @@ -979,8 +979,7 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) { } } -BSD::BSD(Core::System& system_, const char* name) - : ServiceFramework{system_, name} { +BSD::BSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { // clang-format off static const FunctionInfo functions[] = { {0, &BSD::RegisterClient, "RegisterClient"}, diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 67e37e0823..dbe88ccf5a 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -562,9 +562,9 @@ private: }; class ISslServiceForSystem final : public ServiceFramework { - public: - explicit ISslServiceForSystem(Core::System& system_) : ServiceFramework{system_, "ssl:s"} { - // clang-format off +public: + explicit ISslServiceForSystem(Core::System& system_) : ServiceFramework{system_, "ssl:s"} { + // clang-format off static const FunctionInfo functions[] = { {0, D<&ISslServiceForSystem::CreateContext>, "CreateContext"}, {1, D<&ISslServiceForSystem::GetContextCount>, "GetContextCount"}, @@ -581,124 +581,124 @@ class ISslServiceForSystem final : public ServiceFramework {102, D<&ISslServiceForSystem::GetThreadCoreMask>, "GetThreadCoreMask"}, {103, D<&ISslServiceForSystem::VerifySignature>, "VerifySignature"} }; - // clang-format on - - RegisterHandlers(functions); - }; - - Result CreateContext() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result GetContextCount() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result GetCertificates() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result GetCertificateBufSize() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result DebugIoctl() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result SetInterfaceVersion() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result FlushSessionCache() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result SetDebugOption() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result GetDebugOption() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result ClearTls12FallbackFlag() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result CreateContextForSystem() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result SetThreadCoreMask() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result GetThreadCoreMask() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; - - Result VerifySignature() { - LOG_DEBUG(Service_SSL, "(STUBBED) called."); - - // TODO (jarrodnorwell) - - return ResultSuccess; - }; + // clang-format on + + RegisterHandlers(functions); }; + Result CreateContext() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result GetContextCount() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result GetCertificates() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result GetCertificateBufSize() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result DebugIoctl() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result SetInterfaceVersion() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result FlushSessionCache() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result SetDebugOption() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result GetDebugOption() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result ClearTls12FallbackFlag() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result CreateContextForSystem() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result SetThreadCoreMask() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result GetThreadCoreMask() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; + + Result VerifySignature() { + LOG_DEBUG(Service_SSL, "(STUBBED) called."); + + // TODO (jarrodnorwell) + + return ResultSuccess; + }; +}; + void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); diff --git a/src/core/hle/service/ssl/ssl_types.h b/src/core/hle/service/ssl/ssl_types.h index 16623c0fc5..1d327a653c 100644 --- a/src/core/hle/service/ssl/ssl_types.h +++ b/src/core/hle/service/ssl/ssl_types.h @@ -40,39 +40,42 @@ enum class CaCertificateId : s32 { GoDaddyRootCertificateAuthorityG2 = 1025, StarfieldClass2CertificationAuthority = 1026, StarfieldRootCertificateAuthorityG2 = 1027, - thawtePrimaryRootCAG3 = 1028, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted - thawtePrimaryRootCA = 1029, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted - VeriSignClass3PublicPrimaryCertificationAuthorityG3 = 1030, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted - VeriSignClass3PublicPrimaryCertificationAuthorityG5 = 1031, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted - VeriSignUniversalRootCertificationAuthority = 1032, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted - DSTRootCAX3 = 1033, // [6.0.0+] - USERTrustRsaCertificationAuthority = 1034, // [10.0.3+] - ISRGRootX10 = 1035, // [10.1.0+] - USERTrustEccCertificationAuthority = 1036, // [10.1.0+] - COMODORsaCertificationAuthority = 1037, // [10.1.0+] - COMODOEccCertificationAuthority = 1038, // [10.1.0+] - AmazonRootCA2 = 1039, // [11.0.0+] - AmazonRootCA3 = 1040, // [11.0.0+] - AmazonRootCA4 = 1041, // [11.0.0+] - DigiCertAssuredIDRootG3 = 1042, // [11.0.0+] - DigiCertGlobalRootG3 = 1043, // [11.0.0+] - DigiCertTrustedRootG4 = 1044, // [11.0.0+] - EntrustRootCertificationAuthorityEC1 = 1045, // [11.0.0+] - EntrustRootCertificationAuthorityG4 = 1046, // [11.0.0+] - GlobalSignECCRootCAR4 = 1047, // [11.0.0+] - GlobalSignECCRootCAR5 = 1048, // [11.0.0+] - GlobalSignECCRootCAR6 = 1049, // [11.0.0+] - GTSRootR1 = 1050, // [11.0.0+] - GTSRootR2 = 1051, // [11.0.0+] - GTSRootR3 = 1052, // [11.0.0+] - GTSRootR4 = 1053, // [11.0.0+] - SecurityCommunicationRootCA = 1054, // [12.0.0+] - GlobalSignRootE4 = 1055, // [15.0.0+] - GlobalSignRootR4 = 1056, // [15.0.0+] - TTeleSecGlobalRootClass2 = 1057, // [15.0.0+] - DigiCertTLSECCP384RootG5 = 1058, // [16.0.0+] - DigiCertTLSRSA4096RootG5 = 1059, // [16.0.0+] - NintendoTempRootCAG4 = 65536, // [16.0.0+] ([19.0.0+] Removed) + thawtePrimaryRootCAG3 = 1028, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted + thawtePrimaryRootCA = 1029, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted + VeriSignClass3PublicPrimaryCertificationAuthorityG3 = + 1030, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted + VeriSignClass3PublicPrimaryCertificationAuthorityG5 = + 1031, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted + VeriSignUniversalRootCertificationAuthority = + 1032, // [8.0.0+] TrustedCertStatus is EnabledNotTrusted + DSTRootCAX3 = 1033, // [6.0.0+] + USERTrustRsaCertificationAuthority = 1034, // [10.0.3+] + ISRGRootX10 = 1035, // [10.1.0+] + USERTrustEccCertificationAuthority = 1036, // [10.1.0+] + COMODORsaCertificationAuthority = 1037, // [10.1.0+] + COMODOEccCertificationAuthority = 1038, // [10.1.0+] + AmazonRootCA2 = 1039, // [11.0.0+] + AmazonRootCA3 = 1040, // [11.0.0+] + AmazonRootCA4 = 1041, // [11.0.0+] + DigiCertAssuredIDRootG3 = 1042, // [11.0.0+] + DigiCertGlobalRootG3 = 1043, // [11.0.0+] + DigiCertTrustedRootG4 = 1044, // [11.0.0+] + EntrustRootCertificationAuthorityEC1 = 1045, // [11.0.0+] + EntrustRootCertificationAuthorityG4 = 1046, // [11.0.0+] + GlobalSignECCRootCAR4 = 1047, // [11.0.0+] + GlobalSignECCRootCAR5 = 1048, // [11.0.0+] + GlobalSignECCRootCAR6 = 1049, // [11.0.0+] + GTSRootR1 = 1050, // [11.0.0+] + GTSRootR2 = 1051, // [11.0.0+] + GTSRootR3 = 1052, // [11.0.0+] + GTSRootR4 = 1053, // [11.0.0+] + SecurityCommunicationRootCA = 1054, // [12.0.0+] + GlobalSignRootE4 = 1055, // [15.0.0+] + GlobalSignRootR4 = 1056, // [15.0.0+] + TTeleSecGlobalRootClass2 = 1057, // [15.0.0+] + DigiCertTLSECCP384RootG5 = 1058, // [16.0.0+] + DigiCertTLSRSA4096RootG5 = 1059, // [16.0.0+] + NintendoTempRootCAG4 = 65536, // [16.0.0+] ([19.0.0+] Removed) }; enum class TrustedCertStatus : s32 { diff --git a/src/core/hle/service/vi/application_display_service.cpp b/src/core/hle/service/vi/application_display_service.cpp index 289ad7073c..68f3a6de6e 100644 --- a/src/core/hle/service/vi/application_display_service.cpp +++ b/src/core/hle/service/vi/application_display_service.cpp @@ -15,8 +15,8 @@ namespace Service::VI { IApplicationDisplayService::IApplicationDisplayService(Core::System& system_, std::shared_ptr container) - : ServiceFramework{system_, "IApplicationDisplayService"}, - m_container{std::move(container)}, m_context{system, "IApplicationDisplayService"} { + : ServiceFramework{system_, "IApplicationDisplayService"}, m_container{std::move(container)}, + m_context{system, "IApplicationDisplayService"} { // clang-format off static const FunctionInfo functions[] = { {100, C<&IApplicationDisplayService::GetRelayService>, "GetRelayService"}, @@ -91,9 +91,8 @@ Result IApplicationDisplayService::OpenDisplay(Out out_display_id, DisplayN display_name[display_name.size() - 1] = '\0'; // According to switchbrew, only "Default", "External", "Edid", "Internal" and "Null" are valid - const std::array valid_names = { - "Default", "External", "Edid", "Internal", "Null" - }; + const std::array valid_names = {"Default", "External", "Edid", "Internal", + "Null"}; bool valid_name = false; for (const auto& name : valid_names) { diff --git a/src/core/hle/service/vi/conductor.cpp b/src/core/hle/service/vi/conductor.cpp index c8ce4fca04..d6c001e187 100644 --- a/src/core/hle/service/vi/conductor.cpp +++ b/src/core/hle/service/vi/conductor.cpp @@ -15,9 +15,8 @@ namespace Service::VI { Conductor::Conductor(Core::System& system, Container& container, DisplayList& displays) : m_system(system), m_container(container) { - displays.ForEachDisplay([&](Display& display) { - m_vsync_managers.insert({display.GetId(), VsyncManager{}}); - }); + displays.ForEachDisplay( + [&](Display& display) { m_vsync_managers.insert({display.GetId(), VsyncManager{}}); }); if (system.IsMulticore()) { m_event = Core::Timing::CreateEvent( diff --git a/src/core/internal_network/emu_net_state.h b/src/core/internal_network/emu_net_state.h index d16f1830a6..5cfc523d24 100644 --- a/src/core/internal_network/emu_net_state.h +++ b/src/core/internal_network/emu_net_state.h @@ -3,8 +3,8 @@ #pragma once #include -#include #include +#include namespace Network { diff --git a/src/core/internal_network/network_interface.cpp b/src/core/internal_network/network_interface.cpp index 42def7af92..ec02d23225 100644 --- a/src/core/internal_network/network_interface.cpp +++ b/src/core/internal_network/network_interface.cpp @@ -27,7 +27,7 @@ namespace Network { #ifdef _WIN32 -std::vector GetAvailableNetworkInterfaces() { +std::vector GetAvailableNetworkInterfaces() { ULONG buf_size = 0; if (GetAdaptersAddresses( @@ -47,7 +47,7 @@ std::vector GetAvailableNetworkInterfaces() { return {}; } - std::vector result; + std::vector result; for (auto* a = addrs; a; a = a->Next) { @@ -80,13 +80,12 @@ std::vector GetAvailableNetworkInterfaces() { break; } - result.emplace_back(NetworkInterface{ - .name = Common::UTF16ToUTF8(std::wstring{a->FriendlyName}), - .ip_address = ip, - .subnet_mask = mask, - .gateway = gw, - .kind = kind - }); + result.emplace_back( + NetworkInterface{.name = Common::UTF16ToUTF8(std::wstring{a->FriendlyName}), + .ip_address = ip, + .subnet_mask = mask, + .gateway = gw, + .kind = kind}); } return result; @@ -94,7 +93,7 @@ std::vector GetAvailableNetworkInterfaces() { #else -std::vector GetAvailableNetworkInterfaces() { +std::vector GetAvailableNetworkInterfaces() { struct ifaddrs* ifaddr = nullptr; if (getifaddrs(&ifaddr) != 0) { @@ -103,7 +102,7 @@ std::vector GetAvailableNetworkInterfaces() { return {}; } - std::vector result; + std::vector result; for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr) { @@ -122,11 +121,10 @@ std::vector GetAvailableNetworkInterfaces() { // On Android, we can't reliably get gateway info from /proc/net/route // Just use 0 as the gateway address result.emplace_back(NetworkInterface{ - .name{ifa->ifa_name}, - .ip_address{Common::BitCast(*ifa->ifa_addr).sin_addr}, - .subnet_mask{Common::BitCast(*ifa->ifa_netmask).sin_addr}, - .gateway{in_addr{.s_addr = 0}} - }); + .name{ifa->ifa_name}, + .ip_address{Common::BitCast(*ifa->ifa_addr).sin_addr}, + .subnet_mask{Common::BitCast(*ifa->ifa_netmask).sin_addr}, + .gateway{in_addr{.s_addr = 0}}}); #else u32 gateway{}; @@ -134,11 +132,14 @@ std::vector GetAvailableNetworkInterfaces() { if (!file.is_open()) { LOG_ERROR(Network, "Failed to open \"/proc/net/route\""); - result.emplace_back(NetworkInterface{ - .name{ifa->ifa_name}, - .ip_address{Common::BitCast(*ifa->ifa_addr).sin_addr}, - .subnet_mask{Common::BitCast(*ifa->ifa_netmask).sin_addr}, - .gateway{in_addr{.s_addr = gateway}}}); + // Solaris defines s_addr as a macro, can't use special C++ shenanigans here + in_addr gateway_0; + gateway_0.s_addr = gateway; + result.emplace_back(Network::NetworkInterface{ + .name = ifa->ifa_name, + .ip_address = Common::BitCast(*ifa->ifa_addr).sin_addr, + .subnet_mask = Common::BitCast(*ifa->ifa_netmask).sin_addr, + .gateway = gateway_0}); continue; } @@ -183,11 +184,13 @@ std::vector GetAvailableNetworkInterfaces() { gateway = 0; } - result.emplace_back(NetworkInterface{ - .name{ifa->ifa_name}, - .ip_address{Common::BitCast(*ifa->ifa_addr).sin_addr}, - .subnet_mask{Common::BitCast(*ifa->ifa_netmask).sin_addr}, - .gateway{in_addr{.s_addr = gateway}}}); + in_addr gateway_0; + gateway_0.s_addr = gateway; + result.emplace_back(Network::NetworkInterface{ + .name = ifa->ifa_name, + .ip_address = Common::BitCast(*ifa->ifa_addr).sin_addr, + .subnet_mask = Common::BitCast(*ifa->ifa_netmask).sin_addr, + .gateway = gateway_0}); #endif // ANDROID } @@ -197,7 +200,7 @@ std::vector GetAvailableNetworkInterfaces() { #endif // _WIN32 -std::optional GetSelectedNetworkInterface() { +std::optional GetSelectedNetworkInterface() { const auto& selected_network_interface = Settings::values.network_interface.GetValue(); const auto network_interfaces = Network::GetAvailableNetworkInterfaces(); @@ -206,11 +209,11 @@ std::optional GetSelectedNetworkInterface() { return std::nullopt; } - #ifdef __ANDROID__ - if (selected_network_interface.empty()) { - return network_interfaces[0]; - } - #endif +#ifdef __ANDROID__ + if (selected_network_interface.empty()) { + return network_interfaces[0]; + } +#endif const auto res = std::ranges::find_if(network_interfaces, [&selected_network_interface](const auto& iface) { diff --git a/src/core/internal_network/wifi_scanner.cpp b/src/core/internal_network/wifi_scanner.cpp index df9bc92910..152791ac5a 100644 --- a/src/core/internal_network/wifi_scanner.cpp +++ b/src/core/internal_network/wifi_scanner.cpp @@ -20,6 +20,7 @@ using namespace std::chrono_literals; namespace Network { +#ifdef ENABLE_WIFI_SCAN #ifdef _WIN32 static u8 QualityToPercent(DWORD q) { return static_cast(q); @@ -95,8 +96,7 @@ static u8 QualityToPercent(const iwrange& r, const wireless_scan* ws) { return static_cast(std::clamp(100 * lvl / max, 0, 100)); } -static int wifi_callback(int skfd, char* ifname, char* args[], int count) -{ +static int wifi_callback(int skfd, char* ifname, char* args[], int count) { iwrange range; int res = iw_get_range_info(skfd, ifname, &range); @@ -123,7 +123,7 @@ static std::vector ScanWifiLinux(std::chrono::milliseconds de } char ifname[IFNAMSIZ] = {0}; - char *args[1] = {ifname}; + char* args[1] = {ifname}; iw_enum_devices(sock, &wifi_callback, args, 0); @@ -173,16 +173,20 @@ static std::vector ScanWifiLinux(std::chrono::milliseconds de return out; } #endif /* linux */ +#endif std::vector ScanWifiNetworks(std::chrono::milliseconds deadline) { +#ifdef ENABLE_WIFI_SCAN #ifdef _WIN32 return ScanWifiWin(deadline); #elif defined(__linux__) && !defined(ANDROID) return ScanWifiLinux(deadline); #else - std::this_thread::sleep_for(deadline); return {}; // unsupported host, pretend no results #endif +#else + return {}; +#endif } } // namespace Network diff --git a/src/core/internal_network/wifi_scanner.h b/src/core/internal_network/wifi_scanner.h index adf2fe2de3..5df42c5854 100644 --- a/src/core/internal_network/wifi_scanner.h +++ b/src/core/internal_network/wifi_scanner.h @@ -19,4 +19,4 @@ struct ScanData { static_assert(sizeof(ScanData) <= 0x2C, "ScanData layout changed – update conversions!"); std::vector ScanWifiNetworks(std::chrono::milliseconds deadline); -} +} // namespace Network diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 4a87ab53e7..478000baf9 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -4,6 +4,7 @@ #include #include "common/hex_util.h" +#include "common/literals.h" #include "common/scope_exit.h" #include "core/core.h" #include "core/file_sys/content_archive.h" @@ -15,7 +16,6 @@ #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nca.h" #include "mbedtls/sha256.h" -#include "common/literals.h" namespace Loader { @@ -105,7 +105,8 @@ AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::KProcess& process, Core::S return load_result; } - LOG_INFO(Loader, "Set pointer buffer size to {:#x} bytes for ProgramID {:#018x} (Heap size: {:#x})", + LOG_INFO(Loader, + "Set pointer buffer size to {:#x} bytes for ProgramID {:#018x} (Heap size: {:#x})", process.GetPointerBufferSize(), nca->GetTitleId(), heap_size); // Register the process in the file system controller diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 34539cc650..83bacc5aef 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -37,105 +37,6 @@ namespace Core::Memory { namespace { -inline void FastMemcpy(void* dst, const void* src, std::size_t size) { - // Fast path for small copies - switch (size) { - case 1: - *static_cast(dst) = *static_cast(src); - break; - case 2: - *static_cast(dst) = *static_cast(src); - break; - case 4: - *static_cast(dst) = *static_cast(src); - break; - case 8: - *static_cast(dst) = *static_cast(src); - break; - case 16: { - // Optimize for 16-byte copy (common case for SIMD registers) - const u64* src_64 = static_cast(src); - u64* dst_64 = static_cast(dst); - dst_64[0] = src_64[0]; - dst_64[1] = src_64[1]; - break; - } - case 32: { - // Optimize for 32-byte copy - const u64* src_64 = static_cast(src); - u64* dst_64 = static_cast(dst); - dst_64[0] = src_64[0]; - dst_64[1] = src_64[1]; - dst_64[2] = src_64[2]; - dst_64[3] = src_64[3]; - break; - } - case 64: { - // Optimize for 64-byte copy - const u64* src_64 = static_cast(src); - u64* dst_64 = static_cast(dst); - dst_64[0] = src_64[0]; - dst_64[1] = src_64[1]; - dst_64[2] = src_64[2]; - dst_64[3] = src_64[3]; - dst_64[4] = src_64[4]; - dst_64[5] = src_64[5]; - dst_64[6] = src_64[6]; - dst_64[7] = src_64[7]; - break; - } - default: - // For larger sizes, use standard memcpy which is usually optimized by the compiler - std::memcpy(dst, src, size); - break; - } -} - -inline void FastMemset(void* dst, int value, std::size_t size) { - // Fast path for small fills - switch (size) { - case 1: - *static_cast(dst) = static_cast(value); - break; - case 2: - *static_cast(dst) = static_cast(value); - break; - case 4: - *static_cast(dst) = static_cast(value); - break; - case 8: - *static_cast(dst) = static_cast(value); - break; - case 16: { - // Optimize for 16-byte fill (common case for SIMD registers) - u64* dst_64 = static_cast(dst); - const u64 val64 = static_cast(value) * 0x0101010101010101ULL; - dst_64[0] = val64; - dst_64[1] = val64; - break; - } - default: - if (size <= 128 && value == 0) { - // Fast path for small zero-fills - u8* dst_bytes = static_cast(dst); - for (std::size_t i = 0; i < size; i += 8) { - if (i + 8 <= size) { - *reinterpret_cast(dst_bytes + i) = 0; - } else { - // Handle remaining bytes (less than 8) - for (std::size_t j = i; j < size; j++) { - dst_bytes[j] = 0; - } - } - } - } else { - // For larger sizes, use standard memset which is usually optimized by the compiler - std::memset(dst, value, size); - } - break; - } -} - bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessAddress addr, const std::size_t size) { const Common::ProcessAddress max_addr = 1ULL << table.GetAddressSpaceBits(); @@ -416,17 +317,17 @@ struct Memory::Impl { LOG_ERROR(HW_Memory, "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", GetInteger(current_vaddr), GetInteger(src_addr), size); - FastMemset(dest_buffer, 0, copy_amount); + std::memset(dest_buffer, 0, copy_amount); }, [&](const std::size_t copy_amount, const u8* const src_ptr) { - FastMemcpy(dest_buffer, src_ptr, copy_amount); + std::memcpy(dest_buffer, src_ptr, copy_amount); }, [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, const u8* const host_ptr) { if constexpr (!UNSAFE) { HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); } - FastMemcpy(dest_buffer, host_ptr, copy_amount); + std::memcpy(dest_buffer, host_ptr, copy_amount); }, [&](const std::size_t copy_amount) { dest_buffer = static_cast(dest_buffer) + copy_amount; @@ -434,7 +335,7 @@ struct Memory::Impl { } bool ReadBlockParallel(const Common::ProcessAddress src_addr, void* dest_buffer, - const std::size_t size) { + const std::size_t size) { // Calculate chunk size based on thread count const size_t chunk_size = (size + thread_count - 1) / thread_count; @@ -457,7 +358,8 @@ struct Memory::Impl { void* current_dest = static_cast(dest_buffer) + offset; // Launch thread - threads.emplace_back([this, i, current_addr, current_dest, current_chunk_size, &results] { + threads.emplace_back([this, i, current_addr, current_dest, current_chunk_size, + &results] { results[i] = ReadBlockImpl(current_addr, current_dest, current_chunk_size); }); } @@ -515,14 +417,14 @@ struct Memory::Impl { GetInteger(current_vaddr), GetInteger(dest_addr), size); }, [&](const std::size_t copy_amount, u8* const dest_ptr) { - FastMemcpy(dest_ptr, src_buffer, copy_amount); + std::memcpy(dest_ptr, src_buffer, copy_amount); }, [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, u8* const host_ptr) { if constexpr (!UNSAFE) { HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount); } - FastMemcpy(host_ptr, src_buffer, copy_amount); + std::memcpy(host_ptr, src_buffer, copy_amount); }, [&](const std::size_t copy_amount) { src_buffer = static_cast(src_buffer) + copy_amount; @@ -530,7 +432,7 @@ struct Memory::Impl { } bool WriteBlockParallel(const Common::ProcessAddress dest_addr, const void* src_buffer, - const std::size_t size) { + const std::size_t size) { // Calculate chunk size based on thread count const size_t chunk_size = (size + thread_count - 1) / thread_count; @@ -553,7 +455,8 @@ struct Memory::Impl { const void* current_src = static_cast(src_buffer) + offset; // Launch thread - threads.emplace_back([this, i, current_addr, current_src, current_chunk_size, &results] { + threads.emplace_back([this, i, current_addr, current_src, current_chunk_size, + &results] { results[i] = WriteBlockImpl(current_addr, current_src, current_chunk_size); }); } @@ -593,12 +496,12 @@ struct Memory::Impl { GetInteger(current_vaddr), GetInteger(dest_addr), size); }, [](const std::size_t copy_amount, u8* const dest_ptr) { - FastMemset(dest_ptr, 0, copy_amount); + std::memset(dest_ptr, 0, copy_amount); }, [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, u8* const host_ptr) { HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount); - FastMemset(host_ptr, 0, copy_amount); + std::memset(host_ptr, 0, copy_amount); }, [](const std::size_t copy_amount) {}); } @@ -876,8 +779,10 @@ struct Memory::Impl { return nullptr; } else { // Avoid adding any extra logic to this fast-path block - const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw(); - if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { + const uintptr_t raw_pointer = + current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw(); + if (const uintptr_t pointer = + Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { return reinterpret_cast(pointer + vaddr); } else { switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) { @@ -912,8 +817,7 @@ struct Memory::Impl { } [[nodiscard]] u8* GetPointerSilent(const Common::ProcessAddress vaddr) const { - return GetPointerImpl( - GetInteger(vaddr), []() {}, []() {}); + return GetPointerImpl(GetInteger(vaddr), []() {}, []() {}); } /** @@ -934,10 +838,7 @@ struct Memory::Impl { if constexpr (std::is_same_v || std::is_same_v) { // 8-bit reads are always aligned const u8* const ptr = GetPointerImpl( - addr, - [addr]() { - LOG_ERROR(HW_Memory, "Unmapped Read8 @ 0x{:016X}", addr); - }, + addr, [addr]() { LOG_ERROR(HW_Memory, "Unmapped Read8 @ 0x{:016X}", addr); }, [&]() { HandleRasterizerDownload(addr, sizeof(T)); }); if (ptr) { return static_cast(*ptr); @@ -947,10 +848,7 @@ struct Memory::Impl { // Check alignment for 16-bit reads if ((addr & 1) == 0) { const u8* const ptr = GetPointerImpl( - addr, - [addr]() { - LOG_ERROR(HW_Memory, "Unmapped Read16 @ 0x{:016X}", addr); - }, + addr, [addr]() { LOG_ERROR(HW_Memory, "Unmapped Read16 @ 0x{:016X}", addr); }, [&]() { HandleRasterizerDownload(addr, sizeof(T)); }); if (ptr) { return static_cast(*reinterpret_cast(ptr)); @@ -960,10 +858,7 @@ struct Memory::Impl { // Check alignment for 32-bit reads if ((addr & 3) == 0) { const u8* const ptr = GetPointerImpl( - addr, - [addr]() { - LOG_ERROR(HW_Memory, "Unmapped Read32 @ 0x{:016X}", addr); - }, + addr, [addr]() { LOG_ERROR(HW_Memory, "Unmapped Read32 @ 0x{:016X}", addr); }, [&]() { HandleRasterizerDownload(addr, sizeof(T)); }); if (ptr) { return static_cast(*reinterpret_cast(ptr)); @@ -973,10 +868,7 @@ struct Memory::Impl { // Check alignment for 64-bit reads if ((addr & 7) == 0) { const u8* const ptr = GetPointerImpl( - addr, - [addr]() { - LOG_ERROR(HW_Memory, "Unmapped Read64 @ 0x{:016X}", addr); - }, + addr, [addr]() { LOG_ERROR(HW_Memory, "Unmapped Read64 @ 0x{:016X}", addr); }, [&]() { HandleRasterizerDownload(addr, sizeof(T)); }); if (ptr) { return static_cast(*reinterpret_cast(ptr)); @@ -988,12 +880,10 @@ struct Memory::Impl { T result = 0; const u8* const ptr = GetPointerImpl( addr, - [addr]() { - LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, addr); - }, + [addr]() { LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, addr); }, [&]() { HandleRasterizerDownload(addr, sizeof(T)); }); if (ptr) { - FastMemcpy(&result, ptr, sizeof(T)); + std::memcpy(&result, ptr, sizeof(T)); } return result; } @@ -1080,7 +970,7 @@ struct Memory::Impl { }, [&]() { HandleRasterizerWrite(addr, sizeof(T)); }); if (ptr) { - FastMemcpy(ptr, &data, sizeof(T)); + std::memcpy(ptr, &data, sizeof(T)); } } @@ -1114,8 +1004,7 @@ struct Memory::Impl { } void HandleRasterizerDownload(VAddr v_address, size_t size) { - const auto* p = GetPointerImpl( - v_address, []() {}, []() {}); + const auto* p = GetPointerImpl(v_address, []() {}, []() {}); if (!gpu_device_memory) [[unlikely]] { gpu_device_memory = &system.Host1x().MemoryManager(); } @@ -1132,8 +1021,7 @@ struct Memory::Impl { } void HandleRasterizerWrite(VAddr v_address, size_t size) { - const auto* p = GetPointerImpl( - v_address, []() {}, []() {}); + const auto* p = GetPointerImpl(v_address, []() {}, []() {}); constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1; const size_t core = std::min(system.GetCurrentHostThreadID(), sys_core); // any other calls threads go to syscore. @@ -1153,13 +1041,13 @@ struct Memory::Impl { auto& current_area = rasterizer_write_areas[core]; PAddr subaddress = address >> YUZU_PAGEBITS; // Performance note: - // It may not be a good idea to assume accesses are within the same subaddress (i.e same page) - // It is often the case the games like to access wildly different addresses. Hence why I propose - // we should let the compiler just do it's thing... + // It may not be a good idea to assume accesses are within the same subaddress (i.e same + // page) It is often the case the games like to access wildly different addresses. Hence + // why I propose we should let the compiler just do it's thing... if (current_area.last_address != subaddress) { // Short circuit the need to check for address/size - auto const do_collection = (address != 0 && size != 0) - && system.GPU().OnCPUWrite(address, size); + auto const do_collection = + (address != 0 && size != 0) && system.GPU().OnCPUWrite(address, size); if (do_collection) { current_area.last_address = subaddress; } else { @@ -1418,21 +1306,7 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { impl->InvalidateGPUMemory(ptr, size); } -#ifdef __linux__ - if (!rasterizer && mapped) { - impl->buffer->DeferredMapSeparateHeap(GetInteger(vaddr)); - } -#endif - return mapped && ptr != nullptr; } -bool Memory::InvalidateSeparateHeap(void* fault_address) { -#ifdef __linux__ - return impl->buffer->DeferredMapSeparateHeap(static_cast(fault_address)); -#else - return false; -#endif -} - } // namespace Core::Memory diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index d8921e5658..ae651631d6 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -218,8 +218,8 @@ std::vector TextCheatParser::Parse(std::string_view data) const { CheatEngine::CheatEngine(System& system_, std::vector cheats_, const std::array& build_id_) - : vm{std::make_unique(system_, metadata)}, - cheats(std::move(cheats_)), core_timing{system_.CoreTiming()}, system{system_} { + : vm{std::make_unique(system_, metadata)}, cheats(std::move(cheats_)), + core_timing{system_.CoreTiming()}, system{system_} { metadata.main_nso_build_id = build_id_; } diff --git a/src/dedicated_room/yuzu_room.cpp b/src/dedicated_room/yuzu_room.cpp index 156bff62dc..2556201b93 100644 --- a/src/dedicated_room/yuzu_room.cpp +++ b/src/dedicated_room/yuzu_room.cpp @@ -190,8 +190,7 @@ static void InitializeLogging(const std::string& log_file) { } /// Application entry point -void LaunchRoom(int argc, char** argv, bool called_by_option) -{ +void LaunchRoom(int argc, char** argv, bool called_by_option) { Common::DetachedTasks detached_tasks; int option_index = 0; char* endarg; @@ -240,7 +239,8 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) InitializeLogging(log_file); while (optind < argc) { - int arg = getopt_long(argc, argv, "n:d:s:p:m:w:g:u:t:a:i:l:hv", long_options, &option_index); + int arg = + getopt_long(argc, argv, "n:d:s:p:m:w:g:u:t:a:i:l:hv", long_options, &option_index); if (arg != -1) { char carg = static_cast(arg); @@ -312,8 +312,7 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) "room.\nSet with --preferred-game-id id"); } if (max_members > Network::MaxConcurrentConnections || max_members < 2) { - LOG_ERROR(Network, - "max_members needs to be in the range 2 - {}!", + LOG_ERROR(Network, "max_members needs to be in the range 2 - {}!", Network::MaxConcurrentConnections); PrintHelp(argv[0]); std::exit(-1); @@ -327,9 +326,8 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) std::exit(-1); } if (ban_list_file.empty()) { - LOG_ERROR(Network, - "Ban list file not set!\nThis should get set to load and save room ban " - "list.\nSet with --ban-list-file "); + LOG_ERROR(Network, "Ban list file not set!\nThis should get set to load and save room ban " + "list.\nSet with --ban-list-file "); } bool announce = true; if (token.empty() && announce) { diff --git a/src/frontend_common/firmware_manager.cpp b/src/frontend_common/firmware_manager.cpp index a180693996..97e94cf0cd 100644 --- a/src/frontend_common/firmware_manager.cpp +++ b/src/frontend_common/firmware_manager.cpp @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later -#include "firmware_manager.h" #include #include +#include "firmware_manager.h" #include "common/fs/fs.h" #include "common/fs/path_util.h" @@ -14,30 +14,26 @@ #include "frontend_common/content_manager.h" #ifdef ANDROID -#include -#include #include +#include +#include #endif -FirmwareManager::KeyInstallResult -FirmwareManager::InstallKeys(std::string location, std::string extension) { +FirmwareManager::KeyInstallResult FirmwareManager::InstallKeys(std::string location, + std::string extension) { LOG_INFO(Frontend, "Installing key files from {}", location); const auto keys_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::KeysDir); #ifdef ANDROID - JNIEnv *env = Common::Android::GetEnvForThread(); + JNIEnv* env = Common::Android::GetEnvForThread(); jstring jsrc = Common::Android::ToJString(env, location); jclass native = Common::Android::GetNativeLibraryClass(); jmethodID getExtension = Common::Android::GetFileExtension(); - jstring jext = static_cast(env->CallStaticObjectMethod( - native, - getExtension, - jsrc - )); + jstring jext = static_cast(env->CallStaticObjectMethod(native, getExtension, jsrc)); std::string ext = Common::Android::GetJString(env, jext); @@ -48,12 +44,7 @@ FirmwareManager::InstallKeys(std::string location, std::string extension) { jmethodID copyToStorage = Common::Android::GetCopyToStorage(); jstring jdest = Common::Android::ToJString(env, keys_dir.string() + "/"); - jboolean copyResult = env->CallStaticBooleanMethod( - native, - copyToStorage, - jsrc, - jdest - ); + jboolean copyResult = env->CallStaticBooleanMethod(native, copyToStorage, jsrc, jdest); if (!copyResult) { return ErrorFailedCopy; @@ -91,14 +82,11 @@ FirmwareManager::InstallKeys(std::string location, std::string extension) { return ErrorWrongFilename; } - for (const auto &key_file : source_key_files) { + for (const auto& key_file : source_key_files) { std::filesystem::path destination_key_file = keys_dir / key_file.filename(); - if (!std::filesystem::copy_file(key_file, - destination_key_file, + if (!std::filesystem::copy_file(key_file, destination_key_file, std::filesystem::copy_options::overwrite_existing)) { - LOG_ERROR(Frontend, - "Failed to copy file {} to {}", - key_file.string(), + LOG_ERROR(Frontend, "Failed to copy file {} to {}", key_file.string(), destination_key_file.string()); return ErrorFailedCopy; } @@ -116,7 +104,7 @@ FirmwareManager::InstallKeys(std::string location, std::string extension) { return ErrorFailedInit; } -FirmwareManager::FirmwareCheckResult FirmwareManager::VerifyFirmware(Core::System &system) { +FirmwareManager::FirmwareCheckResult FirmwareManager::VerifyFirmware(Core::System& system) { if (!CheckFirmwarePresence(system)) { return ErrorFirmwareMissing; } else { diff --git a/src/frontend_common/firmware_manager.h b/src/frontend_common/firmware_manager.h index 20f3b41478..c0e1a49220 100644 --- a/src/frontend_common/firmware_manager.h +++ b/src/frontend_common/firmware_manager.h @@ -4,23 +4,23 @@ #ifndef FIRMWARE_MANAGER_H #define FIRMWARE_MANAGER_H +#include +#include +#include +#include #include "common/common_types.h" #include "core/core.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/registered_cache.h" #include "core/hle/service/filesystem/filesystem.h" -#include -#include -#include -#include +#include "core/hle/result.h" #include "core/hle/service/set/settings_types.h" #include "core/hle/service/set/system_settings_server.h" -#include "core/hle/result.h" namespace FirmwareManager { -static constexpr std::array KEY_INSTALL_RESULT_STRINGS = { +static constexpr std::array KEY_INSTALL_RESULT_STRINGS = { "Decryption Keys were successfully installed", "Unable to read key directory, aborting", "One or more keys failed to copy.", @@ -54,8 +54,7 @@ KeyInstallResult InstallKeys(std::string location, std::string expected_extensio * \param result The result code. * \return A string representation of the passed result code. */ -inline constexpr const char *GetKeyInstallResultString(KeyInstallResult result) -{ +inline constexpr const char* GetKeyInstallResultString(KeyInstallResult result) { return KEY_INSTALL_RESULT_STRINGS.at(static_cast(result)); } @@ -65,13 +64,11 @@ inline constexpr const char *GetKeyInstallResultString(KeyInstallResult result) * \param program_id The program ID to check. * \return Whether or not the program requires firmware to run properly. */ -inline constexpr bool GameRequiresFirmware(u64 program_id) -{ - return std::find(FIRMWARE_REQUIRED_GAMES.begin(), FIRMWARE_REQUIRED_GAMES.end(), program_id) - != FIRMWARE_REQUIRED_GAMES.end(); +inline constexpr bool GameRequiresFirmware(u64 program_id) { + return std::find(FIRMWARE_REQUIRED_GAMES.begin(), FIRMWARE_REQUIRED_GAMES.end(), program_id) != + FIRMWARE_REQUIRED_GAMES.end(); } - enum FirmwareCheckResult { FirmwareGood, ErrorFirmwareMissing, @@ -79,7 +76,7 @@ enum FirmwareCheckResult { ErrorFirmwareTooNew, }; -static constexpr std::array FIRMWARE_CHECK_STRINGS = { +static constexpr std::array FIRMWARE_CHECK_STRINGS = { "", "Firmware missing. Firmware is required to run certain games and use the Home Menu. " "Eden only works with firmware 19.0.1 and earlier.", @@ -93,8 +90,7 @@ static constexpr std::array FIRMWARE_CHECK_STRINGS = { * \param system The system to check for firmware. * \return Whether or not the system has installed firmware. */ -inline bool CheckFirmwarePresence(Core::System &system) -{ +inline bool CheckFirmwarePresence(Core::System& system) { constexpr u64 MiiEditId = static_cast(Service::AM::AppletProgramId::MiiEdit); auto bis_system = system.GetFileSystemController().GetSystemNANDContents(); @@ -116,15 +112,14 @@ inline bool CheckFirmwarePresence(Core::System &system) * \param system The system to check firmware on. * \return A result code defining the status of the system's firmware. */ -FirmwareCheckResult VerifyFirmware(Core::System &system); +FirmwareCheckResult VerifyFirmware(Core::System& system); /** * \brief Get a string representation of a result from CheckFirmwareVersion. * \param result The result code. * \return A string representation of the passed result code. */ -inline constexpr const char *GetFirmwareCheckString(FirmwareCheckResult result) -{ +inline constexpr const char* GetFirmwareCheckString(FirmwareCheckResult result) { return FIRMWARE_CHECK_STRINGS.at(static_cast(result)); } @@ -133,16 +128,14 @@ inline constexpr const char *GetFirmwareCheckString(FirmwareCheckResult result) * @param system The system to check firmware on. * @return A pair of the firmware version format and result code. */ -inline std::pair GetFirmwareVersion(Core::System &system) -{ +inline std::pair GetFirmwareVersion( + Core::System& system) { Service::Set::FirmwareVersionFormat firmware_data{}; - const auto result - = Service::Set::GetFirmwareVersionImpl(firmware_data, - system, - Service::Set::GetFirmwareVersionType::Version2); + const auto result = Service::Set::GetFirmwareVersionImpl( + firmware_data, system, Service::Set::GetFirmwareVersionType::Version2); return {firmware_data, result}; } -} +} // namespace FirmwareManager #endif // FIRMWARE_MANAGER_H diff --git a/src/hid_core/frontend/emulated_controller.cpp b/src/hid_core/frontend/emulated_controller.cpp index 5bdad4a0ad..e20800ec02 100644 --- a/src/hid_core/frontend/emulated_controller.cpp +++ b/src/hid_core/frontend/emulated_controller.cpp @@ -760,14 +760,15 @@ void EmulatedController::StartMotionCalibration() { } } -void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) { +void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, + Common::UUID uuid) { const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type); const auto& player = Settings::values.players.GetValue()[player_index]; - - if (index >= controller.button_values.size()) { + + if (index >= controller.button_values.size()) { return; } - + std::unique_lock lock{mutex}; bool value_changed = false; const auto new_status = TransformToButton(callback); diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp index d483cd3490..ed6c01d0af 100644 --- a/src/input_common/drivers/udp_client.cpp +++ b/src/input_common/drivers/udp_client.cpp @@ -117,7 +117,6 @@ private: boost::asio::basic_waitable_timer timer; udp::socket socket; - const u32 client_id; static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message); diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp index 188e862d7f..1c0d5d9ed6 100644 --- a/src/input_common/input_poller.cpp +++ b/src/input_common/input_poller.cpp @@ -148,8 +148,8 @@ public: Common::Input::AnalogProperties properties_y_, InputEngine* input_engine_) : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_), - properties_y(properties_y_), - input_engine(input_engine_), invert_axis_y{input_engine_->GetEngineName() == "sdl"} { + properties_y(properties_y_), input_engine(input_engine_), + invert_axis_y{input_engine_->GetEngineName() == "sdl"} { UpdateCallback engine_callback{[this]() { OnChange(); }}; const InputIdentifier x_input_identifier{ .identifier = identifier, diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 8e306219fb..1657feaa5f 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -25,6 +25,11 @@ if (ENABLE_WEB_SERVICE) target_link_libraries(network PRIVATE web_service) endif() +# Solaris uses /lib/amd64/libsocket.so and /lib/amd64/libnsl.so +if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") + target_link_libraries(network PRIVATE socket nsl) +endif() + if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(network PRIVATE precompiled_headers.h) endif() diff --git a/src/network/announce_multiplayer_session.cpp b/src/network/announce_multiplayer_session.cpp index 8836524c73..dafd90413f 100644 --- a/src/network/announce_multiplayer_session.cpp +++ b/src/network/announce_multiplayer_session.cpp @@ -13,9 +13,9 @@ #include "common/settings.h" #include "network/network.h" -//#ifdef ENABLE_WEB_SERVICE +// #ifdef ENABLE_WEB_SERVICE #include "web_service/announce_room_json.h" -//#endif +// #endif namespace Core { @@ -23,13 +23,13 @@ namespace Core { static constexpr std::chrono::seconds announce_time_interval(15); AnnounceMultiplayerSession::AnnounceMultiplayerSession() { -//#ifdef ENABLE_WEB_SERVICE + // #ifdef ENABLE_WEB_SERVICE backend = std::make_unique(Settings::values.web_api_url.GetValue(), Settings::values.eden_username.GetValue(), Settings::values.eden_token.GetValue()); -//#else -// backend = std::make_unique(); -//#endif + // #else + // backend = std::make_unique(); + // #endif } WebService::WebResult AnnounceMultiplayerSession::Register() { @@ -156,11 +156,11 @@ bool AnnounceMultiplayerSession::IsRunning() const { void AnnounceMultiplayerSession::UpdateCredentials() { ASSERT_MSG(!IsRunning(), "Credentials can only be updated when session is not running"); -//#ifdef ENABLE_WEB_SERVICE + // #ifdef ENABLE_WEB_SERVICE backend = std::make_unique(Settings::values.web_api_url.GetValue(), Settings::values.eden_username.GetValue(), Settings::values.eden_token.GetValue()); -//#endif + // #endif } } // namespace Core diff --git a/src/network/packet.cpp b/src/network/packet.cpp index 0e22f1eb4d..e7fc83ed99 100644 --- a/src/network/packet.cpp +++ b/src/network/packet.cpp @@ -14,13 +14,13 @@ namespace Network { #ifndef htonll static u64 htonll(u64 x) { - return ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32)); + return ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)); } #endif #ifndef ntohll static u64 ntohll(u64 x) { - return ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32)); + return ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)); } #endif diff --git a/src/network/room.cpp b/src/network/room.cpp index 99dcf0c3b4..5fe44f4857 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp @@ -360,7 +360,7 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { } if (verify_backend != nullptr) - member.user_data = verify_backend->LoadUserData(uid, token); + member.user_data = verify_backend->LoadUserData(uid, token); if (nickname == room_information.host_username) { member.user_data.moderator = true; diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp index 47babcdc07..e0e8942e48 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp @@ -6,8 +6,8 @@ #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" #include "shader_recompiler/backend/glasm/glasm_emit_context.h" #include "shader_recompiler/frontend/ir/value.h" -#include "shader_recompiler/runtime_info.h" #include "shader_recompiler/profile.h" +#include "shader_recompiler/runtime_info.h" #include "shader_recompiler/shader_info.h" namespace Shader::Backend::GLASM { diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp index 473dc83642..6aa132e629 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp @@ -225,4 +225,28 @@ void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, Register value) { Convert(ctx, inst, value, "F64", "U64", true); } +void EmitConvertU16U32(EmitContext& ctx, IR::Inst& inst, Register value) { + Convert(ctx, inst, value, "U32", "U16", false); +} + +void EmitConvertU32U16(EmitContext& ctx, IR::Inst& inst, Register value) { + Convert(ctx, inst, value, "U16", "U32", false); +} + +void EmitConvertU8U32(EmitContext& ctx, IR::Inst& inst, Register value) { + Convert(ctx, inst, value, "U32", "U8", false); +} + +void EmitConvertU32U8(EmitContext& ctx, IR::Inst& inst, Register value) { + Convert(ctx, inst, value, "U8", "U32", false); +} + +void EmitConvertS32S8(EmitContext& ctx, IR::Inst& inst, Register value) { + Convert(ctx, inst, value, "S8", "S32", false); +} + +void EmitConvertS32S16(EmitContext& ctx, IR::Inst& inst, Register value) { + Convert(ctx, inst, value, "S16", "S32", false); +} + } // namespace Shader::Backend::GLASM diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h index c5d4835fa9..e4cc5e694b 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h +++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h @@ -541,6 +541,12 @@ void EmitConvertF64U8(EmitContext& ctx, IR::Inst& inst, Register value); void EmitConvertF64U16(EmitContext& ctx, IR::Inst& inst, Register value); void EmitConvertF64U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value); void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, Register value); +void EmitConvertU16U32(EmitContext& ctx, IR::Inst& inst, Register value); +void EmitConvertU32U16(EmitContext& ctx, IR::Inst& inst, Register value); +void EmitConvertU8U32(EmitContext& ctx, IR::Inst& inst, Register value); +void EmitConvertU32U8(EmitContext& ctx, IR::Inst& inst, Register value); +void EmitConvertS32S8(EmitContext& ctx, IR::Inst& inst, Register value); +void EmitConvertS32S16(EmitContext& ctx, IR::Inst& inst, Register value); void EmitBindlessImageSampleImplicitLod(EmitContext&); void EmitBindlessImageSampleExplicitLod(EmitContext&); void EmitBindlessImageSampleDrefImplicitLod(EmitContext&); diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp index aeacb5a64c..cf404f7b51 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp @@ -68,6 +68,36 @@ void EmitConvertU32F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I NotImplemented(); } +void EmitConvertU16U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, + [[maybe_unused]] std::string_view value) { + NotImplemented(); +} + +void EmitConvertU32U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, + [[maybe_unused]] std::string_view value) { + NotImplemented(); +} + +void EmitConvertU8U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, + [[maybe_unused]] std::string_view value) { + NotImplemented(); +} + +void EmitConvertU32U8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, + [[maybe_unused]] std::string_view value) { + NotImplemented(); +} + +void EmitConvertS32S8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, + [[maybe_unused]] std::string_view value) { + NotImplemented(); +} + +void EmitConvertS32S16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, + [[maybe_unused]] std::string_view value) { + NotImplemented(); +} + void EmitConvertU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { ctx.AddU32("{}=uint({});", inst, value); } diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index 9e405b37fb..fb669d399e 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h @@ -611,6 +611,12 @@ void EmitConvertF64U8(EmitContext& ctx, IR::Inst& inst, std::string_view value); void EmitConvertF64U16(EmitContext& ctx, IR::Inst& inst, std::string_view value); void EmitConvertF64U32(EmitContext& ctx, IR::Inst& inst, std::string_view value); void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value); +void EmitConvertU16U32(EmitContext& ctx, IR::Inst& inst, std::string_view value); +void EmitConvertU32U16(EmitContext& ctx, IR::Inst& inst, std::string_view value); +void EmitConvertU8U32(EmitContext& ctx, IR::Inst& inst, std::string_view value); +void EmitConvertU32U8(EmitContext& ctx, IR::Inst& inst, std::string_view value); +void EmitConvertS32S8(EmitContext& ctx, IR::Inst& inst, std::string_view value); +void EmitConvertS32S16(EmitContext& ctx, IR::Inst& inst, std::string_view value); void EmitBindlessImageSampleImplicitLod(EmitContext&); void EmitBindlessImageSampleExplicitLod(EmitContext&); void EmitBindlessImageSampleDrefImplicitLod(EmitContext&); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp index 0ce73f289b..fd6a9c4bfb 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp @@ -35,7 +35,7 @@ Id StorageIndex(EmitContext& ctx, const IR::Value& offset, size_t element_size) } Id StoragePointer(EmitContext& ctx, const StorageTypeDefinition& type_def, - Id StorageDefinitions::*member_ptr, const IR::Value& binding, + Id StorageDefinitions::* member_ptr, const IR::Value& binding, const IR::Value& offset, size_t element_size) { if (!binding.IsImmediate()) { throw NotImplementedException("Dynamic storage buffer indexing"); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 5dab8b62ea..076aeb9e52 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -110,7 +110,7 @@ std::optional OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { } } -Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, u32 element_size, +Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::* member_ptr, u32 element_size, const IR::Value& binding, const IR::Value& offset, const Id indirect_func) { Id buffer_offset; const Id uniform_type{ctx.uniform_types.*member_ptr}; @@ -427,7 +427,7 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, [[maybe_un static constexpr IR::Attribute cd7 = IR::Attribute::ClipDistance7; if (attr >= cd0 && attr <= cd7) { - const u32 idx = (u32) attr - (u32) cd0; + const u32 idx = (u32)attr - (u32)cd0; clip_distance_written.set(idx); } ctx.OpStore(output->pointer, value); @@ -556,9 +556,12 @@ Id EmitInvocationInfo(EmitContext& ctx) { switch (ctx.stage) { case Stage::TessellationControl: case Stage::TessellationEval: - return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.OpLoad(ctx.U32[1], ctx.patch_vertices_in), ctx.Const(16u)); + return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.OpLoad(ctx.U32[1], ctx.patch_vertices_in), + ctx.Const(16u)); case Stage::Geometry: - return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.Const(InputTopologyVertices::vertices(ctx.runtime_info.input_topology)), ctx.Const(16u)); + return ctx.OpShiftLeftLogical( + ctx.U32[1], ctx.Const(InputTopologyVertices::vertices(ctx.runtime_info.input_topology)), + ctx.Const(16u)); default: LOG_WARNING(Shader, "(STUBBED) called"); return ctx.Const(0x00ff0000u); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index 7b6e34f315..1ff88762dc 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -151,7 +151,7 @@ Id EmitConvertF16F32(EmitContext& ctx, Id value) { const auto result = ctx.OpFConvert(ctx.F16[1], value); const auto isOverflowing = ctx.OpIsNan(ctx.U1, result); return ctx.OpSelect(ctx.F16[1], isOverflowing, ctx.Constant(ctx.F16[1], 0), result); - //return ctx.OpFConvert(ctx.F16[1], value); + // return ctx.OpFConvert(ctx.F16[1], value); } Id EmitConvertF32F16(EmitContext& ctx, Id value) { @@ -268,4 +268,53 @@ Id EmitConvertF64U64(EmitContext& ctx, Id value) { return ctx.OpConvertUToF(ctx.F64[1], value); } +Id EmitConvertU16U32(EmitContext& ctx, Id value) { + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U16, value); + } else { + return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u)); + } +} + +Id EmitConvertU32U16(EmitContext& ctx, Id value) { + if (ctx.profile.support_int16) { + return ctx.OpUConvert(ctx.U32[1], value); + } else { + return ExtractU16(ctx, value); + } +} + +Id EmitConvertU8U32(EmitContext& ctx, Id value) { + if (ctx.profile.support_int8) { + return ctx.OpUConvert(ctx.U8, value); + } else { + return ExtractU8(ctx, value); + } +} + +Id EmitConvertU32U8(EmitContext& ctx, Id value) { + if (ctx.profile.support_int8) { + return ctx.OpUConvert(ctx.U32[1], value); + } else { + return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u)); + } +} + +// in signed +Id EmitConvertS32S8(EmitContext& ctx, Id value) { + if (ctx.profile.support_int8) { + return ctx.OpSConvert(ctx.U32[1], value); + } else { + return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u)); + } +} + +Id EmitConvertS32S16(EmitContext& ctx, Id value) { + if (ctx.profile.support_int16) { + return ctx.OpSConvert(ctx.U32[1], value); + } else { + return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u)); + } +} + } // namespace Shader::Backend::SPIRV diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index b8e98e6c58..52be1369c2 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -503,6 +503,12 @@ Id EmitConvertF64U8(EmitContext& ctx, Id value); Id EmitConvertF64U16(EmitContext& ctx, Id value); Id EmitConvertF64U32(EmitContext& ctx, Id value); Id EmitConvertF64U64(EmitContext& ctx, Id value); +Id EmitConvertU16U32(EmitContext& ctx, Id value); +Id EmitConvertU32U16(EmitContext& ctx, Id value); +Id EmitConvertU8U32(EmitContext& ctx, Id value); +Id EmitConvertU32U8(EmitContext& ctx, Id value); +Id EmitConvertS32S8(EmitContext& ctx, Id value); +Id EmitConvertS32S16(EmitContext& ctx, Id value); Id EmitBindlessImageSampleImplicitLod(EmitContext&); Id EmitBindlessImageSampleExplicitLod(EmitContext&); Id EmitBindlessImageSampleDrefImplicitLod(EmitContext&); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp index bdcbccfde9..fb7aed28ee 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp @@ -29,7 +29,7 @@ Id StorageIndex(EmitContext& ctx, const IR::Value& offset, size_t element_size, Id StoragePointer(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, const StorageTypeDefinition& type_def, size_t element_size, - Id StorageDefinitions::*member_ptr, u32 index_offset = 0) { + Id StorageDefinitions::* member_ptr, u32 index_offset = 0) { if (!binding.IsImmediate()) { throw NotImplementedException("Dynamic storage buffer indexing"); } @@ -40,7 +40,7 @@ Id StoragePointer(EmitContext& ctx, const IR::Value& binding, const IR::Value& o Id LoadStorage(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, Id result_type, const StorageTypeDefinition& type_def, size_t element_size, - Id StorageDefinitions::*member_ptr, u32 index_offset = 0) { + Id StorageDefinitions::* member_ptr, u32 index_offset = 0) { const Id pointer{ StoragePointer(ctx, binding, offset, type_def, element_size, member_ptr, index_offset)}; return ctx.OpLoad(result_type, pointer); @@ -54,7 +54,7 @@ Id LoadStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& of void WriteStorage(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, Id value, const StorageTypeDefinition& type_def, size_t element_size, - Id StorageDefinitions::*member_ptr, u32 index_offset = 0) { + Id StorageDefinitions::* member_ptr, u32 index_offset = 0) { const Id pointer{ StoragePointer(ctx, binding, offset, type_def, element_size, member_ptr, index_offset)}; ctx.OpStore(pointer, value); diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 388ddce2c8..9ad604fcf7 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -262,7 +262,7 @@ void Name(EmitContext& ctx, Id object, std::string_view format_str, Args&&... ar .c_str()); } -void DefineConstBuffers(EmitContext& ctx, const Info& info, Id UniformDefinitions::*member_type, +void DefineConstBuffers(EmitContext& ctx, const Info& info, Id UniformDefinitions::* member_type, u32 binding, Id type, char type_char, u32 element_size) { const Id array_type{ctx.TypeArray(type, ctx.Const(65536U / element_size))}; ctx.Decorate(array_type, spv::Decoration::ArrayStride, element_size); @@ -293,7 +293,7 @@ void DefineConstBuffers(EmitContext& ctx, const Info& info, Id UniformDefinition } void DefineSsbos(EmitContext& ctx, StorageTypeDefinition& type_def, - Id StorageDefinitions::*member_type, const Info& info, u32 binding, Id type, + Id StorageDefinitions::* member_type, const Info& info, u32 binding, Id type, u32 stride) { const Id array_type{ctx.TypeRuntimeArray(type)}; ctx.Decorate(array_type, spv::Decoration::ArrayStride, stride); @@ -1156,7 +1156,7 @@ void EmitContext::DefineConstantBufferIndirectFunctions(const Info& info) { if (!info.uses_cbuf_indirect) { return; } - const auto make_accessor{[&](Id buffer_type, Id UniformDefinitions::*member_ptr) { + const auto make_accessor{[&](Id buffer_type, Id UniformDefinitions::* member_ptr) { const Id func_type{TypeFunction(buffer_type, U32[1], U32[1])}; const Id func{OpFunction(buffer_type, spv::FunctionControlMask::MaskNone, func_type)}; const Id binding{OpFunctionParameter(U32[1])}; diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 66cdb1d3db..65da62ac9b 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -69,7 +69,7 @@ struct UniformDefinitions { Id U32x2{}; Id U32x4{}; - constexpr static size_t NumElements(Id UniformDefinitions::*member_ptr) { + constexpr static size_t NumElements(Id UniformDefinitions::* member_ptr) { if (member_ptr == &UniformDefinitions::U8) { return 1; } @@ -98,7 +98,7 @@ struct UniformDefinitions { return 1; } - constexpr static bool IsFloat(Id UniformDefinitions::*member_ptr) { + constexpr static bool IsFloat(Id UniformDefinitions::* member_ptr) { if (member_ptr == &UniformDefinitions::F32) { return true; } diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index e1e46cb81c..a2fa9b1588 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp @@ -1730,10 +1730,36 @@ F16F32F64 IREmitter::ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool i : ConvertUToF(dest_bitsize, src_bitsize, value, control); } -U32U64 IREmitter::UConvert(size_t result_bitsize, const U32U64& value) { +U8U16U32U64 IREmitter::UConvert(size_t result_bitsize, const U8U16U32U64& value) { switch (result_bitsize) { + case 8: + switch (value.Type()) { + case Type::U8: + // Nothing to do + return value; + case Type::U32: + return Inst(Opcode::ConvertU8U32, value); + default: + break; + } + break; + case 16: + switch (value.Type()) { + case Type::U16: + // Nothing to do + return value; + case Type::U32: + return Inst(Opcode::ConvertU16U32, value); + default: + break; + } + break; case 32: switch (value.Type()) { + case Type::U8: + return Inst(Opcode::ConvertU32U8, value); + case Type::U16: + return Inst(Opcode::ConvertU32U16, value); case Type::U32: // Nothing to do return value; @@ -1753,10 +1779,31 @@ U32U64 IREmitter::UConvert(size_t result_bitsize, const U32U64& value) { default: break; } + break; + default: + break; } throw NotImplementedException("Conversion from {} to {} bits", value.Type(), result_bitsize); } +U8U16U32U64 IR::IREmitter::SConvert(size_t result_bitsize, const U8U16U32U64& value) { + switch (result_bitsize) { + case 32: + switch (value.Type()) { + case Type::U8: + return Inst(Opcode::ConvertS32S8, value); + case Type::U16: + return Inst(Opcode::ConvertS32S16, value); + default: + break; + } + break; + default: + break; + } + throw NotImplementedException("Signed Conversion from {} to {} bits", value.Type(), result_bitsize); +} + F16F32F64 IREmitter::FPConvert(size_t result_bitsize, const F16F32F64& value, FpControl control) { switch (result_bitsize) { case 16: diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 073091ea58..48828f3ecc 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h @@ -305,7 +305,8 @@ public: [[nodiscard]] F16F32F64 ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, const Value& value, FpControl control = {}); - [[nodiscard]] U32U64 UConvert(size_t result_bitsize, const U32U64& value); + [[nodiscard]] U8U16U32U64 UConvert(size_t result_bitsize, const U8U16U32U64& value); + [[nodiscard]] U8U16U32U64 SConvert(size_t result_bitsize, const U8U16U32U64& value); [[nodiscard]] F16F32F64 FPConvert(size_t result_bitsize, const F16F32F64& value, FpControl control = {}); diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 2f880a8596..4a6da06f66 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc @@ -475,6 +475,12 @@ OPCODE(ConvertF64U8, F64, U32, OPCODE(ConvertF64U16, F64, U32, ) OPCODE(ConvertF64U32, F64, U32, ) OPCODE(ConvertF64U64, F64, U64, ) +OPCODE(ConvertU16U32, U16, U32, ) +OPCODE(ConvertU32U16, U32, U16, ) +OPCODE(ConvertU8U32, U8, U32, ) +OPCODE(ConvertU32U8, U32, U8, ) +OPCODE(ConvertS32S8, U32, U8, ) +OPCODE(ConvertS32S16, U32, U16, ) // Image operations OPCODE(BindlessImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h index c27546b0e1..514344dfe3 100644 --- a/src/shader_recompiler/frontend/ir/value.h +++ b/src/shader_recompiler/frontend/ir/value.h @@ -269,6 +269,7 @@ using F32 = TypedValue; using F64 = TypedValue; using U32U64 = TypedValue; using F32F64 = TypedValue; +using U8U16U32U64 = TypedValue; using U16U32U64 = TypedValue; using F16F32F64 = TypedValue; using UAny = TypedValue; diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.cpp b/src/shader_recompiler/frontend/maxwell/control_flow.cpp index a2ad56cc49..b8d09d1614 100644 --- a/src/shader_recompiler/frontend/maxwell/control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/control_flow.cpp @@ -186,8 +186,8 @@ Function::Function(ObjectPool& block_pool, Location start_address) CFG::CFG(Environment& env_, ObjectPool& block_pool_, Location start_address, bool exits_to_dispatcher_) - : env{env_}, block_pool{block_pool_}, program_start{start_address}, exits_to_dispatcher{ - exits_to_dispatcher_} { + : env{env_}, block_pool{block_pool_}, program_start{start_address}, + exits_to_dispatcher{exits_to_dispatcher_} { if (exits_to_dispatcher) { dispatch_block = block_pool.Create(Block{}); dispatch_block->begin = {}; diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index 3c18f49982..acc54ca8bb 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp @@ -112,8 +112,8 @@ struct Statement : ListBaseHook { Statement(SetVariable, u32 id_, Statement* op_, Statement* up_) : op{op_}, id{id_}, up{up_}, type{StatementType::SetVariable} {} Statement(SetIndirectBranchVariable, IR::Reg branch_reg_, s32 branch_offset_, Statement* up_) - : branch_offset{branch_offset_}, - branch_reg{branch_reg_}, up{up_}, type{StatementType::SetIndirectBranchVariable} {} + : branch_offset{branch_offset_}, branch_reg{branch_reg_}, up{up_}, + type{StatementType::SetIndirectBranchVariable} {} Statement(Variable, u32 id_, Statement* up_) : id{id_}, up{up_}, type{StatementType::Variable} {} Statement(IndirectBranchCond, u32 location_, Statement* up_) diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index afd880526a..f198150d36 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -349,11 +349,13 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { const std::optional track_addr{Track(inst.Arg(0), env)}; if (!track_addr) { - //throw NotImplementedException("Failed to track bindless texture constant buffer"); - addr = last_valid_addr; // TODO:xbzk: shall be dropped when Track method cover all bindless stuff + // throw NotImplementedException("Failed to track bindless texture constant buffer"); + addr = last_valid_addr; // TODO:xbzk: shall be dropped when Track method cover all + // bindless stuff } else { addr = *track_addr; - last_valid_addr = addr; // TODO:xbzk: shall be dropped when Track method cover all bindless stuff + last_valid_addr = + addr; // TODO:xbzk: shall be dropped when Track method cover all bindless stuff } } else { addr = ConstBufferAddr{ diff --git a/src/tests/common/host_memory.cpp b/src/tests/common/host_memory.cpp index cb040c942d..57268e7878 100644 --- a/src/tests/common/host_memory.cpp +++ b/src/tests/common/host_memory.cpp @@ -15,8 +15,12 @@ static constexpr auto PERMS = Common::MemoryPermission::ReadWrite; static constexpr auto HEAP = false; TEST_CASE("HostMemory: Initialize and deinitialize", "[common]") { - { HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE); } - { HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE); } + { + HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE); + } + { + HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE); + } } TEST_CASE("HostMemory: Simple map", "[common]") { diff --git a/src/tests/input_common/calibration_configuration_job.cpp b/src/tests/input_common/calibration_configuration_job.cpp index 8f5466253c..14d9c8e2a5 100644 --- a/src/tests/input_common/calibration_configuration_job.cpp +++ b/src/tests/input_common/calibration_configuration_job.cpp @@ -11,7 +11,6 @@ #include "input_common/drivers/udp_client.h" #include "input_common/helpers/udp_protocol.h" - class FakeCemuhookServer { public: FakeCemuhookServer() diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index a6e87a3583..d32d4ace24 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -187,34 +187,34 @@ void BufferCache

::ClearDownload(DAddr device_addr, u64 size) { } template -bool BufferCache

::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) { +bool BufferCache

::DMACopy(GPUVAddr src_address, GPUVAddr dst_address, u64 amount) { const std::optional cpu_src_address = gpu_memory->GpuToCpuAddress(src_address); - const std::optional cpu_dest_address = gpu_memory->GpuToCpuAddress(dest_address); - if (!cpu_src_address || !cpu_dest_address) { + const std::optional cpu_dst_address = gpu_memory->GpuToCpuAddress(dst_address); + if (!cpu_src_address || !cpu_dst_address) { return false; } - const bool source_dirty = IsRegionRegistered(*cpu_src_address, amount); - const bool dest_dirty = IsRegionRegistered(*cpu_dest_address, amount); - if (!source_dirty && !dest_dirty) { + const bool src_dirty = IsRegionRegistered(*cpu_src_address, amount); + const bool dst_dirty = IsRegionRegistered(*cpu_dst_address, amount); + if (!src_dirty && !dst_dirty) { return false; } - ClearDownload(*cpu_dest_address, amount); + ClearDownload(*cpu_dst_address, amount); BufferId buffer_a; BufferId buffer_b; do { channel_state->has_deleted_buffers = false; buffer_a = FindBuffer(*cpu_src_address, static_cast(amount)); - buffer_b = FindBuffer(*cpu_dest_address, static_cast(amount)); + buffer_b = FindBuffer(*cpu_dst_address, static_cast(amount)); } while (channel_state->has_deleted_buffers); auto& src_buffer = slot_buffers[buffer_a]; - auto& dest_buffer = slot_buffers[buffer_b]; + auto& dst_buffer = slot_buffers[buffer_b]; SynchronizeBuffer(src_buffer, *cpu_src_address, static_cast(amount)); - SynchronizeBuffer(dest_buffer, *cpu_dest_address, static_cast(amount)); + SynchronizeBuffer(dst_buffer, *cpu_dst_address, static_cast(amount)); std::array copies{BufferCopy{ .src_offset = src_buffer.Offset(*cpu_src_address), - .dst_offset = dest_buffer.Offset(*cpu_dest_address), + .dst_offset = dst_buffer.Offset(*cpu_dst_address), .size = amount, }}; @@ -222,28 +222,28 @@ bool BufferCache

::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am auto mirror = [&](DAddr base_address, DAddr base_address_end) { const u64 size = base_address_end - base_address; const DAddr diff = base_address - *cpu_src_address; - const DAddr new_base_address = *cpu_dest_address + diff; + const DAddr new_base_address = *cpu_dst_address + diff; tmp_intervals.push_back({new_base_address, size}); uncommitted_gpu_modified_ranges.Add(new_base_address, size); }; gpu_modified_ranges.ForEachInRange(*cpu_src_address, amount, mirror); // This subtraction in this order is important for overlapping copies. - gpu_modified_ranges.Subtract(*cpu_dest_address, amount); + gpu_modified_ranges.Subtract(*cpu_dst_address, amount); const bool has_new_downloads = tmp_intervals.size() != 0; for (const auto& pair : tmp_intervals) { gpu_modified_ranges.Add(pair.first, pair.second); } const auto& copy = copies[0]; src_buffer.MarkUsage(copy.src_offset, copy.size); - dest_buffer.MarkUsage(copy.dst_offset, copy.size); - runtime.CopyBuffer(dest_buffer, src_buffer, copies, true); + dst_buffer.MarkUsage(copy.dst_offset, copy.size); + runtime.CopyBuffer(dst_buffer, src_buffer, copies, true); if (has_new_downloads) { - memory_tracker.MarkRegionAsGpuModified(*cpu_dest_address, amount); + memory_tracker.MarkRegionAsGpuModified(*cpu_dst_address, amount); } Tegra::Memory::DeviceGuestMemoryScoped tmp(device_memory, *cpu_src_address, amount, &tmp_buffer); - tmp.SetAddressAndSize(*cpu_dest_address, amount); + tmp.SetAddressAndSize(*cpu_dst_address, amount); return true; } @@ -253,8 +253,8 @@ bool BufferCache

::DMAClear(GPUVAddr dst_address, u64 amount, u32 value) { if (!cpu_dst_address) { return false; } - const bool dest_dirty = IsRegionRegistered(*cpu_dst_address, amount); - if (!dest_dirty) { + const bool dst_dirty = IsRegionRegistered(*cpu_dst_address, amount); + if (!dst_dirty) { return false; } @@ -263,10 +263,10 @@ bool BufferCache

::DMAClear(GPUVAddr dst_address, u64 amount, u32 value) { gpu_modified_ranges.Subtract(*cpu_dst_address, size); const BufferId buffer = FindBuffer(*cpu_dst_address, static_cast(size)); - Buffer& dest_buffer = slot_buffers[buffer]; - const u32 offset = dest_buffer.Offset(*cpu_dst_address); - runtime.ClearBuffer(dest_buffer, offset, size, value); - dest_buffer.MarkUsage(offset, size); + Buffer& dst_buffer = slot_buffers[buffer]; + const u32 offset = dst_buffer.Offset(*cpu_dst_address); + runtime.ClearBuffer(dst_buffer, offset, size, value); + dst_buffer.MarkUsage(offset, size); return true; } @@ -467,6 +467,10 @@ void BufferCache

::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index; const auto& launch_desc = kepler_compute->launch_description; + if (((launch_desc.const_buffer_enable_mask >> cbuf_index) & 1) == 0) { + LOG_WARNING(HW_GPU, "Skipped binding SSBO: cbuf index {} is not enabled", cbuf_index); + return; + } ASSERT(((launch_desc.const_buffer_enable_mask >> cbuf_index) & 1) != 0); const auto& cbufs = launch_desc.const_buffer_config; @@ -1074,8 +1078,7 @@ void BufferCache

::UpdateIndexBuffer() { u32 buffer_size = Common::AlignUp(inline_index_size, CACHING_PAGESIZE); if (inline_buffer_id == NULL_BUFFER_ID) [[unlikely]] { inline_buffer_id = CreateBuffer(0, buffer_size); - } - if (slot_buffers[inline_buffer_id].SizeBytes() < buffer_size) [[unlikely]] { + } else if (slot_buffers[inline_buffer_id].SizeBytes() < buffer_size) [[unlikely]] { slot_buffers.erase(inline_buffer_id); inline_buffer_id = CreateBuffer(0, buffer_size); } @@ -1529,38 +1532,38 @@ void BufferCache

::MappedUploadMemory([[maybe_unused]] Buffer& buffer, } template -bool BufferCache

::InlineMemory(DAddr dest_address, size_t copy_size, +bool BufferCache

::InlineMemory(DAddr dst_address, size_t copy_size, std::span inlined_buffer) { - const bool is_dirty = IsRegionRegistered(dest_address, copy_size); + const bool is_dirty = IsRegionRegistered(dst_address, copy_size); if (!is_dirty) { return false; } - DAddr aligned_start = Common::AlignDown(dest_address, DEVICE_PAGESIZE); - DAddr aligned_end = Common::AlignUp(dest_address + copy_size, DEVICE_PAGESIZE); + DAddr aligned_start = Common::AlignDown(dst_address, DEVICE_PAGESIZE); + DAddr aligned_end = Common::AlignUp(dst_address + copy_size, DEVICE_PAGESIZE); if (!IsRegionGpuModified(aligned_start, aligned_end - aligned_start)) { return false; } - InlineMemoryImplementation(dest_address, copy_size, inlined_buffer); + InlineMemoryImplementation(dst_address, copy_size, inlined_buffer); return true; } template -void BufferCache

::InlineMemoryImplementation(DAddr dest_address, size_t copy_size, +void BufferCache

::InlineMemoryImplementation(DAddr dst_address, size_t copy_size, std::span inlined_buffer) { - ClearDownload(dest_address, copy_size); - gpu_modified_ranges.Subtract(dest_address, copy_size); + ClearDownload(dst_address, copy_size); + gpu_modified_ranges.Subtract(dst_address, copy_size); - BufferId buffer_id = FindBuffer(dest_address, static_cast(copy_size)); + BufferId buffer_id = FindBuffer(dst_address, static_cast(copy_size)); auto& buffer = slot_buffers[buffer_id]; - SynchronizeBuffer(buffer, dest_address, static_cast(copy_size)); + SynchronizeBuffer(buffer, dst_address, static_cast(copy_size)); if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) { auto upload_staging = runtime.UploadStagingBuffer(copy_size); std::array copies{BufferCopy{ .src_offset = upload_staging.offset, - .dst_offset = buffer.Offset(dest_address), + .dst_offset = buffer.Offset(dst_address), .size = copy_size, }}; u8* const src_pointer = upload_staging.mapped_span.data(); @@ -1568,7 +1571,7 @@ void BufferCache

::InlineMemoryImplementation(DAddr dest_address, size_t copy_ const bool can_reorder = runtime.CanReorderUpload(buffer, copies); runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true, can_reorder); } else { - buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer.first(copy_size)); + buffer.ImmediateUpload(buffer.Offset(dst_address), inlined_buffer.first(copy_size)); } } @@ -1701,6 +1704,11 @@ template Binding BufferCache

::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index, bool is_written) const { const GPUVAddr gpu_addr = gpu_memory->Read(ssbo_addr); + + if (gpu_addr == 0) { + return NULL_BINDING; + } + const auto size = [&]() { const bool is_nvn_cbuf = cbuf_index == 0; // The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. @@ -1723,7 +1731,7 @@ Binding BufferCache

::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index, const std::optional aligned_device_addr = gpu_memory->GpuToCpuAddress(aligned_gpu_addr); if (!aligned_device_addr || size == 0) { - LOG_WARNING(HW_GPU, "Failed to find storage buffer for cbuf index {}", cbuf_index); + LOG_DEBUG(HW_GPU, "Failed to find storage buffer for cbuf index {}", cbuf_index); return NULL_BINDING; } const std::optional device_addr = gpu_memory->GpuToCpuAddress(gpu_addr); diff --git a/src/video_core/cdma_pusher.cpp b/src/video_core/cdma_pusher.cpp index 2a13594719..ab949ea0da 100644 --- a/src/video_core/cdma_pusher.cpp +++ b/src/video_core/cdma_pusher.cpp @@ -21,8 +21,8 @@ namespace Tegra { CDmaPusher::CDmaPusher(Host1x::Host1x& host1x_, s32 id) : host1x{host1x_}, memory_manager{host1x.GMMU()}, - host_processor{std::make_unique(host1x_)}, current_class{ - static_cast(id)} { + host_processor{std::make_unique(host1x_)}, + current_class{static_cast(id)} { thread = std::jthread([this](std::stop_token stop_token) { ProcessEntries(stop_token); }); } diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 401329eea0..c2ec5267f0 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/cityhash.h" #include "common/microprofile.h" #include "common/settings.h" #include "core/core.h" @@ -14,18 +13,12 @@ namespace Tegra { constexpr u32 MacroRegistersStart = 0xE00; -constexpr u32 ComputeInline = 0x6D; -//start on PR#76 of Eden this is a unused variable in android (need to investigate) - -// Dummy function that uses ComputeInline -constexpr void UseComputeInline() { - static_cast(ComputeInline); // Suppress unused variable error -} +// constexpr u32 ComputeInline = 0x6D; DmaPusher::DmaPusher(Core::System& system_, GPU& gpu_, MemoryManager& memory_manager_, Control::ChannelState& channel_state_) - : gpu{gpu_}, system{system_}, memory_manager{memory_manager_}, puller{gpu_, memory_manager_, - *this, channel_state_} {} + : gpu{gpu_}, system{system_}, memory_manager{memory_manager_}, + puller{gpu_, memory_manager_, *this, channel_state_} {} DmaPusher::~DmaPusher() = default; @@ -107,10 +100,8 @@ bool DmaPusher::Step() { // Only use unsafe reads for non-compute macro operations if (Settings::IsGPULevelHigh()) { - const bool is_compute = (subchannel_type[dma_state.subchannel] == - Engines::EngineTypes::KeplerCompute); - - if (dma_state.method >= MacroRegistersStart && !is_compute) { + if (subchannel_type[dma_state.subchannel] != Engines::EngineTypes::KeplerCompute && + dma_state.method >= MacroRegistersStart) { unsafe_process(); return true; } diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 0d47b032c8..5e070fa3b4 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -24,9 +24,8 @@ constexpr u32 MacroRegistersStart = 0xE00; Maxwell3D::Maxwell3D(Core::System& system_, MemoryManager& memory_manager_) : draw_manager{std::make_unique(this)}, system{system_}, - memory_manager{memory_manager_}, macro_engine{GetMacroEngine(*this)}, upload_state{ - memory_manager, - regs.upload} { + memory_manager{memory_manager_}, macro_engine{GetMacroEngine(*this)}, + upload_state{memory_manager, regs.upload} { dirty.flags.flip(); InitializeRegisterDefaults(); execution_mask.reset(); diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp index 8dd34c04ab..415bac9c98 100644 --- a/src/video_core/engines/puller.cpp +++ b/src/video_core/engines/puller.cpp @@ -21,8 +21,8 @@ namespace Tegra::Engines { Puller::Puller(GPU& gpu_, MemoryManager& memory_manager_, DmaPusher& dma_pusher_, Control::ChannelState& channel_state_) - : gpu{gpu_}, memory_manager{memory_manager_}, dma_pusher{dma_pusher_}, channel_state{ - channel_state_} {} + : gpu{gpu_}, memory_manager{memory_manager_}, dma_pusher{dma_pusher_}, + channel_state{channel_state_} {} Puller::~Puller() = default; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 7c34005a12..36709193e3 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -200,10 +200,9 @@ struct GPU::Impl { u64 gpu_tick = system.CoreTiming().GetGPUTicks(); if (Settings::values.use_fast_gpu_time.GetValue()) { - gpu_tick /= (u64) (128 - * std::pow(2, - static_cast( - Settings::values.fast_gpu_time.GetValue()))); + gpu_tick /= + (u64)(128 * + std::pow(2, static_cast(Settings::values.fast_gpu_time.GetValue()))); } return gpu_tick; @@ -230,9 +229,8 @@ struct GPU::Impl { } void NotifyShutdown() { - std::unique_lock lk{sync_mutex}; - shutting_down.store(true, std::memory_order::relaxed); - sync_cv.notify_all(); + rasterizer->ReleaseFences(true); + gpu_thread.StopThread(); } /// Obtain the CPU Context @@ -348,18 +346,13 @@ struct GPU::Impl { s32 new_channel_id{1}; /// Shader build notifier std::unique_ptr shader_notify; - /// When true, we are about to shut down emulation session, so terminate outstanding tasks - std::atomic_bool shutting_down{}; std::array, Service::Nvidia::MaxSyncPoints> syncpoints{}; std::array, Service::Nvidia::MaxSyncPoints> syncpt_interrupts; - std::mutex sync_mutex; std::mutex device_mutex; - std::condition_variable sync_cv; - std::list> sync_requests; std::atomic current_sync_fence{}; u64 last_sync_fence{}; diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index e2bfdcd7fd..fef555b1df 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -54,8 +54,7 @@ static void RunThread(std::stop_token stop_token, Core::System& system, } state.signaled_fence.store(next.fence); if (next.block) { - // We have to lock the write_lock to ensure that the condition_variable wait not get a - // race between the check and the lock itself. + // We have to lock the write_lock to ensure that the waiting threads are notified. std::scoped_lock lk{state.write_lock}; state.cv.notify_all(); } @@ -75,6 +74,13 @@ void ThreadManager::StartThread(VideoCore::RendererBase& renderer, std::ref(scheduler), std::ref(state)); } +void ThreadManager::StopThread() { + if (thread.joinable()) { + thread.request_stop(); + thread.join(); + } +} + void ThreadManager::SubmitList(s32 channel, Tegra::CommandList&& entries) { PushCommand(SubmitListCommand(channel, std::move(entries))); } diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index dc0fce9f82..3ffa4ff438 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h @@ -107,6 +107,8 @@ public: void StartThread(VideoCore::RendererBase& renderer, Core::Frontend::GraphicsContext& context, Tegra::Control::Scheduler& scheduler); + void StopThread(); + /// Push GPU command entries to be processed void SubmitList(s32 channel, Tegra::CommandList&& entries); diff --git a/src/video_core/host1x/codecs/decoder.cpp b/src/video_core/host1x/codecs/decoder.cpp old mode 100755 new mode 100644 index 49a601969c..c3565011fb --- a/src/video_core/host1x/codecs/decoder.cpp +++ b/src/video_core/host1x/codecs/decoder.cpp @@ -11,8 +11,8 @@ namespace Tegra { Decoder::Decoder(Host1x::Host1x& host1x_, s32 id_, const Host1x::NvdecCommon::NvdecRegisters& regs_, Host1x::FrameQueue& frame_queue_) - : host1x(host1x_), memory_manager{host1x.GMMU()}, regs{regs_}, id{id_}, frame_queue{ - frame_queue_} {} + : host1x(host1x_), memory_manager{host1x.GMMU()}, regs{regs_}, id{id_}, + frame_queue{frame_queue_} {} Decoder::~Decoder() = default; @@ -41,7 +41,7 @@ void Decoder::Decode() { if (!frame.get()) { LOG_ERROR(HW_GPU, - "Nvdec {} dailed to decode interlaced frame for top 0x{:X} bottom 0x{:X}", id, + "Nvdec {} failed to decode interlaced frame for top 0x{:X} bottom 0x{:X}", id, luma_top, luma_bottom); } diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp index d6eff2bdd7..73497ca1c0 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp @@ -33,21 +33,39 @@ constexpr std::array PreferredGpuDecoders = { #elif defined(__FreeBSD__) AV_HWDEVICE_TYPE_VDPAU, #elif defined(__unix__) + AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VAAPI, + AV_HWDEVICE_TYPE_VDPAU, #endif AV_HWDEVICE_TYPE_VULKAN, }; AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) { + const auto desc = av_pix_fmt_desc_get(codec_context->pix_fmt); + if (desc && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + for (int i = 0;; i++) { + const AVCodecHWConfig* config = avcodec_get_hw_config(codec_context->codec, i); + if (!config) { + break; + } + + for (const auto type : PreferredGpuDecoders) { + if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && + config->device_type == type) { + codec_context->pix_fmt = config->pix_fmt; + } + } + } + } + for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) { if (*p == codec_context->pix_fmt) { return codec_context->pix_fmt; } } - LOG_INFO(HW_GPU, "Could not find compatible GPU AV format, falling back to CPU"); + LOG_INFO(HW_GPU, "Could not find supported GPU pixel format, falling back to CPU decoder"); av_buffer_unref(&codec_context->hw_device_ctx); - codec_context->pix_fmt = PreferredCpuFormat; return codec_context->pix_fmt; } @@ -100,10 +118,12 @@ bool Decoder::SupportsDecodingOnDevice(AVPixelFormat* out_pix_fmt, AVHWDeviceTyp for (int i = 0;; i++) { const AVCodecHWConfig* config = avcodec_get_hw_config(m_codec, i); if (!config) { - LOG_DEBUG(HW_GPU, "{} decoder does not support device type {}", m_codec->name, av_hwdevice_get_type_name(type)); + LOG_DEBUG(HW_GPU, "{} decoder does not support device type {}", m_codec->name, + av_hwdevice_get_type_name(type)); break; } - if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == type) { + if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && + config->device_type == type) { LOG_INFO(HW_GPU, "Using {} GPU decoder", av_hwdevice_get_type_name(type)); *out_pix_fmt = config->pix_fmt; return true; @@ -131,7 +151,8 @@ HardwareContext::~HardwareContext() { av_buffer_unref(&m_gpu_decoder); } -bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context, const Decoder& decoder) { +bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context, + const Decoder& decoder) { const auto supported_types = GetSupportedDeviceTypes(); for (const auto type : PreferredGpuDecoders) { AVPixelFormat hw_pix_fmt; @@ -157,8 +178,10 @@ bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context, cons bool HardwareContext::InitializeWithType(AVHWDeviceType type) { av_buffer_unref(&m_gpu_decoder); - if (const int ret = av_hwdevice_ctx_create(&m_gpu_decoder, type, nullptr, nullptr, 0); ret < 0) { - LOG_DEBUG(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type), AVError(ret)); + if (const int ret = av_hwdevice_ctx_create(&m_gpu_decoder, type, nullptr, nullptr, 0); + ret < 0) { + LOG_DEBUG(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type), + AVError(ret)); return false; } @@ -195,7 +218,8 @@ DecoderContext::~DecoderContext() { avcodec_free_context(&m_codec_context); } -void DecoderContext::InitializeHardwareDecoder(const HardwareContext& context, AVPixelFormat hw_pix_fmt) { +void DecoderContext::InitializeHardwareDecoder(const HardwareContext& context, + AVPixelFormat hw_pix_fmt) { m_codec_context->hw_device_ctx = av_buffer_ref(context.GetBufferRef()); m_codec_context->get_format = GetGpuFormat; m_codec_context->pix_fmt = hw_pix_fmt; @@ -215,8 +239,9 @@ bool DecoderContext::OpenContext(const Decoder& decoder) { } bool DecoderContext::SendPacket(const Packet& packet) { - m_temp_frame = std::make_shared(); - if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF) { + m_temp_frame = std::make_shared(); + if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); + ret < 0 && ret != AVERROR_EOF) { LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret)); return false; } @@ -224,31 +249,34 @@ bool DecoderContext::SendPacket(const Packet& packet) { } std::shared_ptr DecoderContext::ReceiveFrame() { - auto ReceiveImpl = [&](AVFrame* frame) -> bool { - if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0 && ret != AVERROR_EOF) { - LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret)); - return false; - } - return true; - }; + auto ReceiveImpl = [&](AVFrame* frame) -> bool { + if (const int ret = avcodec_receive_frame(m_codec_context, frame); + ret < 0 && ret != AVERROR_EOF) { + LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret)); + return false; + } + return true; + }; - std::shared_ptr intermediate_frame = std::make_shared(); - if (!ReceiveImpl(intermediate_frame->GetFrame())) { - return {}; - } + std::shared_ptr intermediate_frame = std::make_shared(); + if (!ReceiveImpl(intermediate_frame->GetFrame())) { + return {}; + } - const auto desc = av_pix_fmt_desc_get(intermediate_frame->GetPixelFormat()); - if (m_codec_context->hw_device_ctx && (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { - m_temp_frame->SetFormat(PreferredGpuFormat); - if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { - LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); - return {}; - } - } else { - m_temp_frame = std::move(intermediate_frame); - } + const auto desc = av_pix_fmt_desc_get(intermediate_frame->GetPixelFormat()); + if (m_codec_context->hw_device_ctx && (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + m_temp_frame->SetFormat(PreferredGpuFormat); + if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), + intermediate_frame->GetFrame(), 0); + ret < 0) { + LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); + return {}; + } + } else { + m_temp_frame = std::move(intermediate_frame); + } - return std::move(m_temp_frame); + return std::move(m_temp_frame); } void DecodeApi::Reset() { diff --git a/src/video_core/host1x/host1x.cpp b/src/video_core/host1x/host1x.cpp index 293bca6d79..7499ee77ec 100644 --- a/src/video_core/host1x/host1x.cpp +++ b/src/video_core/host1x/host1x.cpp @@ -9,8 +9,8 @@ namespace Tegra::Host1x { Host1x::Host1x(Core::System& system_) - : system{system_}, syncpoint_manager{}, - memory_manager(system.DeviceMemory()), gmmu_manager{system, memory_manager, 32, 0, 12}, + : system{system_}, syncpoint_manager{}, memory_manager(system.DeviceMemory()), + gmmu_manager{system, memory_manager, 32, 0, 12}, allocator{std::make_unique>(1 << 12)} {} Host1x::~Host1x() = default; diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp index 3ad56bb80c..2d06580609 100644 --- a/src/video_core/host1x/vic.cpp +++ b/src/video_core/host1x/vic.cpp @@ -94,8 +94,8 @@ void SwizzleSurface(std::span output, u32 out_stride, std::span in } // namespace Vic::Vic(Host1x& host1x_, s32 id_, u32 syncpt, FrameQueue& frame_queue_) - : CDmaPusher{host1x_, id_}, id{id_}, syncpoint{syncpt}, - frame_queue{frame_queue_}, has_sse41{HasSSE41()} { + : CDmaPusher{host1x_, id_}, id{id_}, syncpoint{syncpt}, frame_queue{frame_queue_}, + has_sse41{HasSSE41()} { LOG_INFO(HW_GPU, "Created vic {}", id); } diff --git a/src/video_core/host_shaders/convert_abgr8_srgb_to_d24s8.frag b/src/video_core/host_shaders/convert_abgr8_srgb_to_d24s8.frag index a9bd21192d..2e464fffa6 100644 --- a/src/video_core/host_shaders/convert_abgr8_srgb_to_d24s8.frag +++ b/src/video_core/host_shaders/convert_abgr8_srgb_to_d24s8.frag @@ -5,9 +5,10 @@ layout(binding = 0) uniform sampler2D color_texture; -// More accurate sRGB to linear conversion +// Even more accurate sRGB to linear conversion +// https://entropymine.com/imageworsener/srgbformula/ float srgbToLinear(float srgb) { - if (srgb <= 0.04045) { + if (srgb <= 0.0404482362771082f) { //assumes it's >= 0 return srgb / 12.92; } else { return pow((srgb + 0.055) / 1.055, 2.4); diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index ffafc48eff..aa60938119 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -28,8 +28,8 @@ MemoryManager::MemoryManager(Core::System& system_, MaxwellDeviceMemoryManager& split_address{split_address_}, page_bits{page_bits_}, big_page_bits{big_page_bits_}, entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38, page_bits != big_page_bits ? page_bits : 0}, - kind_map{PTEKind::INVALID}, unique_identifier{unique_identifier_generator.fetch_add( - 1, std::memory_order_acq_rel)}, + kind_map{PTEKind::INVALID}, + unique_identifier{unique_identifier_generator.fetch_add(1, std::memory_order_acq_rel)}, accumulator{std::make_unique()} { address_space_size = 1ULL << address_space_bits; page_size = 1ULL << page_bits; diff --git a/src/video_core/query_cache/query_cache.h b/src/video_core/query_cache/query_cache.h index 08b7790555..6e084cc079 100644 --- a/src/video_core/query_cache/query_cache.h +++ b/src/video_core/query_cache/query_cache.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -115,8 +118,8 @@ struct QueryCacheBase::QueryCacheBaseImpl { QueryCacheBaseImpl(QueryCacheBase* owner_, VideoCore::RasterizerInterface& rasterizer_, Tegra::MaxwellDeviceMemoryManager& device_memory_, RuntimeType& runtime_, Tegra::GPU& gpu_) - : owner{owner_}, rasterizer{rasterizer_}, - device_memory{device_memory_}, runtime{runtime_}, gpu{gpu_} { + : owner{owner_}, rasterizer{rasterizer_}, device_memory{device_memory_}, runtime{runtime_}, + gpu{gpu_} { streamer_mask = 0; for (size_t i = 0; i < static_cast(QueryType::MaxQueryTypes); i++) { streamers[i] = runtime.GetStreamerInterface(static_cast(i)); @@ -267,7 +270,11 @@ void QueryCacheBase::CounterReport(GPUVAddr addr, QueryType counter_type return; } if (False(query_base->flags & QueryFlagBits::IsFinalValueSynced)) [[unlikely]] { - ASSERT(false); + LOG_ERROR(HW_GPU, + "Query report value not synchronized. Consider increasing GPU accuracy."); + if (!is_synced) [[likely]] { + impl->pending_unregister.push_back(query_location); + } return; } query_base->value += streamer->GetAmendValue(); @@ -370,8 +377,6 @@ void QueryCacheBase::NotifySegment(bool resume) { if (resume) { impl->runtime.ResumeHostConditionalRendering(); } else { - CounterClose(VideoCommon::QueryType::ZPassPixelCount64); - CounterClose(VideoCommon::QueryType::StreamingByteCount); impl->runtime.PauseHostConditionalRendering(); } } diff --git a/src/video_core/query_cache/query_stream.h b/src/video_core/query_cache/query_stream.h index 1d11b12752..2437b66d63 100644 --- a/src/video_core/query_cache/query_stream.h +++ b/src/video_core/query_cache/query_stream.h @@ -133,7 +133,6 @@ protected: } void ReleaseQuery(size_t query_id) { - if (query_id < slot_queries.size()) { old_queries.push_back(query_id); return; diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index d705018607..bb974bfd2b 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp @@ -31,8 +31,8 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac BufferCache& buffer_cache_, ProgramManager& program_manager_, const Shader::Info& info_, std::string code, std::vector code_v, bool force_context_flush) - : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, - program_manager{program_manager_}, info{info_} { + : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_}, + info{info_} { switch (device.GetShaderBackend()) { case Settings::ShaderBackend::Glsl: source_program = CreateProgram(code, GL_COMPUTE_SHADER); diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp index 2147d587f7..ca00d7c3b7 100644 --- a/src/video_core/renderer_opengl/gl_query_cache.cpp +++ b/src/video_core/renderer_opengl/gl_query_cache.cpp @@ -66,9 +66,8 @@ bool QueryCache::AnyCommandQueued() const noexcept { HostCounter::HostCounter(QueryCache& cache_, std::shared_ptr dependency_, VideoCore::QueryType type_) - : HostCounterBase{std::move(dependency_)}, cache{cache_}, type{type_}, query{ - cache.AllocateQuery( - type)} { + : HostCounterBase{std::move(dependency_)}, cache{cache_}, type{type_}, + query{cache.AllocateQuery(type)} { glBeginQuery(GetTarget(type), query.handle); } diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index edf0bdd2f1..de923b3781 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -181,7 +181,8 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, state_tracker{state_tracker_}, shader_notify{shader_notify_}, use_asynchronous_shaders{device.UseAsynchronousShaders()}, strict_context_required{device.StrictContextRequired()}, - optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Never}, + optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != + Settings::SpirvOptimizeMode::Never}, profile{ .supported_spirv = 0x00010000, diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index f2bf5a3228..cf10bb795c 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -7,13 +7,22 @@ #include "common/settings.h" #include "video_core/host_shaders/blit_color_float_frag_spv.h" +#include "video_core/host_shaders/convert_abgr8_srgb_to_d24s8_frag_spv.h" #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" #include "video_core/host_shaders/convert_abgr8_to_d32f_frag_spv.h" +#include "video_core/host_shaders/convert_astc_hdr_to_rgba16f_comp_spv.h" +#include "video_core/host_shaders/convert_bc7_to_rgba8_comp_spv.h" #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_d32f_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" +#include "video_core/host_shaders/convert_rgb_to_yuv420_comp_spv.h" +#include "video_core/host_shaders/convert_rgba16f_to_rgba8_frag_spv.h" +#include "video_core/host_shaders/convert_rgba8_to_bgra8_frag_spv.h" #include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h" +#include "video_core/host_shaders/convert_yuv420_to_rgb_comp_spv.h" +#include "video_core/host_shaders/dither_temporal_frag_spv.h" +#include "video_core/host_shaders/dynamic_resolution_scale_comp_spv.h" #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" #include "video_core/host_shaders/vulkan_color_clear_frag_spv.h" @@ -28,15 +37,6 @@ #include "video_core/surface.h" #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -#include "video_core/host_shaders/convert_abgr8_srgb_to_d24s8_frag_spv.h" -#include "video_core/host_shaders/convert_rgba8_to_bgra8_frag_spv.h" -#include "video_core/host_shaders/convert_yuv420_to_rgb_comp_spv.h" -#include "video_core/host_shaders/convert_rgb_to_yuv420_comp_spv.h" -#include "video_core/host_shaders/convert_bc7_to_rgba8_comp_spv.h" -#include "video_core/host_shaders/convert_astc_hdr_to_rgba16f_comp_spv.h" -#include "video_core/host_shaders/convert_rgba16f_to_rgba8_frag_spv.h" -#include "video_core/host_shaders/dither_temporal_frag_spv.h" -#include "video_core/host_shaders/dynamic_resolution_scale_comp_spv.h" namespace Vulkan { @@ -190,24 +190,26 @@ constexpr VkPipelineDepthStencilStateCreateInfo PIPELINE_DEPTH_STENCIL_STATE_CRE .depthCompareOp = VK_COMPARE_OP_ALWAYS, .depthBoundsTestEnable = VK_FALSE, .stencilTestEnable = VK_TRUE, - .front = VkStencilOpState{ - .failOp = VK_STENCIL_OP_REPLACE, - .passOp = VK_STENCIL_OP_REPLACE, - .depthFailOp = VK_STENCIL_OP_KEEP, - .compareOp = VK_COMPARE_OP_ALWAYS, - .compareMask = 0x0, - .writeMask = 0xFFFFFFFF, - .reference = 0x00, - }, - .back = VkStencilOpState{ - .failOp = VK_STENCIL_OP_REPLACE, - .passOp = VK_STENCIL_OP_REPLACE, - .depthFailOp = VK_STENCIL_OP_KEEP, - .compareOp = VK_COMPARE_OP_ALWAYS, - .compareMask = 0x0, - .writeMask = 0xFFFFFFFF, - .reference = 0x00, - }, + .front = + VkStencilOpState{ + .failOp = VK_STENCIL_OP_REPLACE, + .passOp = VK_STENCIL_OP_REPLACE, + .depthFailOp = VK_STENCIL_OP_KEEP, + .compareOp = VK_COMPARE_OP_ALWAYS, + .compareMask = 0x0, + .writeMask = 0xFFFFFFFF, + .reference = 0x00, + }, + .back = + VkStencilOpState{ + .failOp = VK_STENCIL_OP_REPLACE, + .passOp = VK_STENCIL_OP_REPLACE, + .depthFailOp = VK_STENCIL_OP_KEEP, + .compareOp = VK_COMPARE_OP_ALWAYS, + .compareMask = 0x0, + .writeMask = 0xFFFFFFFF, + .reference = 0x00, + }, .minDepthBounds = 0.0f, .maxDepthBounds = 0.0f, }; @@ -624,10 +626,9 @@ void BlitImageHelper::ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, } void BlitImageHelper::ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { + const ImageView& src_image_view) { ConvertPipelineDepthTargetEx(convert_abgr8_srgb_to_d24s8_pipeline, - dst_framebuffer->RenderPass(), - convert_abgr8_srgb_to_d24s8_frag); + dst_framebuffer->RenderPass(), convert_abgr8_srgb_to_d24s8_frag); Convert(*convert_abgr8_srgb_to_d24s8_pipeline, dst_framebuffer, src_image_view); } @@ -1060,7 +1061,7 @@ void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRen } void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, - bool is_target_depth) { + bool is_target_depth) { if (pipeline) { return; } @@ -1081,7 +1082,7 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass rende .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr, .pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO - : &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, + : &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, .layout = *one_texture_pipeline_layout, .renderPass = renderpass, @@ -1092,66 +1093,50 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass rende } void BlitImageHelper::ConvertRGBAtoGBRA(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(convert_rgba_to_bgra_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(convert_rgba_to_bgra_pipeline, dst_framebuffer->RenderPass(), false); Convert(*convert_rgba_to_bgra_pipeline, dst_framebuffer, src_image_view); } void BlitImageHelper::ConvertYUV420toRGB(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(convert_yuv420_to_rgb_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(convert_yuv420_to_rgb_pipeline, dst_framebuffer->RenderPass(), false); Convert(*convert_yuv420_to_rgb_pipeline, dst_framebuffer, src_image_view); } void BlitImageHelper::ConvertRGBtoYUV420(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(convert_rgb_to_yuv420_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(convert_rgb_to_yuv420_pipeline, dst_framebuffer->RenderPass(), false); Convert(*convert_rgb_to_yuv420_pipeline, dst_framebuffer, src_image_view); } void BlitImageHelper::ConvertBC7toRGBA8(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(convert_bc7_to_rgba8_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(convert_bc7_to_rgba8_pipeline, dst_framebuffer->RenderPass(), false); Convert(*convert_bc7_to_rgba8_pipeline, dst_framebuffer, src_image_view); } void BlitImageHelper::ConvertASTCHDRtoRGBA16F(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(convert_astc_hdr_to_rgba16f_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(convert_astc_hdr_to_rgba16f_pipeline, dst_framebuffer->RenderPass(), false); Convert(*convert_astc_hdr_to_rgba16f_pipeline, dst_framebuffer, src_image_view); } void BlitImageHelper::ConvertRGBA16FtoRGBA8(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(convert_rgba16f_to_rgba8_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(convert_rgba16f_to_rgba8_pipeline, dst_framebuffer->RenderPass(), false); Convert(*convert_rgba16f_to_rgba8_pipeline, dst_framebuffer, src_image_view); } void BlitImageHelper::ApplyDitherTemporal(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(dither_temporal_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(dither_temporal_pipeline, dst_framebuffer->RenderPass(), false); Convert(*dither_temporal_pipeline, dst_framebuffer, src_image_view); } void BlitImageHelper::ApplyDynamicResolutionScale(const Framebuffer* dst_framebuffer, - const ImageView& src_image_view) { - ConvertPipeline(dynamic_resolution_scale_pipeline, - dst_framebuffer->RenderPass(), - false); + const ImageView& src_image_view) { + ConvertPipeline(dynamic_resolution_scale_pipeline, dst_framebuffer->RenderPass(), false); Convert(*dynamic_resolution_scale_pipeline, dst_framebuffer, src_image_view); } diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 3d400be6a9..de3d53e00b 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h @@ -67,7 +67,8 @@ public: void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); - void ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view); void ConvertABGR8ToD32F(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); @@ -88,10 +89,12 @@ public: void ConvertYUV420toRGB(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); void ConvertRGBtoYUV420(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); void ConvertBC7toRGBA8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); - void ConvertASTCHDRtoRGBA16F(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ConvertASTCHDRtoRGBA16F(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view); void ConvertRGBA16FtoRGBA8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); void ApplyDitherTemporal(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); - void ApplyDynamicResolutionScale(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ApplyDynamicResolutionScale(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view); private: void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 133ab01701..39f4fc6993 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp @@ -86,6 +86,12 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0); app_stage.Assign(maxwell3d.engine_state); + depth_bounds_min = static_cast(regs.depth_bounds[0]); + depth_bounds_max = static_cast(regs.depth_bounds[1]); + + line_stipple_factor = regs.line_stipple_params.factor; + line_stipple_pattern = regs.line_stipple_params.pattern; + for (size_t i = 0; i < regs.rt.size(); ++i) { color_formats[i] = static_cast(regs.rt[i].format); } @@ -258,6 +264,8 @@ void FixedPipelineState::DynamicState::Refresh3(const Maxwell& regs) { Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ || regs.viewport_clip_control.geometry_clip == Maxwell::ViewportClipControl::GeometryClip::FrustumZ); + + line_stipple_enable.Assign(regs.line_stipple_enable); } size_t FixedPipelineState::Hash() const noexcept { diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index dfe6d80323..f0b021ca08 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h @@ -150,6 +150,7 @@ struct FixedPipelineState { BitField<6, 4, u32> logic_op; BitField<10, 1, u32> logic_op_enable; BitField<11, 1, u32> depth_clamp_disabled; + BitField<12, 1, u32> line_stipple_enable; }; union { u32 raw2; @@ -218,6 +219,7 @@ struct FixedPipelineState { u32 alpha_test_ref; u32 point_size; + std::array viewport_swizzles; union { u64 attribute_types; // Used with VK_EXT_vertex_input_dynamic_state @@ -233,6 +235,12 @@ struct FixedPipelineState { VideoCommon::TransformFeedbackState xfb_state; + u32 depth_bounds_min; + u32 depth_bounds_max; + + u32 line_stipple_factor; + u32 line_stipple_pattern; + void Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features); size_t Hash() const noexcept; diff --git a/src/video_core/renderer_vulkan/present/filters.cpp b/src/video_core/renderer_vulkan/present/filters.cpp index e5365acde9..7843f38d2c 100644 --- a/src/video_core/renderer_vulkan/present/filters.cpp +++ b/src/video_core/renderer_vulkan/present/filters.cpp @@ -46,8 +46,12 @@ std::unique_ptr MakeBilinear(const Device& device, VkFormat fra } std::unique_ptr MakeBicubic(const Device& device, VkFormat frame_format) { + // No need for handrolled shader -- if the VK impl can do it for us ;) + if (device.IsExtFilterCubicSupported()) + return std::make_unique(device, frame_format, CreateCubicSampler(device), + BuildShader(device, VULKAN_PRESENT_FRAG_SPV)); return std::make_unique(device, frame_format, CreateBilinearSampler(device), - BuildShader(device, PRESENT_BICUBIC_FRAG_SPV)); + BuildShader(device, PRESENT_BICUBIC_FRAG_SPV)); } std::unique_ptr MakeGaussian(const Device& device, VkFormat frame_format) { diff --git a/src/video_core/renderer_vulkan/present/fsr.cpp b/src/video_core/renderer_vulkan/present/fsr.cpp index 3f708be704..55606deb83 100644 --- a/src/video_core/renderer_vulkan/present/fsr.cpp +++ b/src/video_core/renderer_vulkan/present/fsr.cpp @@ -24,8 +24,8 @@ using PushConstants = std::array; FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, VkExtent2D extent) - : m_device{device}, m_memory_allocator{memory_allocator}, - m_image_count{image_count}, m_extent{extent} { + : m_device{device}, m_memory_allocator{memory_allocator}, m_image_count{image_count}, + m_extent{extent} { CreateImages(); CreateRenderPasses(); diff --git a/src/video_core/renderer_vulkan/present/util.cpp b/src/video_core/renderer_vulkan/present/util.cpp index 7f27c7c1b5..6874bbae99 100644 --- a/src/video_core/renderer_vulkan/present/util.cpp +++ b/src/video_core/renderer_vulkan/present/util.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -621,6 +624,31 @@ vk::Sampler CreateNearestNeighborSampler(const Device& device) { return device.GetLogical().CreateSampler(ci_nn); } +vk::Sampler CreateCubicSampler(const Device& device) { + const VkSamplerCreateInfo ci_nn{ + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .magFilter = VK_FILTER_CUBIC_EXT, + .minFilter = VK_FILTER_CUBIC_EXT, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + .mipLodBias = 0.0f, + .anisotropyEnable = VK_FALSE, + .maxAnisotropy = 0.0f, + .compareEnable = VK_FALSE, + .compareOp = VK_COMPARE_OP_NEVER, + .minLod = 0.0f, + .maxLod = 0.0f, + .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + .unnormalizedCoordinates = VK_FALSE, + }; + + return device.GetLogical().CreateSampler(ci_nn); +} + void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image) { static constexpr std::array subresources{{{ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, diff --git a/src/video_core/renderer_vulkan/present/util.h b/src/video_core/renderer_vulkan/present/util.h index 5b22f0fa82..11810352df 100644 --- a/src/video_core/renderer_vulkan/present/util.h +++ b/src/video_core/renderer_vulkan/present/util.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -54,6 +57,7 @@ VkWriteDescriptorSet CreateWriteDescriptorSet(std::vector VkDescriptorSet set, u32 binding); vk::Sampler CreateBilinearSampler(const Device& device); vk::Sampler CreateNearestNeighborSampler(const Device& device); +vk::Sampler CreateCubicSampler(const Device& device); void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index a91fba6725..4c8c3aa34f 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -102,73 +102,46 @@ Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dl } RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& emu_window, - Tegra::MaxwellDeviceMemoryManager& device_memory_, - Tegra::GPU& gpu_, - std::unique_ptr context_) -try - : RendererBase(emu_window, std::move(context_)) - , device_memory(device_memory_) - , gpu(gpu_) - , library(OpenLibrary(context.get())) - , dld() - // Create raw Vulkan instance first - , instance(CreateInstance(*library, - dld, - VK_API_VERSION_1_1, - render_window.GetWindowInfo().type, - Settings::values.renderer_debug.GetValue())) - // Create debug messenger if debug is enabled - , debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance) - : vk::DebugUtilsMessenger{}) - // Create surface - , surface(CreateSurface(instance, render_window.GetWindowInfo())) - , device(CreateDevice(instance, dld, *surface)) - , memory_allocator(device) - , state_tracker() - , scheduler(device, state_tracker) - , swapchain(*surface, - device, - scheduler, - render_window.GetFramebufferLayout().width, - render_window.GetFramebufferLayout().height) - , present_manager(instance, - render_window, - device, - memory_allocator, - scheduler, - swapchain, + Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_, + std::unique_ptr context_) try + : RendererBase(emu_window, std::move(context_)), device_memory(device_memory_), gpu(gpu_), + library(OpenLibrary(context.get())), dld() + // Create raw Vulkan instance first + , + instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, + Settings::values.renderer_debug.GetValue())) + // Create debug messenger if debug is enabled + , + debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance) + : vk::DebugUtilsMessenger{}) + // Create surface + , + surface(CreateSurface(instance, render_window.GetWindowInfo())), + device(CreateDevice(instance, dld, *surface)), memory_allocator(device), state_tracker(), + scheduler(device, state_tracker), + swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, + render_window.GetFramebufferLayout().height), + present_manager(instance, render_window, device, memory_allocator, scheduler, swapchain, #ifdef ANDROID - surface) - , + surface), #else - *surface) - , + *surface), #endif - blit_swapchain(device_memory, - device, - memory_allocator, - present_manager, - scheduler, - PresentFiltersForDisplay) - , blit_capture(device_memory, - device, - memory_allocator, - present_manager, - scheduler, - PresentFiltersForDisplay) - , blit_applet(device_memory, - device, - memory_allocator, - present_manager, - scheduler, - PresentFiltersForAppletCapture) - , rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, scheduler) { + blit_swapchain(device_memory, device, memory_allocator, present_manager, scheduler, + PresentFiltersForDisplay), + blit_capture(device_memory, device, memory_allocator, present_manager, scheduler, + PresentFiltersForDisplay), + blit_applet(device_memory, device, memory_allocator, present_manager, scheduler, + PresentFiltersForAppletCapture), + rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, + scheduler) { // Initialize RAII wrappers after creating the main objects if (Settings::values.enable_raii.GetValue()) { managed_instance = MakeManagedInstance(instance, dld); if (Settings::values.renderer_debug) { - managed_debug_messenger = MakeManagedDebugUtilsMessenger(debug_messenger, instance, dld); + managed_debug_messenger = + MakeManagedDebugUtilsMessenger(debug_messenger, instance, dld); } managed_surface = MakeManagedSurface(surface, instance, dld); } @@ -191,124 +164,118 @@ RendererVulkan::~RendererVulkan() { #ifdef __ANDROID__ class BooleanSetting { - public: -// static BooleanSetting FRAME_SKIPPING; - static BooleanSetting FRAME_INTERPOLATION; - explicit BooleanSetting(bool initial_value = false) : value(initial_value) {} +public: + // static BooleanSetting FRAME_SKIPPING; + static BooleanSetting FRAME_INTERPOLATION; + explicit BooleanSetting(bool initial_value = false) : value(initial_value) {} - [[nodiscard]] bool getBoolean() const { - return value; - } + [[nodiscard]] bool getBoolean() const { + return value; + } - void setBoolean(bool new_value) { - value = new_value; - } + void setBoolean(bool new_value) { + value = new_value; + } - private: - bool value; - }; +private: + bool value; +}; - // Initialize static members +// Initialize static members // BooleanSetting BooleanSetting::FRAME_SKIPPING(false); - BooleanSetting BooleanSetting::FRAME_INTERPOLATION(false); +BooleanSetting BooleanSetting::FRAME_INTERPOLATION(false); // extern "C" JNIEXPORT jboolean JNICALL -// Java_org_yuzu_yuzu_1emu_features_settings_model_BooleanSetting_isFrameSkippingEnabled(JNIEnv* env, jobject /* this */) { +// Java_org_yuzu_yuzu_1emu_features_settings_model_BooleanSetting_isFrameSkippingEnabled(JNIEnv* +// env, jobject /* this */) { // return static_cast(BooleanSetting::FRAME_SKIPPING.getBoolean()); // } - extern "C" JNIEXPORT jboolean JNICALL - Java_org_yuzu_yuzu_1emu_features_settings_model_BooleanSetting_isFrameInterpolationEnabled(JNIEnv* env, jobject /* this */) { - return static_cast(BooleanSetting::FRAME_INTERPOLATION.getBoolean()); +extern "C" JNIEXPORT jboolean JNICALL +Java_org_yuzu_yuzu_1emu_features_settings_model_BooleanSetting_isFrameInterpolationEnabled( + JNIEnv* env, jobject /* this */) { + return static_cast(BooleanSetting::FRAME_INTERPOLATION.getBoolean()); +} + +void RendererVulkan::InterpolateFrames(Frame* prev_frame, Frame* interpolated_frame) { + if (!prev_frame || !interpolated_frame || !prev_frame->image || !interpolated_frame->image) { + return; } - void RendererVulkan::InterpolateFrames(Frame* prev_frame, Frame* interpolated_frame) { - if (!prev_frame || !interpolated_frame || !prev_frame->image || !interpolated_frame->image) { - return; - } + const auto& framebuffer_layout = render_window.GetFramebufferLayout(); + // Fixed aggressive downscale (50%) + VkExtent2D dst_extent{.width = framebuffer_layout.width / 2, + .height = framebuffer_layout.height / 2}; - const auto& framebuffer_layout = render_window.GetFramebufferLayout(); - // Fixed aggressive downscale (50%) - VkExtent2D dst_extent{ - .width = framebuffer_layout.width / 2, - .height = framebuffer_layout.height / 2 - }; - - // Check if we need to recreate the destination frame - bool needs_recreation = false; // Only recreate when necessary - if (!interpolated_frame->image_view) { - needs_recreation = true; // Need to create initially + // Check if we need to recreate the destination frame + bool needs_recreation = false; // Only recreate when necessary + if (!interpolated_frame->image_view) { + needs_recreation = true; // Need to create initially + } else { + // Check if dimensions have changed + if (interpolated_frame->framebuffer) { + needs_recreation = (framebuffer_layout.width / 2 != dst_extent.width) || + (framebuffer_layout.height / 2 != dst_extent.height); } else { - // Check if dimensions have changed - if (interpolated_frame->framebuffer) { - needs_recreation = (framebuffer_layout.width / 2 != dst_extent.width) || - (framebuffer_layout.height / 2 != dst_extent.height); - } else { - needs_recreation = true; - } + needs_recreation = true; } - - if (needs_recreation) { - interpolated_frame->image = CreateWrappedImage(memory_allocator, dst_extent, swapchain.GetImageViewFormat()); - interpolated_frame->image_view = CreateWrappedImageView(device, interpolated_frame->image, swapchain.GetImageViewFormat()); - interpolated_frame->framebuffer = blit_swapchain.CreateFramebuffer( - Layout::FramebufferLayout{dst_extent.width, dst_extent.height}, - *interpolated_frame->image_view, - swapchain.GetImageViewFormat()); - } - - scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([&](vk::CommandBuffer cmdbuf) { - // Transition images to transfer layouts - TransitionImageLayout(cmdbuf, *prev_frame->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - TransitionImageLayout(cmdbuf, *interpolated_frame->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - // Perform the downscale blit - VkImageBlit blit_region{}; - blit_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; - blit_region.srcOffsets[0] = {0, 0, 0}; - blit_region.srcOffsets[1] = { - static_cast(framebuffer_layout.width), - static_cast(framebuffer_layout.height), - 1 - }; - blit_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; - blit_region.dstOffsets[0] = {0, 0, 0}; - blit_region.dstOffsets[1] = { - static_cast(dst_extent.width), - static_cast(dst_extent.height), - 1 - }; - - // Using the wrapper's BlitImage with proper parameters - cmdbuf.BlitImage( - *prev_frame->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - *interpolated_frame->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - blit_region, VK_FILTER_NEAREST - ); - - // Transition back to general layout - TransitionImageLayout(cmdbuf, *prev_frame->image, VK_IMAGE_LAYOUT_GENERAL); - TransitionImageLayout(cmdbuf, *interpolated_frame->image, VK_IMAGE_LAYOUT_GENERAL); - }); } + + if (needs_recreation) { + interpolated_frame->image = + CreateWrappedImage(memory_allocator, dst_extent, swapchain.GetImageViewFormat()); + interpolated_frame->image_view = CreateWrappedImageView(device, interpolated_frame->image, + swapchain.GetImageViewFormat()); + interpolated_frame->framebuffer = blit_swapchain.CreateFramebuffer( + Layout::FramebufferLayout{dst_extent.width, dst_extent.height}, + *interpolated_frame->image_view, swapchain.GetImageViewFormat()); + } + + scheduler.RequestOutsideRenderPassOperationContext(); + scheduler.Record([&](vk::CommandBuffer cmdbuf) { + // Transition images to transfer layouts + TransitionImageLayout(cmdbuf, *prev_frame->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + TransitionImageLayout(cmdbuf, *interpolated_frame->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + // Perform the downscale blit + VkImageBlit blit_region{}; + blit_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; + blit_region.srcOffsets[0] = {0, 0, 0}; + blit_region.srcOffsets[1] = {static_cast(framebuffer_layout.width), + static_cast(framebuffer_layout.height), 1}; + blit_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; + blit_region.dstOffsets[0] = {0, 0, 0}; + blit_region.dstOffsets[1] = {static_cast(dst_extent.width), + static_cast(dst_extent.height), 1}; + + // Using the wrapper's BlitImage with proper parameters + cmdbuf.BlitImage(*prev_frame->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *interpolated_frame->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + blit_region, VK_FILTER_NEAREST); + + // Transition back to general layout + TransitionImageLayout(cmdbuf, *prev_frame->image, VK_IMAGE_LAYOUT_GENERAL); + TransitionImageLayout(cmdbuf, *interpolated_frame->image, VK_IMAGE_LAYOUT_GENERAL); + }); +} #endif void RendererVulkan::Composite(std::span framebuffers) { - #ifdef __ANDROID__ +#ifdef __ANDROID__ static int frame_counter = 0; static int target_fps = 60; // Target FPS (30 or 60) int frame_skip_threshold = 1; - bool frame_skipping = false; //BooleanSetting::FRAME_SKIPPING.getBoolean(); + bool frame_skipping = false; // BooleanSetting::FRAME_SKIPPING.getBoolean(); bool frame_interpolation = BooleanSetting::FRAME_INTERPOLATION.getBoolean(); - #endif +#endif if (framebuffers.empty()) { return; } - #ifdef __ANDROID__ +#ifdef __ANDROID__ if (frame_skipping) { frame_skip_threshold = (target_fps == 30) ? 2 : 2; } @@ -319,14 +286,14 @@ void RendererVulkan::Composite(std::span framebu Frame* interpolated_frame = present_manager.GetRenderFrame(); InterpolateFrames(previous_frame, interpolated_frame); blit_swapchain.DrawToFrame(rasterizer, interpolated_frame, framebuffers, - render_window.GetFramebufferLayout(), swapchain.GetImageCount(), - swapchain.GetImageViewFormat()); + render_window.GetFramebufferLayout(), + swapchain.GetImageCount(), swapchain.GetImageViewFormat()); scheduler.Flush(*interpolated_frame->render_ready); present_manager.Present(interpolated_frame); } return; } - #endif +#endif SCOPE_EXIT { render_window.OnFrameDisplayed(); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index c1e6d5db7f..c2e1700417 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -19,8 +19,8 @@ #include "video_core/renderer_vulkan/vk_turbo_mode.h" #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_memory_allocator.h" -#include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/vulkan_common/vulkan_raii.h" +#include "video_core/vulkan_common/vulkan_wrapper.h" namespace Core::Memory { class Memory; @@ -59,7 +59,7 @@ public: private: void InterpolateFrames(Frame* prev_frame, Frame* curr_frame); - Frame* previous_frame = nullptr; // Store the previous frame for interpolation + Frame* previous_frame = nullptr; // Store the previous frame for interpolation VkCommandBuffer BeginSingleTimeCommands(); void EndSingleTimeCommands(VkCommandBuffer command_buffer); void Report() const; diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 617f92910c..6455e5eb75 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -531,8 +531,8 @@ ASTCDecoderPass::ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, COMPUTE_PUSH_CONSTANT_RANGE, ASTC_DECODER_COMP_SPV), scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, - compute_pass_descriptor_queue{compute_pass_descriptor_queue_}, memory_allocator{ - memory_allocator_} {} + compute_pass_descriptor_queue{compute_pass_descriptor_queue_}, + memory_allocator{memory_allocator_} {} ASTCDecoderPass::~ASTCDecoderPass() = default; diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 73e585c2b7..689c7d760c 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -31,8 +31,8 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel PipelineStatistics* pipeline_statistics, VideoCore::ShaderNotify* shader_notify, const Shader::Info& info_, vk::ShaderModule spv_module_) - : device{device_}, - pipeline_cache(pipeline_cache_), guest_descriptor_queue{guest_descriptor_queue_}, info{info_}, + : device{device_}, pipeline_cache(pipeline_cache_), + guest_descriptor_queue{guest_descriptor_queue_}, info{info_}, spv_module(std::move(spv_module_)) { if (shader_notify) { shader_notify->MarkShaderBuilding(); diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp index fad9e38324..545b852030 100644 --- a/src/video_core/renderer_vulkan/vk_fence_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp @@ -22,8 +22,7 @@ void InnerFence::Queue() { return; } // Get the current tick so we can wait for it - wait_tick = scheduler.CurrentTick(); - scheduler.Flush(); + wait_tick = scheduler.Flush(); } bool InnerFence::IsSignaled() const { diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index eb757d68f5..7e13200437 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -324,9 +324,8 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) { size_t ssbo_index{}; for (const auto& desc : info.storage_buffers_descriptors) { ASSERT(desc.count == 1); - if (!buffer_cache.BindGraphicsStorageBuffer(stage, ssbo_index, desc.cbuf_index, - desc.cbuf_offset, desc.is_written)) - return false; + buffer_cache.BindGraphicsStorageBuffer(stage, ssbo_index, desc.cbuf_index, + desc.cbuf_offset, desc.is_written); ++ssbo_index; } } @@ -355,11 +354,7 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) { const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE { for (u32 index = 0; index < desc.count; ++index) { const auto handle{read_handle(desc, index)}; - views[view_index++] = { - .index = handle.first, - .blacklist = blacklist, - .id = {} - }; + views[view_index++] = {.index = handle.first, .blacklist = blacklist, .id = {}}; } }}; if constexpr (Spec::has_texture_buffers) { @@ -638,14 +633,14 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .flags = 0, .topology = input_assembly_topology, .primitiveRestartEnable = - dynamic.primitive_restart_enable != 0 && - ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && - device.IsTopologyListPrimitiveRestartSupported()) || - SupportsPrimitiveRestart(input_assembly_topology) || - (input_assembly_topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && - device.IsPatchListPrimitiveRestartSupported())) - ? VK_TRUE - : VK_FALSE, + dynamic.primitive_restart_enable != 0 && + ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && + device.IsTopologyListPrimitiveRestartSupported()) || + SupportsPrimitiveRestart(input_assembly_topology) || + (input_assembly_topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && + device.IsPatchListPrimitiveRestartSupported())) + ? VK_TRUE + : VK_FALSE, }; const VkPipelineTessellationStateCreateInfo tessellation_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, @@ -688,11 +683,11 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .pNext = nullptr, .flags = 0, .depthClampEnable = - static_cast(dynamic.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE), + static_cast(dynamic.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE), .rasterizerDiscardEnable = - static_cast(dynamic.rasterize_enable == 0 ? VK_TRUE : VK_FALSE), + static_cast(dynamic.rasterize_enable == 0 ? VK_TRUE : VK_FALSE), .polygonMode = - MaxwellToVK::PolygonMode(FixedPipelineState::UnpackPolygonMode(key.state.polygon_mode)), + MaxwellToVK::PolygonMode(FixedPipelineState::UnpackPolygonMode(key.state.polygon_mode)), .cullMode = static_cast( dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE), .frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace()), @@ -701,6 +696,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .depthBiasClamp = 0.0f, .depthBiasSlopeFactor = 0.0f, .lineWidth = 1.0f, + // TODO(alekpop): Transfer from regs }; VkPipelineRasterizationLineStateCreateInfoEXT line_state{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, @@ -708,9 +704,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .lineRasterizationMode = key.state.smooth_lines != 0 ? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT : VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, - .stippledLineEnable = VK_FALSE, // TODO - .lineStippleFactor = 0, - .lineStipplePattern = 0, + .stippledLineEnable = dynamic.line_stipple_enable ? VK_TRUE : VK_FALSE, + .lineStippleFactor = key.state.line_stipple_factor, + .lineStipplePattern = static_cast(key.state.line_stipple_pattern), }; VkPipelineRasterizationConservativeStateCreateInfoEXT conservative_raster{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, @@ -763,8 +759,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .stencilTestEnable = dynamic.stencil_enable, .front = GetStencilFaceState(dynamic.front), .back = GetStencilFaceState(dynamic.back), - .minDepthBounds = 0.0f, - .maxDepthBounds = 0.0f, + .minDepthBounds = static_cast(key.state.depth_bounds_min), + .maxDepthBounds = static_cast(key.state.depth_bounds_max), }; if (dynamic.depth_bounds_enable && !device.IsDepthBoundsSupported()) { LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); @@ -803,20 +799,20 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .logicOp = static_cast(dynamic.logic_op.Value()), .attachmentCount = static_cast(cb_attachments.size()), .pAttachments = cb_attachments.data(), - .blendConstants = {} - }; - static_vector dynamic_states{ + .blendConstants = {}}; + static_vector dynamic_states{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_LINE_STIPPLE, + VK_DYNAMIC_STATE_LINE_WIDTH, }; if (key.state.extended_dynamic_state) { static constexpr std::array extended{ VK_DYNAMIC_STATE_CULL_MODE_EXT, VK_DYNAMIC_STATE_FRONT_FACE_EXT, - //VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT, //Disabled for VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME + // VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT, + // Disabled for VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT, @@ -841,8 +837,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { } if (key.state.extended_dynamic_state_3_blend) { static constexpr std::array extended3{ - VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT, - VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, + VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT, VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT, // VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT, @@ -855,9 +850,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT, // additional state3 extensions - - // FIXME(crueter): conservative rasterization is totally broken - // VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT, VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT, VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT, @@ -865,7 +857,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT, VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT, VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT, - VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT, VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT, VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT, }; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 7e9dbb583a..ae35381b86 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -108,7 +108,9 @@ public: template static auto MakeConfigureSpecFunc() { - return [](GraphicsPipeline* pl, bool is_indexed) { return pl->ConfigureImpl(is_indexed); }; + return [](GraphicsPipeline* pl, bool is_indexed) { + return pl->ConfigureImpl(is_indexed); + }; } void SetEngine(Tegra::Engines::Maxwell3D* maxwell3d_, Tegra::MemoryManager* gpu_memory_) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 66835fc1c7..aa2e4aebbd 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -57,7 +57,7 @@ using VideoCommon::FileEnvironment; using VideoCommon::GenericEnvironment; using VideoCommon::GraphicsEnvironment; -constexpr u32 CACHE_VERSION = 11; +constexpr u32 CACHE_VERSION = 12; constexpr std::array VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'}; template @@ -314,7 +314,8 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, texture_cache{texture_cache_}, shader_notify{shader_notify_}, use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()}, use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()}, - optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Never}, + optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != + Settings::SpirvOptimizeMode::Never}, workers(device.HasBrokenParallelShaderCompiling() ? 1ULL : GetTotalPipelineWorkers(), "VkPipelineBuilder"), serialization_thread(1, "VkPipelineSerialization") { @@ -408,25 +409,26 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, const u8 dynamic_state = Settings::values.dyna_state.GetValue(); - LOG_INFO(Render_Vulkan, "DynamicState value is set to {}", (u32) dynamic_state); + LOG_INFO(Render_Vulkan, "DynamicState value is set to {}", (u32)dynamic_state); dynamic_features = DynamicFeatures{ - .has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported() - && dynamic_state > 0, - .has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported() - && dynamic_state > 1, - .has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported() - && dynamic_state > 1, - .has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported() - && dynamic_state > 2, - .has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported() - && dynamic_state > 2, + .has_extended_dynamic_state = + device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0, + .has_extended_dynamic_state_2 = + device.IsExtExtendedDynamicState2Supported() && dynamic_state > 1, + .has_extended_dynamic_state_2_extra = + device.IsExtExtendedDynamicState2ExtrasSupported() && dynamic_state > 1, + .has_extended_dynamic_state_3_blend = + device.IsExtExtendedDynamicState3BlendingSupported() && dynamic_state > 2, + .has_extended_dynamic_state_3_enables = + device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state > 2, .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(), }; LOG_INFO(Render_Vulkan, "DynamicState1: {}", dynamic_features.has_extended_dynamic_state); LOG_INFO(Render_Vulkan, "DynamicState2: {}", dynamic_features.has_extended_dynamic_state_2); - LOG_INFO(Render_Vulkan, "DynamicState3: {}", dynamic_features.has_extended_dynamic_state_3_enables); + LOG_INFO(Render_Vulkan, "DynamicState3: {}", + dynamic_features.has_extended_dynamic_state_3_enables); LOG_INFO(Render_Vulkan, "DynamicVertexInput: {}", dynamic_features.has_dynamic_vertex_input); } @@ -696,7 +698,8 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline( const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage)}; ConvertLegacyToGeneric(program, runtime_info); - const std::vector code{EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output)}; + const std::vector code{ + EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output)}; device.SaveShader(code); modules[stage_index] = BuildShader(device, code); if (device.HasDebuggingToolAttached()) { diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index a448dc5288..3cd875d248 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -96,30 +96,26 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice& physical_device, VkFormat form } // Anonymous namespace PresentManager::PresentManager(const vk::Instance& instance_, - Core::Frontend::EmuWindow& render_window_, - const Device& device_, - MemoryAllocator& memory_allocator_, - Scheduler& scheduler_, + Core::Frontend::EmuWindow& render_window_, const Device& device_, + MemoryAllocator& memory_allocator_, Scheduler& scheduler_, Swapchain& swapchain_, #ifdef ANDROID vk::SurfaceKHR& surface_) #else VkSurfaceKHR_T* surface_handle_) #endif - : instance{instance_} - , render_window{render_window_} - , device{device_} - , memory_allocator{memory_allocator_} - , scheduler{scheduler_} - , swapchain{swapchain_} + : instance{instance_}, render_window{render_window_}, device{device_}, + memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_} #ifdef ANDROID - , surface{surface_} + , + surface{surface_} #else - , surface_handle{surface_handle_} + , + surface_handle{surface_handle_} #endif - , blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())} - , use_present_thread{Settings::values.async_presentation.GetValue()} -{ + , + blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())}, + use_present_thread{Settings::values.async_presentation.GetValue()} { SetImageCount(); auto& dld = device.GetLogical(); diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h index 5820280602..b62c38cf38 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.h +++ b/src/video_core/renderer_vulkan/vk_present_manager.h @@ -37,11 +37,8 @@ struct Frame { class PresentManager { public: - PresentManager(const vk::Instance& instance, - Core::Frontend::EmuWindow& render_window, - const Device& device, - MemoryAllocator& memory_allocator, - Scheduler& scheduler, + PresentManager(const vk::Instance& instance, Core::Frontend::EmuWindow& render_window, + const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler, Swapchain& swapchain, #ifdef ANDROID vk::SurfaceKHR& surface); diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 44c06eddf3..1f71bc68c6 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -1161,10 +1164,9 @@ struct QueryCacheRuntimeImpl { StagingBufferPool& staging_pool_, ComputePassDescriptorQueue& compute_pass_descriptor_queue, DescriptorPool& descriptor_pool) - : rasterizer{rasterizer_}, device_memory{device_memory_}, - buffer_cache{buffer_cache_}, device{device_}, - memory_allocator{memory_allocator_}, scheduler{scheduler_}, staging_pool{staging_pool_}, - guest_streamer(0, runtime), + : rasterizer{rasterizer_}, device_memory{device_memory_}, buffer_cache{buffer_cache_}, + device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, + staging_pool{staging_pool_}, guest_streamer(0, runtime), sample_streamer(static_cast(QueryType::ZPassPixelCount64), runtime, rasterizer, device, scheduler, memory_allocator, compute_pass_descriptor_queue, descriptor_pool), @@ -1300,9 +1302,11 @@ void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::Lo if (impl->hcr_is_set) { if (impl->hcr_setup.buffer == impl->hcr_buffer && impl->hcr_setup.offset == impl->hcr_offset) { - ResumeHostConditionalRendering(); return; } + } + bool was_running = impl->is_hcr_running; + if (was_running) { PauseHostConditionalRendering(); } impl->hcr_setup.buffer = impl->hcr_buffer; @@ -1310,7 +1314,9 @@ void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::Lo impl->hcr_setup.flags = is_equal ? VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT : 0; impl->hcr_is_set = true; impl->is_hcr_running = false; - ResumeHostConditionalRendering(); + if (was_running) { + ResumeHostConditionalRendering(); + } } void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal) { @@ -1325,7 +1331,8 @@ void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, boo to_resolve = buffer->Handle(); to_resolve_offset = static_cast(offset); } - if (impl->is_hcr_running) { + bool was_running = impl->is_hcr_running; + if (was_running) { PauseHostConditionalRendering(); } impl->conditional_resolve_pass->Resolve(*impl->hcr_resolve_buffer, to_resolve, @@ -1335,7 +1342,9 @@ void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, boo impl->hcr_setup.flags = is_equal ? 0 : VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT; impl->hcr_is_set = true; impl->is_hcr_running = false; - ResumeHostConditionalRendering(); + if (was_running) { + ResumeHostConditionalRendering(); + } } bool QueryCacheRuntime::HostConditionalRenderingCompareValue(VideoCommon::LookupData object_1, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 0243693049..208f6647e0 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -217,8 +217,6 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) { FlushWork(); gpu_memory->FlushCaching(); - query_cache.NotifySegment(true); - GraphicsPipeline* const pipeline{pipeline_cache.CurrentGraphicsPipeline()}; if (!pipeline) { return; @@ -232,9 +230,13 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) { UpdateDynamicStates(); HandleTransformFeedback(); + query_cache.NotifySegment(true); query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable); + draw_func(); + + query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, false); } void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) { @@ -311,8 +313,6 @@ void RasterizerVulkan::DrawTexture() { }; FlushWork(); - query_cache.NotifySegment(true); - std::scoped_lock l{texture_cache.mutex}; texture_cache.SynchronizeGraphicsDescriptors(); texture_cache.UpdateRenderTargets(false); @@ -359,10 +359,6 @@ void RasterizerVulkan::Clear(u32 layer_count) { FlushWork(); gpu_memory->FlushCaching(); - query_cache.NotifySegment(true); - query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, - maxwell3d->regs.zpass_pixel_count_enable); - auto& regs = maxwell3d->regs; const bool use_color = regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B || regs.clear_surface.A; @@ -378,6 +374,10 @@ void RasterizerVulkan::Clear(u32 layer_count) { const VkExtent2D render_area = framebuffer->RenderArea(); scheduler.RequestRenderpass(framebuffer); + query_cache.NotifySegment(true); + query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, + maxwell3d->regs.zpass_pixel_count_enable); + u32 up_scale = 1; u32 down_shift = 0; if (texture_cache.IsRescaling()) { @@ -518,6 +518,14 @@ void RasterizerVulkan::DispatchCompute() { } const std::array dim{qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z}; scheduler.RequestOutsideRenderPassOperationContext(); + static constexpr VkMemoryBarrier READ_BARRIER{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, + }; + scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, READ_BARRIER); }); scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); }); } @@ -824,6 +832,7 @@ std::optional RasterizerVulkan::AccelerateDisplay( if (!image_view) { return {}; } + query_cache.NotifySegment(false); const auto& resolution = Settings::values.resolution_info; @@ -935,20 +944,22 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateDepthBounds(regs); UpdateStencilFaces(regs); UpdateLineWidth(regs); + // TODO: updating line stipple causes the cmdbuf to die + // UpdateLineStipple(regs); const u8 dynamic_state = Settings::values.dyna_state.GetValue(); auto features = DynamicFeatures{ - .has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported() - && dynamic_state > 0, - .has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported() - && dynamic_state > 1, - .has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported() - && dynamic_state > 1, - .has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported() - && dynamic_state > 2, - .has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported() - && dynamic_state > 2, + .has_extended_dynamic_state = + device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0, + .has_extended_dynamic_state_2 = + device.IsExtExtendedDynamicState2Supported() && dynamic_state > 1, + .has_extended_dynamic_state_2_extra = + device.IsExtExtendedDynamicState2ExtrasSupported() && dynamic_state > 1, + .has_extended_dynamic_state_3_blend = + device.IsExtExtendedDynamicState3BlendingSupported() && dynamic_state > 2, + .has_extended_dynamic_state_3_enables = + device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state > 2, .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(), }; @@ -973,16 +984,12 @@ void RasterizerVulkan::UpdateDynamicStates() { if (features.has_extended_dynamic_state_3_enables) { using namespace Tegra::Engines; - if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE - || device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) { - struct In - { + if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE || + device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) { + struct In { const Maxwell3D::Regs::VertexAttribute::Type d; - In(Maxwell3D::Regs::VertexAttribute::Type n) - : d(n) - {} - bool operator()(Maxwell3D::Regs::VertexAttribute n) const - { + In(Maxwell3D::Regs::VertexAttribute::Type n) : d(n) {} + bool operator()(Maxwell3D::Regs::VertexAttribute n) const { return n.type == d; } }; @@ -1133,36 +1140,36 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { if (is_d24 && !device.SupportsD24DepthBuffer()) { static constexpr const size_t length = sizeof(NEEDS_D24) / sizeof(NEEDS_D24[0]); - static constexpr const u64 *start = NEEDS_D24; - static constexpr const u64 *end = NEEDS_D24 + length; + static constexpr const u64* start = NEEDS_D24; + static constexpr const u64* end = NEEDS_D24 + length; - const u64 *it = std::find(start, end, program_id); + const u64* it = std::find(start, end, program_id); if (it != end) { // the base formulas can be obtained from here: // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias - const double rescale_factor = static_cast(1ULL << (32 - 24)) - / (static_cast(0x1.ep+127)); + const double rescale_factor = + static_cast(1ULL << (32 - 24)) / (static_cast(0x1.ep+127)); units = static_cast(static_cast(units) * rescale_factor); } } - scheduler.Record( - [constant = units, clamp = regs.depth_bias_clamp, factor = regs.slope_scale_depth_bias, this]( - vk::CommandBuffer cmdbuf) { - if (device.IsExtDepthBiasControlSupported()) { - static VkDepthBiasRepresentationInfoEXT bias_info{ - .sType = VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT, - .pNext = nullptr, - .depthBiasRepresentation = VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT, - .depthBiasExact = VK_FALSE, - }; + scheduler.Record([constant = units, clamp = regs.depth_bias_clamp, + factor = regs.slope_scale_depth_bias, this](vk::CommandBuffer cmdbuf) { + if (device.IsExtDepthBiasControlSupported()) { + static VkDepthBiasRepresentationInfoEXT bias_info{ + .sType = VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT, + .pNext = nullptr, + .depthBiasRepresentation = + VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT, + .depthBiasExact = VK_FALSE, + }; - cmdbuf.SetDepthBias(constant, clamp, factor, &bias_info); - } else { - cmdbuf.SetDepthBias(constant, clamp, factor); - } - }); + cmdbuf.SetDepthBias(constant, clamp, factor, &bias_info); + } else { + cmdbuf.SetDepthBias(constant, clamp, factor); + } + }); } void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1344,21 +1351,19 @@ void RasterizerVulkan::UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D:: }); } -void RasterizerVulkan::UpdateConservativeRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs) -{ +void RasterizerVulkan::UpdateConservativeRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchConservativeRasterizationMode()) { return; } scheduler.Record([enable = regs.conservative_raster_enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetConservativeRasterizationModeEXT( - enable ? VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT + enable ? VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT); }); } -void RasterizerVulkan::UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs& regs) -{ +void RasterizerVulkan::UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchLineStippleEnable()) { return; } @@ -1368,8 +1373,17 @@ void RasterizerVulkan::UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs& }); } -void RasterizerVulkan::UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs) -{ +void RasterizerVulkan::UpdateLineStipple(Tegra::Engines::Maxwell3D::Regs& regs) { + if (!state_tracker.TouchLineStipple()) { + return; + } + + scheduler.Record([params = regs.line_stipple_params](vk::CommandBuffer cmdbuf) { + cmdbuf.SetLineStippleEXT(params.factor, static_cast(params.pattern)); + }); +} + +void RasterizerVulkan::UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs) { // if (!state_tracker.TouchLi()) { // return; // } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index f562ad1941..ea032635c2 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -180,6 +180,7 @@ private: void UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateConservativeRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs& regs); + void UpdateLineStipple(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 146923db4d..7c556588b6 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -257,16 +260,6 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se void Scheduler::AllocateNewContext() { // Enable counters once again. These are disabled when a command buffer is finished. - if (query_cache) { -#if ANDROID - if (Settings::IsGPULevelHigh()) { - // This is problematic on Android, disable on GPU Normal. - query_cache->NotifySegment(true); - } -#else - query_cache->NotifySegment(true); -#endif - } } void Scheduler::InvalidateState() { @@ -276,15 +269,7 @@ void Scheduler::InvalidateState() { } void Scheduler::EndPendingOperations() { -#if ANDROID - if (Settings::IsGPULevelHigh()) { - // This is problematic on Android, disable on GPU Normal. - // query_cache->DisableStreams(); - } -#else - // query_cache->DisableStreams(); -#endif - query_cache->NotifySegment(false); + query_cache->CounterReset(VideoCommon::QueryType::ZPassPixelCount64); EndRenderPass(); } @@ -292,6 +277,10 @@ void Scheduler::EndRenderPass() { if (!state.renderpass) { return; } + + query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false); + query_cache->NotifySegment(false); + Record([num_images = num_renderpass_images, images = renderpass_images, ranges = renderpass_image_ranges](vk::CommandBuffer cmdbuf) { std::array barriers; diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 51e7ab1e1d..54ab8ba52b 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -153,6 +153,7 @@ private: TypedCommand& operator=(TypedCommand&&) = delete; void Execute(vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) const override { + command(cmdbuf, upload_cmdbuf); } diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 72d5ec35f9..d78bdeca6b 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -49,8 +49,8 @@ size_t GetStreamBufferSize(const Device& device) { StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, Scheduler& scheduler_) : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, - stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size / - StagingBufferPool::NUM_SYNCS} { + stream_buffer_size{GetStreamBufferSize(device)}, + region_size{stream_buffer_size / StagingBufferPool::NUM_SYNCS} { VkBufferCreateInfo stream_ci = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index ff274ede6e..242d03cf24 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -52,9 +52,6 @@ Flags MakeInvalidationFlags() { VertexInput, StateEnable, PrimitiveRestartEnable, - RasterizerDiscardEnable, - ConservativeRasterizationMode, - LineStippleEnable, DepthBiasEnable, LogicOpEnable, DepthClampEnable, @@ -63,6 +60,9 @@ Flags MakeInvalidationFlags() { ColorMask, BlendEquations, BlendEnable, + ConservativeRasterizationMode, + LineStippleEnable, + LineStippleParams, }; Flags flags{}; for (const int flag : INVALIDATION_FLAGS) { @@ -142,13 +142,12 @@ void SetupDirtyStateEnable(Tables& tables) { setup(OFF(stencil_enable), StencilTestEnable); setup(OFF(primitive_restart.enabled), PrimitiveRestartEnable); setup(OFF(rasterize_enable), RasterizerDiscardEnable); - setup(OFF(conservative_raster_enable), ConservativeRasterizationMode); - setup(OFF(line_stipple_enable), LineStippleEnable); setup(OFF(polygon_offset_point_enable), DepthBiasEnable); setup(OFF(polygon_offset_line_enable), DepthBiasEnable); setup(OFF(polygon_offset_fill_enable), DepthBiasEnable); setup(OFF(logic_op.enable), LogicOpEnable); setup(OFF(viewport_clip_control.geometry_clip), DepthClampEnable); + setup(OFF(line_stipple_enable), LineStippleEnable); } void SetupDirtyDepthCompareOp(Tables& tables) { @@ -221,6 +220,13 @@ void SetupDirtyVertexBindings(Tables& tables) { tables[1][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = flag; } } + +void SetupRasterModes(Tables &tables) { + auto& table = tables[0]; + + table[OFF(line_stipple_params)] = LineStippleParams; + table[OFF(conservative_raster_enable)] = ConservativeRasterizationMode; +} } // Anonymous namespace void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) { @@ -243,6 +249,7 @@ void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) { SetupDirtyVertexAttributes(tables); SetupDirtyVertexBindings(tables); SetupDirtySpecialOps(tables); + SetupRasterModes(tables); } void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) { diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index c7e460ce11..7edd464e7a 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -55,6 +55,7 @@ enum : u8 { RasterizerDiscardEnable, ConservativeRasterizationMode, LineStippleEnable, + LineStippleParams, DepthBiasEnable, StateEnable, LogicOp, @@ -205,14 +206,21 @@ public: return Exchange(Dirty::RasterizerDiscardEnable, false); } - bool TouchConservativeRasterizationMode() - { + bool TouchConservativeRasterizationMode() { return Exchange(Dirty::ConservativeRasterizationMode, false); } - bool TouchLineStippleEnable() { return Exchange(Dirty::ConservativeRasterizationMode, false); } + bool TouchLineStippleEnable() { + return Exchange(Dirty::LineStippleEnable, false); + } - bool TouchDepthBiasEnable() { return Exchange(Dirty::DepthBiasEnable, false); } + bool TouchLineStipple() { + return Exchange(Dirty::LineStippleParams, false); + } + + bool TouchDepthBiasEnable() { + return Exchange(Dirty::DepthBiasEnable, false); + } bool TouchLogicOpEnable() { return Exchange(Dirty::LogicOpEnable, false); diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index a002ca83a0..962a61d91c 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -111,18 +111,14 @@ Swapchain::Swapchain( #else VkSurfaceKHR_T* surface_handle_, #endif - const Device& device_, - Scheduler& scheduler_, - u32 width_, - u32 height_) + const Device& device_, Scheduler& scheduler_, u32 width_, u32 height_) #ifdef ANDROID : surface(surface_) #else : surface_handle{surface_handle_} #endif - , device{device_} - , scheduler{scheduler_} -{ + , + device{device_}, scheduler{scheduler_} { #ifdef ANDROID Create(surface, width_, height_); #else @@ -138,9 +134,7 @@ void Swapchain::Create( #else VkSurfaceKHR_T* surface_handle_, #endif - u32 width_, - u32 height_) -{ + u32 width_, u32 height_) { is_outdated = false; is_suboptimal = false; width = width_; @@ -243,8 +237,8 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) { const auto present_modes = physical_device.GetSurfacePresentModesKHR(surface_handle); #endif - has_mailbox = std::find(present_modes.begin(), present_modes.end(), VK_PRESENT_MODE_MAILBOX_KHR) - != present_modes.end(); + has_mailbox = std::find(present_modes.begin(), present_modes.end(), + VK_PRESENT_MODE_MAILBOX_KHR) != present_modes.end(); has_imm = std::find(present_modes.begin(), present_modes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR) != present_modes.end(); has_fifo_relaxed = std::find(present_modes.begin(), present_modes.end(), diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index b3e1c4f025..389c5525c8 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h @@ -27,10 +27,7 @@ public: #else VkSurfaceKHR_T* surface_handle, #endif - const Device& device, - Scheduler& scheduler, - u32 width, - u32 height); + const Device& device, Scheduler& scheduler, u32 width, u32 height); ~Swapchain(); /// Creates (or recreates) the swapchain with a given size. @@ -40,8 +37,7 @@ public: #else VkSurfaceKHR_T* surface_handle, #endif - u32 width, - u32 height); + u32 width, u32 height); /// Acquires the next image in the swapchain, waits as needed. bool AcquireNextImage(); @@ -101,7 +97,7 @@ public: } VkSemaphore CurrentRenderSemaphore() const { - return *render_semaphores[frame_index]; + return *render_semaphores[image_index]; } u32 GetWidth() const { diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 022a9ae572..8296ce7d54 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -38,6 +41,7 @@ using VideoCommon::ImageInfo; using VideoCommon::ImageType; using VideoCommon::SubresourceRange; using VideoCore::Surface::BytesPerBlock; +using VideoCore::Surface::HasAlpha; using VideoCore::Surface::IsPixelFormatASTC; using VideoCore::Surface::IsPixelFormatInteger; using VideoCore::Surface::SurfaceType; @@ -1206,8 +1210,8 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im src_view.format == PixelFormat::B8G8R8A8_SRGB) { // Verify format support before conversion if (device.IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, - FormatType::Optimal)) { + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, + FormatType::Optimal)) { return blit_image_helper.ConvertABGR8SRGBToD24S8(dst, src_view); } else { // Fallback to regular ABGR8 conversion if sRGB not supported @@ -1323,12 +1327,13 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im case PixelFormat::D32_FLOAT_S8_UINT: case PixelFormat::Invalid: default: + LOG_ERROR(Render_Vulkan, "Unimplemented texture conversion from {} to {} format type", src_view.format, dst_view.format); break; } } VkFormat TextureCacheRuntime::GetSupportedFormat(VkFormat requested_format, - VkFormatFeatureFlags required_features) const { + VkFormatFeatureFlags required_features) const { if (requested_format == VK_FORMAT_A8B8G8R8_SRGB_PACK32 && (required_features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { // Force valid depth format when sRGB requested in depth context @@ -1364,6 +1369,16 @@ bool TextureCacheRuntime::IsFormatScalable(PixelFormat format) { void TextureCacheRuntime::CopyImage(Image& dst, Image& src, std::span copies) { + // As per the size-compatible formats section of vulkan, copy manually via ReinterpretImage + // these images that aren't size-compatible + if (BytesPerBlock(src.info.format) != BytesPerBlock(dst.info.format)) { + auto oneCopy = VideoCommon::ImageCopy{ + .src_offset = VideoCommon::Offset3D(0, 0, 0), + .dst_offset = VideoCommon::Offset3D(0, 0, 0), + .extent = dst.info.size + }; + return ReinterpretImage(dst, src, std::span{&oneCopy, 1}); + } boost::container::small_vector vk_copies(copies.size()); const VkImageAspectFlags aspect_mask = dst.AspectMask(); ASSERT(aspect_mask == src.AspectMask()); @@ -1523,7 +1538,7 @@ Image::Image(const VideoCommon::NullImageParams& params) : VideoCommon::ImageBas Image::~Image() = default; void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, - std::span copies) { + std::span copies) { // TODO: Move this to another API const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); if (is_rescaled) { @@ -1531,8 +1546,9 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, } // Handle MSAA upload if necessary - /* WARNING, TODO: This code uses some hacks, besides being fundamentally ugly - since tropic didn't want to touch it for a long time, so it needs a rewrite from someone better than me at vulkan.*/ + /* WARNING, TODO: This code uses some hacks, besides being fundamentally ugly + since tropic didn't want to touch it for a long time, so it needs a rewrite from someone better + than me at vulkan.*/ if (info.num_samples > 1 && runtime->CanUploadMSAA()) { // Only use MSAA copy pass for color formats // TODO: Depth/stencil formats need special handling @@ -1552,9 +1568,11 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, const VkBuffer src_buffer = buffer; const VkImage temp_vk_image = *temp_image; const VkImageAspectFlags vk_aspect_mask = aspect_mask; - scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { - CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, vk_copies); - }); + scheduler->Record( + [src_buffer, temp_vk_image, vk_aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { + CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, + vk_copies); + }); // Use MSAACopyPass to convert from non-MSAA to MSAA std::vector image_copies; @@ -1591,7 +1609,8 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, const bool is_initialized = std::exchange(initialized, true); scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies](vk::CommandBuffer cmdbuf) { - CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies); + CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, + vk_copies); }); } @@ -1616,7 +1635,7 @@ void Image::DownloadMemory(VkBuffer buffer, size_t offset, } void Image::DownloadMemory(std::span buffers_span, std::span offsets_span, - std::span copies) { + std::span copies) { const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); if (is_rescaled) { ScaleDown(); @@ -1662,8 +1681,9 @@ void Image::DownloadMemory(std::span buffers_span, std::span o } scheduler->RequestOutsideRenderPassOperationContext(); - scheduler->Record([buffers = std::move(buffers_vector), image = *temp_wrapper.original_image, - aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { + scheduler->Record([buffers = std::move(buffers_vector), + image = *temp_wrapper.original_image, aspect_mask_ = aspect_mask, + vk_copies](vk::CommandBuffer cmdbuf) { const VkImageMemoryBarrier read_barrier{ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, @@ -1682,12 +1702,12 @@ void Image::DownloadMemory(std::span buffers_span, std::span o .layerCount = VK_REMAINING_ARRAY_LAYERS, }, }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, read_barrier); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, read_barrier); for (size_t index = 0; index < buffers.size(); index++) { - cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers[index], - vk_copies[index]); + cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + buffers[index], vk_copies[index]); } const VkMemoryBarrier memory_write_barrier{ @@ -1714,8 +1734,9 @@ void Image::DownloadMemory(std::span buffers_span, std::span o .layerCount = VK_REMAINING_ARRAY_LAYERS, }, }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - 0, memory_write_barrier, nullptr, image_write_barrier); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, memory_write_barrier, + nullptr, image_write_barrier); }); return; } @@ -1749,12 +1770,12 @@ void Image::DownloadMemory(std::span buffers_span, std::span o .layerCount = VK_REMAINING_ARRAY_LAYERS, }, }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, read_barrier); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, read_barrier); for (size_t index = 0; index < buffers.size(); index++) { - cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers[index], - vk_copies[index]); + cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + buffers[index], vk_copies[index]); } const VkMemoryBarrier memory_write_barrier{ @@ -1781,8 +1802,9 @@ void Image::DownloadMemory(std::span buffers_span, std::span o .layerCount = VK_REMAINING_ARRAY_LAYERS, }, }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - 0, memory_write_barrier, nullptr, image_write_barrier); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, memory_write_barrier, + nullptr, image_write_barrier); }); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index cd11cc8fc7..d7fb405c4c 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -113,7 +113,8 @@ public: bool IsFormatDitherable(VideoCore::Surface::PixelFormat format); bool IsFormatScalable(VideoCore::Surface::PixelFormat format); - VkFormat GetSupportedFormat(VkFormat requested_format, VkFormatFeatureFlags required_features) const; + VkFormat GetSupportedFormat(VkFormat requested_format, + VkFormatFeatureFlags required_features) const; const Device& device; Scheduler& scheduler; @@ -197,7 +198,7 @@ private: // Use a pointer to field because it is relative, so that the object can be // moved without breaking the reference. - vk::Image Image::*current_image{}; + vk::Image Image::* current_image{}; std::vector storage_image_views; VkImageAspectFlags aspect_mask = 0; diff --git a/src/video_core/renderer_vulkan/vk_texture_manager.cpp b/src/video_core/renderer_vulkan/vk_texture_manager.cpp index 003af9e6fb..07d3aa4100 100644 --- a/src/video_core/renderer_vulkan/vk_texture_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_manager.cpp @@ -75,15 +75,17 @@ void TextureManager::CleanupTextureCache() { // TODO: track usage and remove unused textures [ZEP] - LOG_INFO(Render_Vulkan, "Handling texture cache cleanup, current size: {}", texture_cache.size()); + LOG_INFO(Render_Vulkan, "Handling texture cache cleanup, current size: {}", + texture_cache.size()); } void TextureManager::HandleTextureRendering(const std::string& texture_path, - std::function render_callback) { + std::function render_callback) { VkImage texture = GetTexture(texture_path); if (!IsTextureLoadedCorrectly(texture)) { - LOG_ERROR(Render_Vulkan, "Texture failed to load correctly: {}, attempting reload", texture_path); + LOG_ERROR(Render_Vulkan, "Texture failed to load correctly: {}, attempting reload", + texture_path); ReloadTexture(texture_path); texture = GetTexture(texture_path); } @@ -115,26 +117,26 @@ vk::Image TextureManager::LoadTexture(const std::string& texture_path) { vk::Image TextureManager::CreateDefaultTexture() { // Create a small default texture (1x1 pixel) to use as a fallback -// const VkExtent2D extent{1, 1}; + // const VkExtent2D extent{1, 1}; -/* // Create image - const VkImageCreateInfo image_ci{ - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .imageType = VK_IMAGE_TYPE_2D, - .format = texture_format, - .extent = {extent.width, extent.height, 1}, - .mipLevels = 1, - .arrayLayers = 1, - .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = nullptr, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - }; */ + /* // Create image + const VkImageCreateInfo image_ci{ + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .imageType = VK_IMAGE_TYPE_2D, + .format = texture_format, + .extent = {extent.width, extent.height, 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = nullptr, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; */ // TODO: create an actual VkImage [ZEP] LOG_INFO(Render_Vulkan, "Created default fallback texture"); diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index baeb8b23a0..7b19aa265d 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp @@ -398,8 +398,8 @@ u32 GraphicsEnvironment::ReadViewportTransformState() { ComputeEnvironment::ComputeEnvironment(Tegra::Engines::KeplerCompute& kepler_compute_, Tegra::MemoryManager& gpu_memory_, GPUVAddr program_base_, u32 start_address_) - : GenericEnvironment{gpu_memory_, program_base_, start_address_}, kepler_compute{ - &kepler_compute_} { + : GenericEnvironment{gpu_memory_, program_base_, start_address_}, + kepler_compute{&kepler_compute_} { const auto& qmd{kepler_compute->launch_description}; stage = Shader::Stage::Compute; local_memory_size = qmd.local_pos_alloc + qmd.local_crs_alloc; diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 9055b1b929..1998849e84 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -237,6 +240,44 @@ SurfaceType GetFormatType(PixelFormat pixel_format) { return SurfaceType::Invalid; } +bool HasAlpha(PixelFormat pixel_format) { + switch (pixel_format) { + case PixelFormat::A8B8G8R8_UNORM: + case PixelFormat::A8B8G8R8_SNORM: + case PixelFormat::A8B8G8R8_SINT: + case PixelFormat::A8B8G8R8_UINT: + case PixelFormat::A1R5G5B5_UNORM: + case PixelFormat::A2B10G10R10_UNORM: + case PixelFormat::A2B10G10R10_UINT: + case PixelFormat::A2R10G10B10_UNORM: + case PixelFormat::A1B5G5R5_UNORM: + case PixelFormat::A5B5G5R1_UNORM: + case PixelFormat::R16G16B16A16_FLOAT: + case PixelFormat::R16G16B16A16_UNORM: + case PixelFormat::R16G16B16A16_SNORM: + case PixelFormat::R16G16B16A16_SINT: + case PixelFormat::R16G16B16A16_UINT: + case PixelFormat::R32G32B32A32_UINT: + case PixelFormat::BC1_RGBA_UNORM: + case PixelFormat::B8G8R8A8_UNORM: + case PixelFormat::R32G32B32A32_FLOAT: + case PixelFormat::R32G32B32A32_SINT: + case PixelFormat::A8B8G8R8_SRGB: + case PixelFormat::B8G8R8A8_SRGB: + case PixelFormat::BC1_RGBA_SRGB: + case PixelFormat::A4B4G4R4_UNORM: + case PixelFormat::BC2_SRGB: + case PixelFormat::BC2_UNORM: + case PixelFormat::BC3_SRGB: + case PixelFormat::BC3_UNORM: + case PixelFormat::BC7_SRGB: + case PixelFormat::BC7_UNORM: + return true; + default: + return false; + } +} + bool IsPixelFormatASTC(PixelFormat format) { switch (format) { case PixelFormat::ASTC_2D_4X4_UNORM: diff --git a/src/video_core/surface.h b/src/video_core/surface.h index ec9cd2fbf0..4ccb24f27d 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -503,6 +503,8 @@ PixelFormat PixelFormatFromGPUPixelFormat(Service::android::PixelFormat format); SurfaceType GetFormatType(PixelFormat pixel_format); +bool HasAlpha(PixelFormat pixel_format); + bool IsPixelFormatASTC(PixelFormat format); bool IsPixelFormatBCn(PixelFormat format); diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 1a6f0d1ad1..e3faa5bf95 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Ryujinx Team and Contributors // SPDX-License-Identifier: GPL-2.0-or-later AND MIT @@ -343,7 +346,7 @@ template if (!IsBlockLinearSizeCompatible(new_info, info, base.level, 0, strict_size)) { return std::nullopt; } - const u32 mip_depth = std::max(1U, new_info.size.depth << base.level); + const u32 mip_depth = AdjustMipSize(new_info.size.depth, base.level); if (mip_depth < info.size.depth + base.layer) { return std::nullopt; } @@ -428,8 +431,14 @@ template return std::nullopt; } const SubresourceExtent resources = new_info.resources; - s32 layers = 1; - if (info.type != ImageType::e3D) { + s32 layers; + if (info.type == ImageType::e3D) { + const u32 mip_depth = AdjustMipSize(info.size.depth, base->level); + if (mip_depth < new_info.size.depth + base->layer) { + return std::nullopt; + } + layers = 1; + } else { layers = std::max(resources.layers, info.resources.layers + base->layer); } return OverlapResult{ @@ -1216,7 +1225,7 @@ std::optional FindSubresource(const ImageInfo& candidate, const return std::nullopt; } if (existing.type == ImageType::e3D) { - const u32 mip_depth = std::max(1U, existing.size.depth << base->level); + const u32 mip_depth = AdjustMipSize(existing.size.depth, base->level); if (mip_depth < candidate.size.depth + base->layer) { return std::nullopt; } @@ -1247,7 +1256,7 @@ bool IsSubCopy(const ImageInfo& candidate, const ImageBase& image, GPUVAddr cand return false; } if (existing.type == ImageType::e3D) { - const u32 mip_depth = std::max(1U, existing.size.depth << base->level); + const u32 mip_depth = AdjustMipSize(existing.size.depth, base->level); if (mip_depth < candidate.size.depth + base->layer) { return false; } diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp index fef0be31d8..f35e00d9a5 100644 --- a/src/video_core/textures/astc.cpp +++ b/src/video_core/textures/astc.cpp @@ -924,7 +924,7 @@ static void DecodeColorValues(u32* out, std::span data, const u32* modes, co assert(false && "Unsupported trit encoding for color values!"); break; } // switch(bitlen) - } // case IntegerEncoding::Trit + } // case IntegerEncoding::Trit break; case IntegerEncoding::Quint: { @@ -968,7 +968,7 @@ static void DecodeColorValues(u32* out, std::span data, const u32* modes, co assert(false && "Unsupported quint encoding for color values!"); break; } // switch(bitlen) - } // case IntegerEncoding::Quint + } // case IntegerEncoding::Quint break; } // switch(val.encoding) @@ -1588,7 +1588,7 @@ static void DecompressBlock(std::span inBuf, const u32 blockWidth, // Reverse everything for (u32 i = 0; i < 8; i++) { // Taken from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits -#define REVERSE_BYTE(b) (((b)*0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32 +#define REVERSE_BYTE(b) (((b) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32 u8 a = static_cast(REVERSE_BYTE(texelWeightData[i])); u8 b = static_cast(REVERSE_BYTE(texelWeightData[15 - i])); #undef REVERSE_BYTE diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 474e420daf..e70d530443 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -290,9 +290,9 @@ std::unordered_map GetFormatProperties(vk::Physica void OverrideBcnFormats(std::unordered_map& format_properties) { // These properties are extracted from Adreno driver 512.687.0 constexpr VkFormatFeatureFlags tiling_features{ - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | - VK_FORMAT_FEATURE_TRANSFER_DST_BIT}; + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | + VK_FORMAT_FEATURE_TRANSFER_DST_BIT}; constexpr VkFormatFeatureFlags buffer_features{VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT}; @@ -313,7 +313,7 @@ void OverrideBcnFormats(std::unordered_map& format #endif NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical, - const std::set>& exts) { + const std::set>& exts) { VkPhysicalDeviceProperties2 physical_properties{}; physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; physical_properties.pNext = nullptr; @@ -408,7 +408,7 @@ void Device::RemoveExtensionFeatureIfUnsuitable(bool is_suitable, Feature& featu Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR surface, const vk::InstanceDispatch& dld_) : instance{instance_}, dld{dld_}, physical{physical_}, - format_properties(GetFormatProperties(physical)) { + format_properties(GetFormatProperties(physical)) { // Get suitability and device properties. const bool is_suitable = GetSuitability(surface != nullptr); @@ -445,7 +445,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const void* first_next = &features2; VkDeviceDiagnosticsConfigCreateInfoNV diagnostics_nv{}; - const bool use_diagnostics_nv = Settings::values.enable_nsight_aftermath && extensions.device_diagnostics_config; + const bool use_diagnostics_nv = + Settings::values.enable_nsight_aftermath && extensions.device_diagnostics_config; if (use_diagnostics_nv) { nsight_aftermath_tracker = std::make_unique(); @@ -461,7 +462,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, - .pNext = use_diagnostics_nv ? static_cast(&diagnostics_nv) : static_cast(&features2), + .pNext = use_diagnostics_nv ? static_cast(&diagnostics_nv) + : static_cast(&features2), .shaderSampledImageArrayNonUniformIndexing = VK_TRUE, .descriptorBindingPartiallyBound = VK_TRUE, .descriptorBindingVariableDescriptorCount = VK_TRUE, @@ -494,14 +496,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (is_qualcomm || is_turnip) { LOG_WARNING(Render_Vulkan, "Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color"); - //RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, - //VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + // RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, + // VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); } if (is_qualcomm) { LOG_WARNING(Render_Vulkan, "Qualcomm drivers have a slow VK_KHR_push_descriptor implementation"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + // RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); #if defined(ANDROID) && defined(ARCHITECTURE_arm64) // Patch the driver to enable BCn textures. @@ -535,7 +537,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } else if (arch <= NvidiaArchitecture::Arch_Volta) { if (nv_major_version < 527) { LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + // RemoveExtension(extensions.push_descriptor, + // VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } } if (nv_major_version >= 510) { @@ -549,9 +552,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) { LOG_WARNING(Render_Vulkan, "RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state"); - //RemoveExtensionFeature(extensions.extended_dynamic_state, - //features.extended_dynamic_state, - //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + // RemoveExtensionFeature(extensions.extended_dynamic_state, + // features.extended_dynamic_state, + // VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } } if (extensions.extended_dynamic_state2 && is_radv) { @@ -572,9 +575,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // Qualcomm Adreno 7xx drivers do not properly support extended_dynamic_state2. LOG_WARNING(Render_Vulkan, "Qualcomm Adreno 7xx drivers have broken VK_EXT_extended_dynamic_state2"); - //RemoveExtensionFeature(extensions.extended_dynamic_state2, - //features.extended_dynamic_state2, - //VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + // RemoveExtensionFeature(extensions.extended_dynamic_state2, + // features.extended_dynamic_state2, + // VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } } if (extensions.extended_dynamic_state3 && is_radv) { @@ -591,7 +594,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR dynamic_state3_enables = true; } } - if (extensions.extended_dynamic_state3 && (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) { + if (extensions.extended_dynamic_state3 && + (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) { // AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation LOG_WARNING(Render_Vulkan, "AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation"); @@ -616,9 +620,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // Qualcomm drivers do not properly support vertex_input_dynamic_state. LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken VK_EXT_vertex_input_dynamic_state"); - //RemoveExtensionFeature(extensions.vertex_input_dynamic_state, - // features.vertex_input_dynamic_state, - // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + // RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + // features.vertex_input_dynamic_state, + // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } sets_per_pool = 64; @@ -652,9 +656,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(27, 20, 100, 0)) { LOG_WARNING(Render_Vulkan, "Intel has broken VK_EXT_vertex_input_dynamic_state"); - //RemoveExtensionFeature(extensions.vertex_input_dynamic_state, - //features.vertex_input_dynamic_state, - //VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + // RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + // features.vertex_input_dynamic_state, + // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } if (features.shader_float16_int8.shaderFloat16 && is_intel_windows) { @@ -681,14 +685,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // mesa/mesa/-/commit/ff91c5ca42bc80aa411cb3fd8f550aa6fdd16bdc LOG_WARNING(Render_Vulkan, "ANV drivers 22.3.0 to 23.1.0 have broken VK_KHR_push_descriptor"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + // RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } } else if (extensions.push_descriptor && is_nvidia) { const auto arch = GetNvidiaArch(); if (arch <= NvidiaArchitecture::Arch_Pascal) { LOG_WARNING(Render_Vulkan, "Pascal and older architectures have broken VK_KHR_push_descriptor"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + // RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } } @@ -724,30 +728,33 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (Settings::values.dyna_state.GetValue() == 0) { must_emulate_scaled_formats = true; - LOG_INFO(Render_Vulkan, "Dynamic state is disabled (dyna_state = 0), forcing scaled format emulation ON"); + LOG_INFO(Render_Vulkan, + "Dynamic state is disabled (dyna_state = 0), forcing scaled format emulation ON"); // Disable dynamic state 1-3 and all extensions RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, - VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); - RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, - VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, - VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); dynamic_state3_blending = false; dynamic_state3_enables = false; LOG_INFO(Render_Vulkan, "All dynamic state extensions and features have been disabled"); } else { must_emulate_scaled_formats = false; - LOG_INFO(Render_Vulkan, "Dynamic state is enabled (dyna_state = 1-3), disabling scaled format emulation"); + LOG_INFO(Render_Vulkan, + "Dynamic state is enabled (dyna_state = 1-3), disabling scaled format emulation"); } logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions), @@ -850,9 +857,9 @@ bool Device::ComputeIsOptimalAstcSupported() const { return false; } const auto format_feature_usage{ - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | - VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | - VK_FORMAT_FEATURE_TRANSFER_DST_BIT}; + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | + VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | + VK_FORMAT_FEATURE_TRANSFER_DST_BIT}; for (const auto format : astc_formats) { const auto physical_format_properties{physical.GetFormatProperties(format)}; if ((physical_format_properties.optimalTilingFeatures & format_feature_usage) == 0) { @@ -999,13 +1006,13 @@ bool Device::GetSuitability(bool requires_swapchain) { #define EXTENSION(prefix, macro_name, var_name) \ if (supported_extensions.contains(VK_##prefix##_##macro_name##_EXTENSION_NAME)) { \ - loaded_extensions.insert(VK_##prefix##_##macro_name##_EXTENSION_NAME); \ - extensions.var_name = true; \ + loaded_extensions.insert(VK_##prefix##_##macro_name##_EXTENSION_NAME); \ + extensions.var_name = true; \ } #define FEATURE_EXTENSION(prefix, struct_name, macro_name, var_name) \ if (supported_extensions.contains(VK_##prefix##_##macro_name##_EXTENSION_NAME)) { \ - loaded_extensions.insert(VK_##prefix##_##macro_name##_EXTENSION_NAME); \ - extensions.var_name = true; \ + loaded_extensions.insert(VK_##prefix##_##macro_name##_EXTENSION_NAME); \ + extensions.var_name = true; \ } if (instance_version < VK_API_VERSION_1_2) { @@ -1024,13 +1031,13 @@ bool Device::GetSuitability(bool requires_swapchain) { // Some extensions are mandatory. Check those. #define CHECK_EXTENSION(extension_name) \ if (!loaded_extensions.contains(extension_name)) { \ - LOG_ERROR(Render_Vulkan, "Missing required extension {}", extension_name); \ - suitable = false; \ + LOG_ERROR(Render_Vulkan, "Missing required extension {}", extension_name); \ + suitable = false; \ } #define LOG_EXTENSION(extension_name) \ if (!loaded_extensions.contains(extension_name)) { \ - LOG_INFO(Render_Vulkan, "Device doesn't support extension {}", extension_name); \ + LOG_INFO(Render_Vulkan, "Device doesn't support extension {}", extension_name); \ } FOR_EACH_VK_RECOMMENDED_EXTENSION(LOG_EXTENSION); @@ -1067,13 +1074,13 @@ bool Device::GetSuitability(bool requires_swapchain) { // We set the structure sType explicitly here as it is zeroed by the constructor. #define FEATURE(prefix, struct_name, macro_name, var_name) \ features.var_name.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##macro_name##_FEATURES; \ - SetNext(next, features.var_name); + SetNext(next, features.var_name); #define EXT_FEATURE(prefix, struct_name, macro_name, var_name) \ if (extensions.var_name) { \ - features.var_name.sType = \ + features.var_name.sType = \ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##macro_name##_FEATURES_##prefix; \ - SetNext(next, features.var_name); \ + SetNext(next, features.var_name); \ } FOR_EACH_VK_FEATURE_1_1(FEATURE); @@ -1101,13 +1108,13 @@ bool Device::GetSuitability(bool requires_swapchain) { // Some features are mandatory. Check those. #define CHECK_FEATURE(feature, name) \ if (!features.feature.name) { \ - LOG_ERROR(Render_Vulkan, "Missing required feature {}", #name); \ - suitable = false; \ + LOG_ERROR(Render_Vulkan, "Missing required feature {}", #name); \ + suitable = false; \ } #define LOG_FEATURE(feature, name) \ if (!features.feature.name) { \ - LOG_INFO(Render_Vulkan, "Device doesn't support feature {}", #name); \ + LOG_INFO(Render_Vulkan, "Device doesn't support feature {}", #name); \ } FOR_EACH_VK_RECOMMENDED_FEATURE(LOG_FEATURE); @@ -1170,11 +1177,11 @@ bool Device::GetSuitability(bool requires_swapchain) { const VkPhysicalDeviceLimits& limits{properties.properties.limits}; const std::array limits_report{ - Limit{65536, limits.maxUniformBufferRange, "maxUniformBufferRange"}, - Limit{16, limits.maxViewports, "maxViewports"}, - Limit{8, limits.maxColorAttachments, "maxColorAttachments"}, - Limit{8, limits.maxClipDistances, "maxClipDistances"}, - }; + Limit{65536, limits.maxUniformBufferRange, "maxUniformBufferRange"}, + Limit{16, limits.maxViewports, "maxViewports"}, + Limit{8, limits.maxColorAttachments, "maxColorAttachments"}, + Limit{8, limits.maxClipDistances, "maxClipDistances"}, + }; for (const auto& [min, value, name] : limits_report) { if (value < min) { @@ -1236,15 +1243,13 @@ void Device::RemoveUnsuitableExtensions() { // VK_EXT_provoking_vertex if (Settings::values.provoking_vertex.GetValue()) { - extensions.provoking_vertex = features.provoking_vertex.provokingVertexLast - && features.provoking_vertex - .transformFeedbackPreservesProvokingVertex; - RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex, - features.provoking_vertex, + extensions.provoking_vertex = + features.provoking_vertex.provokingVertexLast && + features.provoking_vertex.transformFeedbackPreservesProvokingVertex; + RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex, features.provoking_vertex, VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); } else { - RemoveExtensionFeature(extensions.provoking_vertex, - features.provoking_vertex, + RemoveExtensionFeature(extensions.provoking_vertex, features.provoking_vertex, VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); } diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index ddc9451a7e..9b78f2e599 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -85,7 +88,8 @@ VK_DEFINE_HANDLE(VmaAllocator) EXTENSION(NV, GEOMETRY_SHADER_PASSTHROUGH, geometry_shader_passthrough) \ EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \ EXTENSION(NV, VIEWPORT_SWIZZLE, viewport_swizzle) \ - EXTENSION(EXT, DESCRIPTOR_INDEXING, descriptor_indexing) + EXTENSION(EXT, DESCRIPTOR_INDEXING, descriptor_indexing) \ + EXTENSION(EXT, FILTER_CUBIC, filter_cubic) // Define extensions which must be supported. #define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \ @@ -549,6 +553,11 @@ public: return dynamic_state3_enables; } + /// Returns true if the device supports VK_EXT_filter_cubic + bool IsExtFilterCubicSupported() const { + return extensions.filter_cubic; + } + /// Returns true if the device supports VK_EXT_line_rasterization. bool IsExtLineRasterizationSupported() const { return extensions.line_rasterization; diff --git a/src/video_core/vulkan_common/vulkan_raii.h b/src/video_core/vulkan_common/vulkan_raii.h index cf5e268b68..b8ea4fde84 100644 --- a/src/video_core/vulkan_common/vulkan_raii.h +++ b/src/video_core/vulkan_common/vulkan_raii.h @@ -3,10 +3,10 @@ #pragma once -#include -#include #include +#include #include +#include #include "common/logging/log.h" @@ -27,17 +27,16 @@ public: VulkanRaii() : handle{}, deleter{}, dispatch{} {} // Constructor with handle and deleter - VulkanRaii(T handle_, DeleterFunc deleter_, const Dispatch& dispatch_, const char* resource_name = "Vulkan resource") + VulkanRaii(T handle_, DeleterFunc deleter_, const Dispatch& dispatch_, + const char* resource_name = "Vulkan resource") : handle{handle_}, deleter{std::move(deleter_)}, dispatch{dispatch_} { LOG_DEBUG(Render_Vulkan, "RAII wrapper created for {}", resource_name); } // Move constructor VulkanRaii(VulkanRaii&& other) noexcept - : handle{std::exchange(other.handle, VK_NULL_HANDLE)}, - deleter{std::move(other.deleter)}, - dispatch{other.dispatch} { - } + : handle{std::exchange(other.handle, VK_NULL_HANDLE)}, deleter{std::move(other.deleter)}, + dispatch{other.dispatch} {} // Move assignment VulkanRaii& operator=(VulkanRaii&& other) noexcept { @@ -122,14 +121,16 @@ using ManagedDescriptorSetLayout = VulkanRaii; using ManagedSemaphore = VulkanRaii; using ManagedFence = VulkanRaii; -using ManagedDebugUtilsMessenger = VulkanRaii; +using ManagedDebugUtilsMessenger = + VulkanRaii; // Helper functions to create RAII wrappers /** * Creates an RAII wrapper for a Vulkan instance */ -inline ManagedInstance MakeManagedInstance(const vk::Instance& instance, const vk::InstanceDispatch& dispatch) { +inline ManagedInstance MakeManagedInstance(const vk::Instance& instance, + const vk::InstanceDispatch& dispatch) { auto deleter = [](VkInstance handle, const vk::InstanceDispatch& dld) { dld.vkDestroyInstance(handle, nullptr); }; @@ -139,7 +140,8 @@ inline ManagedInstance MakeManagedInstance(const vk::Instance& instance, const v /** * Creates an RAII wrapper for a Vulkan device */ -inline ManagedDevice MakeManagedDevice(const vk::Device& device, const vk::DeviceDispatch& dispatch) { +inline ManagedDevice MakeManagedDevice(const vk::Device& device, + const vk::DeviceDispatch& dispatch) { auto deleter = [](VkDevice handle, const vk::DeviceDispatch& dld) { dld.vkDestroyDevice(handle, nullptr); }; @@ -149,8 +151,11 @@ inline ManagedDevice MakeManagedDevice(const vk::Device& device, const vk::Devic /** * Creates an RAII wrapper for a Vulkan surface */ -inline ManagedSurface MakeManagedSurface(const vk::SurfaceKHR& surface, const vk::Instance& instance, const vk::InstanceDispatch& dispatch) { - auto deleter = [instance_ptr = *instance](VkSurfaceKHR handle, const vk::InstanceDispatch& dld) { +inline ManagedSurface MakeManagedSurface(const vk::SurfaceKHR& surface, + const vk::Instance& instance, + const vk::InstanceDispatch& dispatch) { + auto deleter = [instance_ptr = *instance](VkSurfaceKHR handle, + const vk::InstanceDispatch& dld) { dld.vkDestroySurfaceKHR(instance_ptr, handle, nullptr); }; return ManagedSurface(*surface, deleter, dispatch, "VkSurfaceKHR"); @@ -159,10 +164,11 @@ inline ManagedSurface MakeManagedSurface(const vk::SurfaceKHR& surface, const vk /** * Creates an RAII wrapper for a Vulkan debug messenger */ -inline ManagedDebugUtilsMessenger MakeManagedDebugUtilsMessenger(const vk::DebugUtilsMessenger& messenger, - const vk::Instance& instance, - const vk::InstanceDispatch& dispatch) { - auto deleter = [instance_ptr = *instance](VkDebugUtilsMessengerEXT handle, const vk::InstanceDispatch& dld) { +inline ManagedDebugUtilsMessenger MakeManagedDebugUtilsMessenger( + const vk::DebugUtilsMessenger& messenger, const vk::Instance& instance, + const vk::InstanceDispatch& dispatch) { + auto deleter = [instance_ptr = *instance](VkDebugUtilsMessengerEXT handle, + const vk::InstanceDispatch& dld) { dld.vkDestroyDebugUtilsMessengerEXT(instance_ptr, handle, nullptr); }; return ManagedDebugUtilsMessenger(*messenger, deleter, dispatch, "VkDebugUtilsMessengerEXT"); @@ -171,7 +177,9 @@ inline ManagedDebugUtilsMessenger MakeManagedDebugUtilsMessenger(const vk::Debug /** * Creates an RAII wrapper for a Vulkan swapchain */ -inline ManagedSwapchain MakeManagedSwapchain(VkSwapchainKHR swapchain_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { +inline ManagedSwapchain MakeManagedSwapchain(VkSwapchainKHR swapchain_handle, + VkDevice device_handle, + const vk::DeviceDispatch& dispatch) { auto deleter = [device_handle](VkSwapchainKHR handle, const vk::DeviceDispatch& dld) { dld.vkDestroySwapchainKHR(device_handle, handle, nullptr); }; @@ -181,7 +189,8 @@ inline ManagedSwapchain MakeManagedSwapchain(VkSwapchainKHR swapchain_handle, Vk /** * Creates an RAII wrapper for a Vulkan buffer */ -inline ManagedBuffer MakeManagedBuffer(VkBuffer buffer_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { +inline ManagedBuffer MakeManagedBuffer(VkBuffer buffer_handle, VkDevice device_handle, + const vk::DeviceDispatch& dispatch) { auto deleter = [device_handle](VkBuffer handle, const vk::DeviceDispatch& dld) { dld.vkDestroyBuffer(device_handle, handle, nullptr); }; @@ -191,7 +200,8 @@ inline ManagedBuffer MakeManagedBuffer(VkBuffer buffer_handle, VkDevice device_h /** * Creates an RAII wrapper for a Vulkan image */ -inline ManagedImage MakeManagedImage(VkImage image_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { +inline ManagedImage MakeManagedImage(VkImage image_handle, VkDevice device_handle, + const vk::DeviceDispatch& dispatch) { auto deleter = [device_handle](VkImage handle, const vk::DeviceDispatch& dld) { dld.vkDestroyImage(device_handle, handle, nullptr); }; @@ -201,7 +211,8 @@ inline ManagedImage MakeManagedImage(VkImage image_handle, VkDevice device_handl /** * Creates an RAII wrapper for a Vulkan image view */ -inline ManagedImageView MakeManagedImageView(VkImageView view_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { +inline ManagedImageView MakeManagedImageView(VkImageView view_handle, VkDevice device_handle, + const vk::DeviceDispatch& dispatch) { auto deleter = [device_handle](VkImageView handle, const vk::DeviceDispatch& dld) { dld.vkDestroyImageView(device_handle, handle, nullptr); }; @@ -211,7 +222,8 @@ inline ManagedImageView MakeManagedImageView(VkImageView view_handle, VkDevice d /** * Creates an RAII wrapper for a Vulkan semaphore */ -inline ManagedSemaphore MakeManagedSemaphore(VkSemaphore semaphore_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { +inline ManagedSemaphore MakeManagedSemaphore(VkSemaphore semaphore_handle, VkDevice device_handle, + const vk::DeviceDispatch& dispatch) { auto deleter = [device_handle](VkSemaphore handle, const vk::DeviceDispatch& dld) { dld.vkDestroySemaphore(device_handle, handle, nullptr); }; @@ -221,7 +233,8 @@ inline ManagedSemaphore MakeManagedSemaphore(VkSemaphore semaphore_handle, VkDev /** * Creates an RAII wrapper for a Vulkan fence */ -inline ManagedFence MakeManagedFence(VkFence fence_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) { +inline ManagedFence MakeManagedFence(VkFence fence_handle, VkDevice device_handle, + const vk::DeviceDispatch& dispatch) { auto deleter = [device_handle](VkFence handle, const vk::DeviceDispatch& dld) { dld.vkDestroyFence(device_handle, handle, nullptr); }; diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index d12a1546e5..0bdf4407a6 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -240,6 +240,7 @@ struct DeviceDispatch : InstanceDispatch { PFN_vkCmdSetConservativeRasterizationModeEXT vkCmdSetConservativeRasterizationModeEXT{}; PFN_vkCmdSetLineRasterizationModeEXT vkCmdSetLineRasterizationModeEXT{}; PFN_vkCmdSetLineStippleEnableEXT vkCmdSetLineStippleEnableEXT{}; + PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT{}; PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{}; PFN_vkCmdSetLogicOpEnableEXT vkCmdSetLogicOpEnableEXT{}; PFN_vkCmdSetDepthClampEnableEXT vkCmdSetDepthClampEnableEXT{}; @@ -715,8 +716,8 @@ public: explicit Buffer(VkBuffer handle_, VkDevice owner_, VmaAllocator allocator_, VmaAllocation allocation_, std::span mapped_, bool is_coherent_, const DeviceDispatch& dld_) noexcept - : handle{handle_}, owner{owner_}, allocator{allocator_}, - allocation{allocation_}, mapped{mapped_}, is_coherent{is_coherent_}, dld{&dld_} {} + : handle{handle_}, owner{owner_}, allocator{allocator_}, allocation{allocation_}, + mapped{mapped_}, is_coherent{is_coherent_}, dld{&dld_} {} Buffer() = default; Buffer(const Buffer&) = delete; @@ -724,8 +725,8 @@ public: Buffer(Buffer&& rhs) noexcept : handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, allocator{rhs.allocator}, - allocation{rhs.allocation}, mapped{rhs.mapped}, - is_coherent{rhs.is_coherent}, dld{rhs.dld} {} + allocation{rhs.allocation}, mapped{rhs.mapped}, is_coherent{rhs.is_coherent}, + dld{rhs.dld} {} Buffer& operator=(Buffer&& rhs) noexcept { Release(); @@ -1437,21 +1438,24 @@ public: dld->vkCmdSetRasterizerDiscardEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); } - void SetConservativeRasterizationModeEXT(VkConservativeRasterizationModeEXT mode) const noexcept - { + void SetConservativeRasterizationModeEXT( + VkConservativeRasterizationModeEXT mode) const noexcept { dld->vkCmdSetConservativeRasterizationModeEXT(handle, mode); } - void SetLineRasterizationModeEXT(VkLineRasterizationModeEXT mode) const noexcept - { + void SetLineRasterizationModeEXT(VkLineRasterizationModeEXT mode) const noexcept { dld->vkCmdSetLineRasterizationModeEXT(handle, mode); } - void SetLineStippleEnableEXT(bool enable) const noexcept - { + void SetLineStippleEnableEXT(bool enable) const noexcept { dld->vkCmdSetLineStippleEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); } + void SetLineStippleEXT(u32 factor, u16 pattern) const noexcept + { + dld->vkCmdSetLineStippleEXT(handle, factor, pattern); + } + void SetDepthBiasEnableEXT(bool enable) const noexcept { dld->vkCmdSetDepthBiasEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); } diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index bab6a6c4f5..3755fe0c84 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -494,8 +494,6 @@ if (YUZU_ROOM) target_link_libraries(yuzu PRIVATE yuzu-room) endif() -# Extra deps -add_subdirectory(externals) -target_link_libraries(yuzu PRIVATE QuaZip::QuaZip) +target_link_libraries(yuzu PRIVATE libzip::zip) create_target_directory_groups(yuzu) diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp index 6ef3072894..f33561b25a 100644 --- a/src/yuzu/about_dialog.cpp +++ b/src/yuzu/about_dialog.cpp @@ -1,16 +1,14 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "yuzu/about_dialog.h" #include +#include #include "common/scm_rev.h" #include "ui_aboutdialog.h" -#include +#include "yuzu/about_dialog.h" AboutDialog::AboutDialog(QWidget* parent) - : QDialog(parent) - , ui{std::make_unique()} -{ + : QDialog(parent), ui{std::make_unique()} { const auto description = std::string(Common::g_build_version); const auto build_id = std::string(Common::g_build_id); @@ -21,9 +19,8 @@ AboutDialog::AboutDialog(QWidget* parent) yuzu_build = fmt::format("eden | {}", description); } - const auto override_build = fmt::format(fmt::runtime( - std::string(Common::g_title_bar_format_idle)), - build_id); + const auto override_build = + fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build; ui->setupUi(this); diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index 48ce860ad7..bafb2b7c94 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp @@ -184,14 +184,15 @@ QtControllerSelectorDialog::QtControllerSelectorDialog( CheckIfParametersMet(); }); - connect(connected_controller_checkboxes[i], &QCheckBox::stateChanged, [this, i](int state) { - player_groupboxes[i]->setChecked(state == Qt::Checked); - UpdateControllerIcon(i); - UpdateControllerState(i); - UpdateLEDPattern(i); - UpdateBorderColor(i); - CheckIfParametersMet(); - }); + connect(connected_controller_checkboxes[i], &QCheckBox::checkStateChanged, + [this, i](Qt::CheckState state) { + player_groupboxes[i]->setChecked(state == Qt::Checked); + UpdateControllerIcon(i); + UpdateControllerState(i); + UpdateLEDPattern(i); + UpdateBorderColor(i); + CheckIfParametersMet(); + }); if (i == 0) { connect(emulated_controllers[i], qOverload(&QComboBox::currentIndexChanged), diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp index 8245c12ba2..53e495e461 100644 --- a/src/yuzu/applets/qt_web_browser.cpp +++ b/src/yuzu/applets/qt_web_browser.cpp @@ -54,8 +54,8 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system, : QWebEngineView(parent), input_subsystem{input_subsystem_}, url_interceptor(std::make_unique()), input_interpreter(std::make_unique(system)), - default_profile{QWebEngineProfile::defaultProfile()}, global_settings{ - default_profile->settings()} { + default_profile{QWebEngineProfile::defaultProfile()}, + global_settings{default_profile->settings()} { default_profile->setPersistentStoragePath(QString::fromStdString(Common::FS::PathToUTF8String( Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir) / "qtwebengine"))); diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index d14c46af86..67920fb552 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -284,8 +284,8 @@ struct NullRenderWidget : public RenderWidget { GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_, std::shared_ptr input_subsystem_, Core::System& system_) - : QWidget(parent), - emu_thread(emu_thread_), input_subsystem{std::move(input_subsystem_)}, system{system_} { + : QWidget(parent), emu_thread(emu_thread_), input_subsystem{std::move(input_subsystem_)}, + system{system_} { setWindowTitle(QStringLiteral("eden %1 | %2-%3") .arg(QString::fromUtf8(Common::g_build_name), QString::fromUtf8(Common::g_scm_branch), @@ -1122,9 +1122,21 @@ void GRenderWindow::OnEmulationStopping() { void GRenderWindow::showEvent(QShowEvent* event) { QWidget::showEvent(event); - // windowHandle() is not initialized until the Window is shown, so we connect it here. - connect(windowHandle(), &QWindow::screenChanged, this, &GRenderWindow::OnFramebufferSizeChanged, - Qt::UniqueConnection); + QWindow* window = windowHandle(); + if (!window) { + QWidget* nativeParent = nativeParentWidget(); + if (nativeParent) { + window = nativeParent->windowHandle(); + } + } + if (!window) { + LOG_ERROR(Frontend, "Failed to acquire QWindow pointer of GRenderWindow. ScreenChanged " + "signal not connected."); + } else { + // windowHandle() is not initialized until the Window is shown, so we connect it here. + connect(window, &QWindow::screenChanged, this, &GRenderWindow::OnFramebufferSizeChanged, + Qt::UniqueConnection); + } } bool GRenderWindow::eventFilter(QObject* object, QEvent* event) { diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 987b1462db..dd22bf1b4c 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -33,9 +33,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, InputCommon::InputSubsystem* input_subsystem, std::vector& vk_device_records, Core::System& system_, bool enable_web_config) - : QDialog(parent), ui{std::make_unique()}, - registry(registry_), system{system_}, builder{std::make_unique( - this, !system_.IsPoweredOn())}, + : QDialog(parent), ui{std::make_unique()}, registry(registry_), + system{system_}, + builder{std::make_unique(this, !system_.IsPoweredOn())}, applets_tab{std::make_unique(system_, nullptr, *builder, this)}, audio_tab{std::make_unique(system_, nullptr, *builder, this)}, cpu_tab{std::make_unique(system_, nullptr, *builder, this)}, @@ -43,9 +43,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, filesystem_tab{std::make_unique(this)}, general_tab{std::make_unique(system_, nullptr, *builder, this)}, graphics_advanced_tab{ - std::make_unique(system_, nullptr, *builder, this)}, + std::make_unique(system_, nullptr, *builder, this)}, graphics_extensions_tab{ - std::make_unique(system_, nullptr, *builder, this)}, + std::make_unique(system_, nullptr, *builder, this)}, ui_tab{std::make_unique(system_, this)}, graphics_tab{std::make_unique( system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, @@ -108,7 +108,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, adjustSize(); ui->selectorList->setCurrentRow(0); - // Selects the leftmost button on the bottom bar (Cancel as of writing) + // Selects the leftmost button on the bottom bar (Cancel as of writing) ui->buttonBox->setFocus(); } @@ -167,16 +167,17 @@ Q_DECLARE_METATYPE(QList); void ConfigureDialog::PopulateSelectionList() { const std::array>, 6> items{ - {{tr("General"), - {general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}}, - {tr("System"), - {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(), - applets_tab.get()}}, - {tr("CPU"), {cpu_tab.get()}}, - {tr("Graphics"), {graphics_tab.get(), graphics_advanced_tab.get(), graphics_extensions_tab.get()}}, - {tr("Audio"), {audio_tab.get()}}, - {tr("Controls"), input_tab->GetSubTabs()}}, - }; + {{tr("General"), + {general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}}, + {tr("System"), + {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(), + applets_tab.get()}}, + {tr("CPU"), {cpu_tab.get()}}, + {tr("Graphics"), + {graphics_tab.get(), graphics_advanced_tab.get(), graphics_extensions_tab.get()}}, + {tr("Audio"), {audio_tab.get()}}, + {tr("Controls"), input_tab->GetSubTabs()}}, + }; [[maybe_unused]] const QSignalBlocker blocker(ui->selectorList); diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp index f25f14708b..80f8d1816d 100644 --- a/src/yuzu/configuration/configure_filesystem.cpp +++ b/src/yuzu/configuration/configure_filesystem.cpp @@ -29,9 +29,9 @@ ConfigureFilesystem::ConfigureFilesystem(QWidget* parent) connect(ui->reset_game_list_cache, &QPushButton::pressed, this, &ConfigureFilesystem::ResetMetadata); - connect(ui->gamecard_inserted, &QCheckBox::stateChanged, this, + connect(ui->gamecard_inserted, &QCheckBox::checkStateChanged, this, &ConfigureFilesystem::UpdateEnabledControls); - connect(ui->gamecard_current_game, &QCheckBox::stateChanged, this, + connect(ui->gamecard_current_game, &QCheckBox::checkStateChanged, this, &ConfigureFilesystem::UpdateEnabledControls); } diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index 61491c0ab7..070841a3d4 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -2,10 +2,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include -#include #include +#include #include +#include #include "common/settings.h" #include "core/core.h" #include "ui_configure_graphics_extensions.h" @@ -17,7 +17,8 @@ ConfigureGraphicsExtensions::ConfigureGraphicsExtensions( const Core::System& system_, std::shared_ptr> group_, const ConfigurationShared::Builder& builder, QWidget* parent) - : Tab(group_, parent), ui{std::make_unique()}, system{system_} { + : Tab(group_, parent), ui{std::make_unique()}, + system{system_} { ui->setupUi(this); diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 28c3baf086..b7067ef827 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -121,10 +121,11 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, &ConfigureInput::UpdateAllInputDevices); connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputProfiles, this, &ConfigureInput::UpdateAllInputProfiles, Qt::QueuedConnection); - connect(connected_controller_checkboxes[i], &QCheckBox::stateChanged, [this, i](int state) { - // Keep activated controllers synced with the "Connected Controllers" checkboxes - player_controllers[i]->ConnectPlayer(state == Qt::Checked); - }); + connect(connected_controller_checkboxes[i], &QCheckBox::checkStateChanged, + [this, i](Qt::CheckState state) { + // Keep activated controllers synced with the "Connected Controllers" checkboxes + player_controllers[i]->ConnectPlayer(state == Qt::Checked); + }); // Remove/hide all the elements that exceed max_players, if applicable. if (i >= max_players) { diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index d6c4e09ec0..b9ff58bf7b 100644 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -74,13 +74,13 @@ ConfigureInputAdvanced::ConfigureInputAdvanced(Core::HID::HIDCore& hid_core_, QW } } - connect(ui->mouse_enabled, &QCheckBox::stateChanged, this, + connect(ui->mouse_enabled, &QCheckBox::checkStateChanged, this, &ConfigureInputAdvanced::UpdateUIEnabled); - connect(ui->debug_enabled, &QCheckBox::stateChanged, this, + connect(ui->debug_enabled, &QCheckBox::checkStateChanged, this, &ConfigureInputAdvanced::UpdateUIEnabled); - connect(ui->touchscreen_enabled, &QCheckBox::stateChanged, this, + connect(ui->touchscreen_enabled, &QCheckBox::checkStateChanged, this, &ConfigureInputAdvanced::UpdateUIEnabled); - connect(ui->enable_ring_controller, &QCheckBox::stateChanged, this, + connect(ui->enable_ring_controller, &QCheckBox::checkStateChanged, this, &ConfigureInputAdvanced::UpdateUIEnabled); connect(ui->debug_configure, &QPushButton::clicked, this, diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 12fe935e41..8e0182023b 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -293,11 +293,11 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i InputCommon::InputSubsystem* input_subsystem_, InputProfiles* profiles_, Core::HID::HIDCore& hid_core_, bool is_powered_on_, bool debug_) - : QWidget(parent), - ui(std::make_unique()), player_index{player_index_}, debug{debug_}, - is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, profiles(profiles_), - timeout_timer(std::make_unique()), - poll_timer(std::make_unique()), bottom_row{bottom_row_}, hid_core{hid_core_} { + : QWidget(parent), ui(std::make_unique()), + player_index{player_index_}, debug{debug_}, is_powered_on{is_powered_on_}, + input_subsystem{input_subsystem_}, profiles(profiles_), + timeout_timer(std::make_unique()), poll_timer(std::make_unique()), + bottom_row{bottom_row_}, hid_core{hid_core_} { if (player_index == 0) { auto* emulated_controller_p1 = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); @@ -1214,10 +1214,8 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { case Core::HID::NpadStyleIndex::Fullkey: case Core::HID::NpadStyleIndex::Handheld: layout_hidden = { - ui->buttonShoulderButtonsSLSRLeft, - ui->buttonShoulderButtonsSLSRRight, - ui->horizontalSpacerShoulderButtonsWidget2, - ui->horizontalSpacerShoulderButtonsWidget4, + ui->buttonShoulderButtonsSLSRLeft, ui->buttonShoulderButtonsSLSRRight, + ui->horizontalSpacerShoulderButtonsWidget2, ui->horizontalSpacerShoulderButtonsWidget4, ui->buttonMiscButtonsScreenshotGroup, }; break; diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 031a8d4c2d..6508f032f5 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -45,8 +45,8 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, std::vector& vk_device_records, Core::System& system_) - : QDialog(parent), - ui(std::make_unique()), title_id{title_id_}, system{system_}, + : QDialog(parent), ui(std::make_unique()), title_id{title_id_}, + system{system_}, builder{std::make_unique(this, !system_.IsPoweredOn())}, tab_group{std::make_shared>()} { const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name)); diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index f009800d52..9b920af9e7 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp @@ -32,8 +32,8 @@ #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/filesystem/filesystem.h" #include "ui_configure_profile_manager.h" -#include "yuzu/util/limitable_input_dialog.h" #include "yuzu/configuration/configure_profile_manager.h" +#include "yuzu/util/limitable_input_dialog.h" namespace { // Same backup JPEG used by acc IProfile::GetImage if no jpeg found diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index e193b5f95b..2791a4e5d1 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -83,7 +83,8 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, connect(combo_language, qOverload(&QComboBox::currentIndexChanged), this, locale_check); connect(combo_region, qOverload(&QComboBox::currentIndexChanged), this, locale_check); - connect(checkbox_rtc, qOverload(&QCheckBox::stateChanged), this, update_rtc_date); + connect(checkbox_rtc, qOverload(&QCheckBox::checkStateChanged), this, + update_rtc_date); connect(date_rtc_offset, qOverload(&QSpinBox::valueChanged), this, update_rtc_date); connect(date_rtc, &QDateTimeEdit::dateTimeChanged, this, update_date_offset); diff --git a/src/yuzu/configuration/configure_touch_from_button.cpp b/src/yuzu/configuration/configure_touch_from_button.cpp index a6237ab72f..7810a66e97 100644 --- a/src/yuzu/configuration/configure_touch_from_button.cpp +++ b/src/yuzu/configuration/configure_touch_from_button.cpp @@ -548,9 +548,8 @@ bool TouchScreenPreview::eventFilter(QObject* obj, QEvent* event) { } const auto mouse_event = static_cast(event); if (!drag_state.active) { - drag_state.active = - (mouse_event->globalPosition().toPoint() - drag_state.start_pos).manhattanLength() >= - QApplication::startDragDistance(); + drag_state.active = (mouse_event->globalPosition().toPoint() - drag_state.start_pos) + .manhattanLength() >= QApplication::startDragDistance(); if (!drag_state.active) { break; } diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index 8dafee628b..bc660b1901 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp @@ -119,11 +119,15 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) SetConfiguration(); // Force game list reload if any of the relevant settings are changed. - connect(ui->show_add_ons, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); - connect(ui->show_compat, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); - connect(ui->show_size, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); - connect(ui->show_types, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate); - connect(ui->show_play_time, &QCheckBox::stateChanged, this, + connect(ui->show_add_ons, &QCheckBox::checkStateChanged, this, + &ConfigureUi::RequestGameListUpdate); + connect(ui->show_compat, &QCheckBox::checkStateChanged, this, + &ConfigureUi::RequestGameListUpdate); + connect(ui->show_size, &QCheckBox::checkStateChanged, this, + &ConfigureUi::RequestGameListUpdate); + connect(ui->show_types, &QCheckBox::checkStateChanged, this, + &ConfigureUi::RequestGameListUpdate); + connect(ui->show_play_time, &QCheckBox::checkStateChanged, this, &ConfigureUi::RequestGameListUpdate); connect(ui->game_icon_size_combobox, QOverload::of(&QComboBox::currentIndexChanged), this, &ConfigureUi::RequestGameListUpdate); diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp index d62b5b0853..04fa6d2770 100644 --- a/src/yuzu/configuration/configure_web.cpp +++ b/src/yuzu/configuration/configure_web.cpp @@ -4,9 +4,9 @@ // SPDX-FileCopyrightText: 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "yuzu/configuration/configure_web.h" #include #include +#include "yuzu/configuration/configure_web.h" #if QT_VERSION_MAJOR >= 6 #include @@ -20,24 +20,21 @@ #include "yuzu/uisettings.h" ConfigureWeb::ConfigureWeb(QWidget* parent) - : QWidget(parent) - , ui(std::make_unique()) - , m_rng{QRandomGenerator::system()} -{ + : QWidget(parent), ui(std::make_unique()), m_rng{QRandomGenerator::system()} { ui->setupUi(this); QString user_regex = QStringLiteral(".{4,20}"); QString token_regex = QStringLiteral("[a-z]{48}"); #if QT_VERSION_MAJOR >= 6 - QRegularExpressionValidator *username_validator = new QRegularExpressionValidator(this); - QRegularExpressionValidator *token_validator = new QRegularExpressionValidator(this); + QRegularExpressionValidator* username_validator = new QRegularExpressionValidator(this); + QRegularExpressionValidator* token_validator = new QRegularExpressionValidator(this); username_validator->setRegularExpression(QRegularExpression(user_regex)); token_validator->setRegularExpression(QRegularExpression(token_regex)); #else - QRegExpValidator *username_validator = new QRegExpValidator(this); - QRegExpValidator *token_validator = new QRegExpValidator(this); + QRegExpValidator* username_validator = new QRegExpValidator(this); + QRegExpValidator* token_validator = new QRegExpValidator(this); username_validator->setRegExp(QRegExp(user_regex)); token_validator->setRegExp(QRegExp(token_regex)); @@ -121,7 +118,8 @@ void ConfigureWeb::VerifyLogin() { ui->label_token_verified->setToolTip(tr("All Good", "Tooltip")); } else { ui->label_token_verified->setPixmap(failed); - ui->label_token_verified->setToolTip(tr("Must be 48 characters, and lowercase a-z", "Tooltip")); + ui->label_token_verified->setToolTip( + tr("Must be 48 characters, and lowercase a-z", "Tooltip")); } } diff --git a/src/yuzu/configuration/configure_web.h b/src/yuzu/configuration/configure_web.h index 3da7e5eccc..d2c969cc56 100644 --- a/src/yuzu/configuration/configure_web.h +++ b/src/yuzu/configuration/configure_web.h @@ -8,8 +8,8 @@ #include -#include #include +#include namespace Ui { class ConfigureWeb; @@ -32,7 +32,7 @@ private: void SetConfiguration(); std::unique_ptr ui; - QRandomGenerator *m_rng; + QRandomGenerator* m_rng; private slots: void GenerateToken(); diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index c743e65ae3..29c2f94fca 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -9,6 +9,10 @@ #include "yuzu/configuration/shared_translation.h" +#include +#include +#include +#include #include #include #include "common/settings.h" @@ -16,19 +20,14 @@ #include "common/settings_setting.h" #include "common/time_zone.h" #include "yuzu/uisettings.h" -#include -#include -#include -#include namespace ConfigurationShared { -std::unique_ptr InitializeTranslations(QWidget* parent) -{ +std::unique_ptr InitializeTranslations(QWidget* parent) { std::unique_ptr translations = std::make_unique(); const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); }; -#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \ +#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \ translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{(NAME), (TOOLTIP)}}) // A setting can be ignored by giving it a blank name @@ -61,56 +60,44 @@ std::unique_ptr InitializeTranslations(QWidget* parent) // Core INSERT( - Settings, - use_multi_core, - tr("Multicore CPU Emulation"), + Settings, use_multi_core, tr("Multicore CPU Emulation"), tr("This option increases CPU emulation thread use from 1 to the Switch’s maximum of 4.\n" "This is mainly a debug option and shouldn’t be disabled.")); INSERT( - Settings, - memory_layout_mode, - tr("Memory Layout"), + Settings, memory_layout_mode, tr("Memory Layout"), tr("Increases the amount of emulated RAM from the stock 4GB of the retail Switch to the " "developer kit's 8/6GB.\nIt’s doesn’t improve stability or performance and is intended " "to let big texture mods fit in emulated RAM.\nEnabling it will increase memory " "use. It is not recommended to enable unless a specific game with a texture mod needs " "it.")); INSERT(Settings, use_speed_limit, QString(), QString()); - INSERT(Settings, - speed_limit, - tr("Limit Speed Percent"), + INSERT(Settings, speed_limit, tr("Limit Speed Percent"), tr("Controls the game's maximum rendering speed, but it’s up to each game if it runs " "faster or not.\n200% for a 30 FPS game is 60 FPS, and for a " "60 FPS game it will be 120 FPS.\nDisabling it means unlocking the framerate to the " "maximum your PC can reach.")); - INSERT(Settings, - sync_core_speed, - tr("Synchronize Core Speed"), + INSERT(Settings, sync_core_speed, tr("Synchronize Core Speed"), tr("Synchronizes CPU core speed with the game's maximum rendering speed to boost FPS " "without affecting game speed (animations, physics, etc.).\n" "Compatibility varies by game; many (especially older ones) may not respond well.\n" "Can help reduce stuttering at lower framerates.")); // Cpu - INSERT(Settings, - cpu_accuracy, - tr("Accuracy:"), + INSERT(Settings, cpu_accuracy, tr("Accuracy:"), tr("This setting controls the accuracy of the emulated CPU.\nDon't change this unless " "you know what you are doing.")); INSERT(Settings, cpu_backend, tr("Backend:"), QString()); INSERT(Settings, use_fast_cpu_time, QString(), QString()); - INSERT(Settings, - fast_cpu_time, - tr("Fast CPU Time"), - tr("Overclocks the emulated CPU to remove some FPS limiters. Weaker CPUs may see reduced performance, " - "and certain games may behave improperly.\nUse Boost (1700MHz) to run at the Switch's highest native " + INSERT(Settings, fast_cpu_time, tr("Fast CPU Time"), + tr("Overclocks the emulated CPU to remove some FPS limiters. Weaker CPUs may see " + "reduced performance, " + "and certain games may behave improperly.\nUse Boost (1700MHz) to run at the " + "Switch's highest native " "clock, or Fast (2000MHz) to run at 2x clock.")); INSERT(Settings, use_custom_cpu_ticks, QString(), QString()); - INSERT(Settings, - cpu_ticks, - tr("Custom CPU Ticks"), + INSERT(Settings, cpu_ticks, tr("Custom CPU Ticks"), tr("Set a custom value of CPU ticks. Higher values can increase performance, but may " "also cause the game to freeze. A range of 77–21000 is recommended.")); INSERT(Settings, cpu_backend, tr("Backend:"), QString()); @@ -119,115 +106,79 @@ std::unique_ptr InitializeTranslations(QWidget* parent) // Cpu Unsafe INSERT( - Settings, - cpuopt_unsafe_unfuse_fma, + Settings, cpuopt_unsafe_unfuse_fma, tr("Unfuse FMA (improve performance on CPUs without FMA)"), tr("This option improves speed by reducing accuracy of fused-multiply-add instructions on " "CPUs without native FMA support.")); INSERT( - Settings, - cpuopt_unsafe_reduce_fp_error, - tr("Faster FRSQRTE and FRECPE"), + Settings, cpuopt_unsafe_reduce_fp_error, tr("Faster FRSQRTE and FRECPE"), tr("This option improves the speed of some approximate floating-point functions by using " "less accurate native approximations.")); - INSERT(Settings, - cpuopt_unsafe_ignore_standard_fpcr, + INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr, tr("Faster ASIMD instructions (32 bits only)"), tr("This option improves the speed of 32 bits ASIMD floating-point functions by running " "with incorrect rounding modes.")); - INSERT(Settings, - cpuopt_unsafe_inaccurate_nan, - tr("Inaccurate NaN handling"), + INSERT(Settings, cpuopt_unsafe_inaccurate_nan, tr("Inaccurate NaN handling"), tr("This option improves speed by removing NaN checking.\nPlease note this also reduces " "accuracy of certain floating-point instructions.")); - INSERT(Settings, - cpuopt_unsafe_fastmem_check, - tr("Disable address space checks"), + INSERT(Settings, cpuopt_unsafe_fastmem_check, tr("Disable address space checks"), tr("This option improves speed by eliminating a safety check before every memory " "read/write in guest.\nDisabling it may allow a game to read/write the emulator's " "memory.")); INSERT( - Settings, - cpuopt_unsafe_ignore_global_monitor, - tr("Ignore global monitor"), + Settings, cpuopt_unsafe_ignore_global_monitor, tr("Ignore global monitor"), tr("This option improves speed by relying only on the semantics of cmpxchg to ensure " "safety of exclusive access instructions.\nPlease note this may result in deadlocks and " "other race conditions.")); // Renderer INSERT( - Settings, - renderer_backend, - tr("API:"), + Settings, renderer_backend, tr("API:"), tr("Switches between the available graphics APIs.\nVulkan is recommended in most cases.")); - INSERT(Settings, - vulkan_device, - tr("Device:"), + INSERT(Settings, vulkan_device, tr("Device:"), tr("This setting selects the GPU to use with the Vulkan backend.")); - INSERT(Settings, - shader_backend, - tr("Shader Backend:"), + INSERT(Settings, shader_backend, tr("Shader Backend:"), tr("The shader backend to use for the OpenGL renderer.\nGLSL is the fastest in " "performance and the best in rendering accuracy.\n" "GLASM is a deprecated NVIDIA-only backend that offers much better shader building " "performance at the cost of FPS and rendering accuracy.\n" "SPIR-V compiles the fastest, but yields poor results on most GPU drivers.")); - INSERT(Settings, - resolution_setup, - tr("Resolution:"), + INSERT(Settings, resolution_setup, tr("Resolution:"), tr("Forces the game to render at a different resolution.\nHigher resolutions require " "much more VRAM and bandwidth.\n" "Options lower than 1X can cause rendering issues.")); INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QString()); - INSERT(Settings, - fsr_sharpening_slider, - tr("FSR Sharpness:"), + INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), tr("Determines how sharpened the image will look while using FSR’s dynamic contrast.")); - INSERT(Settings, - anti_aliasing, - tr("Anti-Aliasing Method:"), + INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA has a " "lower performance impact and can produce a better and more stable picture under " "very low resolutions.")); - INSERT(Settings, - fullscreen_mode, - tr("Fullscreen Mode:"), + INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"), tr("The method used to render the window in fullscreen.\nBorderless offers the best " "compatibility with the on-screen keyboard that some games request for " "input.\nExclusive " "fullscreen may offer better performance and better Freesync/Gsync support.")); - INSERT(Settings, - aspect_ratio, - tr("Aspect Ratio:"), + INSERT(Settings, aspect_ratio, tr("Aspect Ratio:"), tr("Stretches the game to fit the specified aspect ratio.\nSwitch games only support " "16:9, so custom game mods are required to get other ratios.\nAlso controls the " "aspect ratio of captured screenshots.")); - INSERT(Settings, - use_disk_shader_cache, - tr("Use disk pipeline cache"), + INSERT(Settings, use_disk_shader_cache, tr("Use disk pipeline cache"), tr("Allows saving shaders to storage for faster loading on following game " "boots.\nDisabling " "it is only intended for debugging.")); - INSERT(Settings, - optimize_spirv_output, - tr("Optimize SPIRV output shader"), + INSERT(Settings, optimize_spirv_output, tr("Optimize SPIRV output shader"), tr("Runs an additional optimization pass over generated SPIRV shaders.\n" "Will increase time required for shader compilation.\nMay slightly improve " "performance.\nThis feature is experimental.")); INSERT( - Settings, - use_asynchronous_gpu_emulation, - tr("Use asynchronous GPU emulation"), + Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled.")); - INSERT(Settings, - nvdec_emulation, - tr("NVDEC emulation:"), + INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), tr("Specifies how videos should be decoded.\nIt can either use the CPU or the GPU for " "decoding, or perform no decoding at all (black screen on videos).\n" "In most cases, GPU decoding provides the best performance.")); - INSERT(Settings, - accelerate_astc, - tr("ASTC Decoding Method:"), + INSERT(Settings, accelerate_astc, tr("ASTC Decoding Method:"), tr("This option controls how ASTC textures should be decoded.\n" "CPU: Use the CPU for decoding, slowest but safest method.\n" "GPU: Use the GPU's compute shaders to decode ASTC textures, recommended for most " @@ -236,29 +187,22 @@ std::unique_ptr InitializeTranslations(QWidget* parent) "eliminates ASTC decoding\nstuttering at the cost of rendering issues while the " "texture is being decoded.")); INSERT( - Settings, - astc_recompression, - tr("ASTC Recompression Method:"), + Settings, astc_recompression, tr("ASTC Recompression Method:"), tr("Almost all desktop and laptop dedicated GPUs lack support for ASTC textures, forcing " "the emulator to decompress to an intermediate format any card supports, RGBA8.\n" "This option recompresses RGBA8 to either the BC1 or BC3 format, saving VRAM but " "negatively affecting image quality.")); - INSERT(Settings, - vram_usage_mode, - tr("VRAM Usage Mode:"), + INSERT(Settings, vram_usage_mode, tr("VRAM Usage Mode:"), tr("Selects whether the emulator should prefer to conserve memory or make maximum usage " "of available video memory for performance. Has no effect on integrated graphics. " "Aggressive mode may severely impact the performance of other applications such as " "recording software.")); - INSERT(Settings, - skip_cpu_inner_invalidation, - tr("Skip CPU Inner Invalidation"), - tr("Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and " + INSERT(Settings, skip_cpu_inner_invalidation, tr("Skip CPU Inner Invalidation"), + tr("Skips certain CPU-side cache invalidations during memory updates, reducing CPU " + "usage and " "improving it's performance. This may cause glitches or crashes on some games.")); INSERT( - Settings, - vsync_mode, - tr("VSync Mode:"), + Settings, vsync_mode, tr("VSync Mode:"), tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " "refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from " "a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop " @@ -269,134 +213,94 @@ std::unique_ptr InitializeTranslations(QWidget* parent) INSERT(Settings, bg_blue, QString(), QString()); // Renderer (Advanced Graphics) - INSERT(Settings, - async_presentation, - tr("Enable asynchronous presentation (Vulkan only)"), + INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"), tr("Slightly improves performance by moving presentation to a separate CPU thread.")); INSERT( - Settings, - renderer_force_max_clock, - tr("Force maximum clocks (Vulkan only)"), + Settings, renderer_force_max_clock, tr("Force maximum clocks (Vulkan only)"), tr("Runs work in the background while waiting for graphics commands to keep the GPU from " "lowering its clock speed.")); - INSERT(Settings, - max_anisotropy, - tr("Anisotropic Filtering:"), + INSERT(Settings, max_anisotropy, tr("Anisotropic Filtering:"), tr("Controls the quality of texture rendering at oblique angles.\nIt’s a light setting " "and safe to set at 16x on most GPUs.")); - INSERT(Settings, - gpu_accuracy, - tr("Accuracy Level:"), + INSERT(Settings, gpu_accuracy, tr("Accuracy Level:"), tr("GPU emulation accuracy.\nMost games render fine with Normal, but High is still " "required for some.\nParticles tend to only render correctly with High " "accuracy.\nExtreme should only be used for debugging.\nThis option can " "be changed while playing.\nSome games may require booting on high to render " "properly.")); - INSERT(Settings, - use_asynchronous_shaders, - tr("Use asynchronous shader building (Hack)"), + INSERT(Settings, use_asynchronous_shaders, tr("Use asynchronous shader building (Hack)"), tr("Enables asynchronous shader compilation, which may reduce shader stutter.\nThis " "feature " "is experimental.")); INSERT(Settings, use_fast_gpu_time, QString(), QString()); - INSERT(Settings, - fast_gpu_time, - tr("Fast GPU Time (Hack)"), + INSERT(Settings, fast_gpu_time, tr("Fast GPU Time (Hack)"), tr("Overclocks the emulated GPU to increase dynamic resolution and render " "distance.\nUse 128 for maximal performance and 512 for maximal graphics fidelity.")); - INSERT(Settings, - use_vulkan_driver_pipeline_cache, - tr("Use Vulkan pipeline cache"), + INSERT(Settings, use_vulkan_driver_pipeline_cache, tr("Use Vulkan pipeline cache"), tr("Enables GPU vendor-specific pipeline cache.\nThis option can improve shader loading " "time significantly in cases where the Vulkan driver does not store pipeline cache " "files internally.")); INSERT( - Settings, - enable_compute_pipelines, - tr("Enable Compute Pipelines (Intel Vulkan Only)"), + Settings, enable_compute_pipelines, tr("Enable Compute Pipelines (Intel Vulkan Only)"), tr("Enable compute pipelines, required by some games.\nThis setting only exists for Intel " "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled " "on all other drivers.")); INSERT( - Settings, - use_reactive_flushing, - tr("Enable Reactive Flushing"), + Settings, use_reactive_flushing, tr("Enable Reactive Flushing"), tr("Uses reactive flushing instead of predictive flushing, allowing more accurate memory " "syncing.")); - INSERT(Settings, - use_video_framerate, - tr("Sync to framerate of video playback"), + INSERT(Settings, use_video_framerate, tr("Sync to framerate of video playback"), tr("Run the game at normal speed during video playback, even when the framerate is " "unlocked.")); - INSERT(Settings, - barrier_feedback_loops, - tr("Barrier feedback loops"), + INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"), tr("Improves rendering of transparency effects in specific games.")); // Renderer (Extensions) - INSERT(Settings, - enable_raii, - tr("RAII"), + INSERT(Settings, enable_raii, tr("RAII"), tr("A method of automatic resource management in Vulkan " "that ensures proper release of resources " "when they are no longer needed, but may cause crashes in bundled games.")); - INSERT(Settings, - dyna_state, - tr("Extended Dynamic State"), + INSERT(Settings, dyna_state, tr("Extended Dynamic State"), tr("Enables the VkExtendedDynamicState* extensions.\nHigher dynamic states will " "generally improve " "performance, but may cause issues on certain games or devices.")); - INSERT(Settings, - provoking_vertex, - tr("Provoking Vertex"), + INSERT(Settings, provoking_vertex, tr("Provoking Vertex"), tr("Improves lighting and vertex handling in certain games.\n" "Only Vulkan 1.0+ devices support this extension.")); - INSERT(Settings, - descriptor_indexing, - tr("Descriptor Indexing"), + INSERT(Settings, descriptor_indexing, tr("Descriptor Indexing"), tr("Improves texture & buffer handling and the Maxwell translation layer.\n" "Some Vulkan 1.1+ and all 1.2+ devices support this extension.")); - INSERT(Settings, - sample_shading, - tr("Sample Shading"), - tr("Allows the fragment shader to execute per sample in a multi-sampled fragment " - "instead once per fragment. Improves graphics quality at the cost of some performance.\n" - "Only Vulkan 1.1+ devices support this extension.")); + INSERT( + Settings, sample_shading, tr("Sample Shading"), + tr("Allows the fragment shader to execute per sample in a multi-sampled fragment " + "instead once per fragment. Improves graphics quality at the cost of some performance.\n" + "Only Vulkan 1.1+ devices support this extension.")); // Renderer (Debug) // System - INSERT(Settings, - rng_seed, - tr("RNG Seed"), + INSERT(Settings, rng_seed, tr("RNG Seed"), tr("Controls the seed of the random number generator.\nMainly used for speedrunning " "purposes.")); INSERT(Settings, rng_seed_enabled, QString(), QString()); INSERT(Settings, device_name, tr("Device Name"), tr("The name of the emulated Switch.")); - INSERT(Settings, - custom_rtc, - tr("Custom RTC Date:"), + INSERT(Settings, custom_rtc, tr("Custom RTC Date:"), tr("This option allows to change the emulated clock of the Switch.\n" "Can be used to manipulate time in games.")); INSERT(Settings, custom_rtc_enabled, QString(), QString()); - INSERT(Settings, - custom_rtc_offset, - QStringLiteral(" "), + INSERT(Settings, custom_rtc_offset, QStringLiteral(" "), QStringLiteral("The number of seconds from the current unix time")); - INSERT(Settings, - language_index, - tr("Language:"), + INSERT(Settings, language_index, tr("Language:"), tr("Note: this can be overridden when region setting is auto-select")); INSERT(Settings, region_index, tr("Region:"), tr("The region of the emulated Switch.")); - INSERT(Settings, time_zone_index, tr("Time Zone:"), tr("The time zone of the emulated Switch.")); + INSERT(Settings, time_zone_index, tr("Time Zone:"), + tr("The time zone of the emulated Switch.")); INSERT(Settings, sound_index, tr("Sound Output Mode:"), QString()); - INSERT(Settings, - use_docked_mode, - tr("Console Mode:"), + INSERT(Settings, use_docked_mode, tr("Console Mode:"), tr("Selects if the console is emulated in Docked or Handheld mode.\nGames will change " "their resolution, details and supported controllers and depending on this setting.\n" "Setting to Handheld can help improve performance for low end systems.")); @@ -417,32 +321,20 @@ std::unique_ptr InitializeTranslations(QWidget* parent) // Ui // Ui General - INSERT(UISettings, - select_user_on_boot, - tr("Prompt for user on game boot"), + INSERT(UISettings, select_user_on_boot, tr("Prompt for user on game boot"), tr("Ask to select a user profile on each boot, useful if multiple people use eden on " "the same PC.")); - INSERT(UISettings, - pause_when_in_background, - tr("Pause emulation when in background"), + INSERT(UISettings, pause_when_in_background, tr("Pause emulation when in background"), tr("This setting pauses eden when focusing other windows.")); - INSERT(UISettings, - confirm_before_stopping, - tr("Confirm before stopping emulation"), + INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"), tr("This setting overrides game prompts asking to confirm stopping the game.\nEnabling " "it bypasses such prompts and directly exits the emulation.")); - INSERT(UISettings, - hide_mouse, - tr("Hide mouse on inactivity"), + INSERT(UISettings, hide_mouse, tr("Hide mouse on inactivity"), tr("This setting hides the mouse after 2.5s of inactivity.")); - INSERT(UISettings, - controller_applet_disabled, - tr("Disable controller applet"), + INSERT(UISettings, controller_applet_disabled, tr("Disable controller applet"), tr("Forcibly disables the use of the controller applet by guests.\nWhen a guest " "attempts to open the controller applet, it is immediately closed.")); - INSERT(UISettings, - check_for_updates, - tr("Check for updates"), + INSERT(UISettings, check_for_updates, tr("Check for updates"), tr("Whether or not to check for updates upon startup.")); // Linux @@ -459,9 +351,9 @@ std::unique_ptr InitializeTranslations(QWidget* parent) return translations; } -std::unique_ptr ComboboxEnumeration(QWidget* parent) -{ - std::unique_ptr translations = std::make_unique(); +std::unique_ptr ComboboxEnumeration(QWidget* parent) { + std::unique_ptr translations = + std::make_unique(); const auto& tr = [&](const char* text, const char* context = "") { return parent->tr(text, context); }; diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index c27a4644e9..5d75daa4f5 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp @@ -693,13 +693,13 @@ void Widget::SetupComponent(const QString& label, std::function& load_fu } if (other_setting != nullptr) { - const auto reset = [restore_func, data_component](int state) { + const auto reset = [restore_func, data_component](Qt::CheckState state) { data_component->setEnabled(state == Qt::Checked); if (state != Qt::Checked) { restore_func(); } }; - connect(checkbox, &QCheckBox::stateChanged, reset); + connect(checkbox, &QCheckBox::checkStateChanged, reset); reset(checkbox->checkState()); } } @@ -767,8 +767,8 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati Builder::Builder(QWidget* parent_, bool runtime_lock_) : translations{InitializeTranslations(parent_)}, - combobox_translations{ComboboxEnumeration(parent_)}, parent{parent_}, runtime_lock{ - runtime_lock_} {} + combobox_translations{ComboboxEnumeration(parent_)}, parent{parent_}, + runtime_lock{runtime_lock_} {} Builder::~Builder() = default; diff --git a/src/yuzu/externals/CMakeLists.txt b/src/yuzu/externals/CMakeLists.txt deleted file mode 100644 index ac17308e09..0000000000 --- a/src/yuzu/externals/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# Disable tests in all externals supporting the standard option name -set(BUILD_TESTING OFF) - -# Build only static externals -set(BUILD_SHARED_LIBS OFF) - -# QuaZip -set(QUAZIP_QT_MAJOR_VERSION 6) -set(QUAZIP_BZIP2 OFF) - -include(CPM) -set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm) -set(CPM_USE_LOCAL_PACKAGES ON) - -CPMAddPackage( - NAME QuaZip-Qt6 - VERSION 1.3 - GIT_REPOSITORY "https://github.com/stachenov/quazip.git" - GIT_TAG v1.5 - PATCHES - ${CMAKE_SOURCE_DIR}/.ci/patch/0001-quazip-strict.patch - ${CMAKE_SOURCE_DIR}/.ci/patch/0002-quazip-fetchcontent.patch -) - -if (NOT MSVC AND NOT "QuaZip-Qt6" IN_LIST CPM_PACKAGES) - message(STATUS "QUAZIP DIR: ${CPM_PACKAGES}") - target_compile_options(QuaZip PRIVATE - -Wno-error=shadow - -Wno-error=missing-declarations - ) -endif() diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 80dd90d876..fe87a90aaf 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -820,8 +820,7 @@ QStandardItemModel* GameList::GetModel() const { return item_model; } -void GameList::PopulateAsync(QVector& game_dirs, const bool cached) -{ +void GameList::PopulateAsync(QVector& game_dirs, const bool cached) { tree_view->setEnabled(false); // Update the columns in case UISettings has changed @@ -838,13 +837,8 @@ void GameList::PopulateAsync(QVector& game_dirs, const bool item_model->removeRows(0, item_model->rowCount()); search_field->clear(); - current_worker = std::make_unique(vfs, - provider, - game_dirs, - compatibility_list, - play_time_manager, - system, - cached); + current_worker = std::make_unique(vfs, provider, game_dirs, compatibility_list, + play_time_manager, system, cached); // Get events from the worker as data becomes available connect(current_worker.get(), &GameListWorker::DataAvailable, this, &GameList::WorkerEvent, @@ -873,16 +867,14 @@ const QStringList GameList::supported_file_extensions = { QStringLiteral("nso"), QStringLiteral("nro"), QStringLiteral("nca"), QStringLiteral("xci"), QStringLiteral("nsp"), QStringLiteral("kip")}; -void GameList::ForceRefreshGameDirectory() -{ +void GameList::ForceRefreshGameDirectory() { if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) { LOG_INFO(Frontend, "Force-reloading game list per user request."); PopulateAsync(UISettings::values.game_dirs, false); } } -void GameList::RefreshGameDirectory() -{ +void GameList::RefreshGameDirectory() { if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) { LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list."); PopulateAsync(UISettings::values.game_dirs); diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index 60109769bf..a0f53f25dc 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp @@ -191,17 +191,12 @@ QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager, return out; } -QList MakeGameListEntry(const std::string& path, - const std::string& name, - const std::size_t size, - const std::vector& icon, - Loader::AppLoader& loader, - u64 program_id, +QList MakeGameListEntry(const std::string& path, const std::string& name, + const std::size_t size, const std::vector& icon, + Loader::AppLoader& loader, u64 program_id, const CompatibilityList& compatibility_list, const PlayTime::PlayTimeManager& play_time_manager, - const FileSys::PatchManager& patch, - const bool cached) -{ + const FileSys::PatchManager& patch, const bool cached) { const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); // The game list uses this as compatibility number for untested games @@ -244,16 +239,10 @@ GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs_, QVector& game_dirs_, const CompatibilityList& compatibility_list_, const PlayTime::PlayTimeManager& play_time_manager_, - Core::System& system_, - const bool cached_) - : vfs{std::move(vfs_)} - , provider{provider_} - , game_dirs{game_dirs_} - , compatibility_list{compatibility_list_} - , play_time_manager{play_time_manager_} - , system{system_} - , cached{cached_} -{ + Core::System& system_, const bool cached_) + : vfs{std::move(vfs_)}, provider{provider_}, game_dirs{game_dirs_}, + compatibility_list{compatibility_list_}, play_time_manager{play_time_manager_}, + system{system_}, cached{cached_} { // We want the game list to manage our lifetime. setAutoDelete(false); } @@ -347,16 +336,9 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { GetMetadataFromControlNCA(patch, *control, icon, name); } - auto entry = MakeGameListEntry(file->GetFullPath(), - name, - file->GetSize(), - icon, - *loader, - program_id, - compatibility_list, - play_time_manager, - patch, - cached); + auto entry = + MakeGameListEntry(file->GetFullPath(), name, file->GetSize(), icon, *loader, program_id, + compatibility_list, play_time_manager, patch, cached); RecordEvent([=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); }); } } @@ -431,16 +413,9 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa const FileSys::PatchManager patch{id, system.GetFileSystemController(), system.GetContentProvider()}; - auto entry = MakeGameListEntry(physical_name, - name, - Common::FS::GetSize(physical_name), - icon, - *loader, - id, - compatibility_list, - play_time_manager, - patch, - cached); + auto entry = MakeGameListEntry( + physical_name, name, Common::FS::GetSize(physical_name), icon, *loader, + id, compatibility_list, play_time_manager, patch, cached); RecordEvent( [=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); }); @@ -455,16 +430,9 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa const FileSys::PatchManager patch{program_id, system.GetFileSystemController(), system.GetContentProvider()}; - auto entry = MakeGameListEntry(physical_name, - name, - Common::FS::GetSize(physical_name), - icon, - *loader, - program_id, - compatibility_list, - play_time_manager, - patch, - cached); + auto entry = MakeGameListEntry( + physical_name, name, Common::FS::GetSize(physical_name), icon, *loader, + program_id, compatibility_list, play_time_manager, patch, cached); RecordEvent( [=](GameList* game_list) { game_list->AddEntry(entry, parent_dir); }); diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h index 0afd7c7849..ab068fd587 100644 --- a/src/yuzu/game_list_worker.h +++ b/src/yuzu/game_list_worker.h @@ -45,8 +45,7 @@ public: QVector& game_dirs_, const CompatibilityList& compatibility_list_, const PlayTime::PlayTimeManager& play_time_manager_, - Core::System& system_, - const bool cached = true); + Core::System& system_, const bool cached = true); ~GameListWorker() override; /// Starts the processing of directory tree information. diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6a575cfa87..9947f7d2fa 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -12,7 +12,7 @@ #include "core/tools/renderdoc.h" #include "frontend_common/firmware_manager.h" -#include +#include "zip.h" #ifdef __APPLE__ #include // for chdir @@ -37,8 +37,8 @@ #include "configuration/configure_input.h" #include "configuration/configure_per_game.h" #include "configuration/configure_tas.h" -#include "core/file_sys/romfs_factory.h" #include "core/core_timing.h" +#include "core/file_sys/romfs_factory.h" #include "core/file_sys/vfs/vfs.h" #include "core/file_sys/vfs/vfs_real.h" #include "core/frontend/applets/cabinet.h" @@ -66,7 +66,7 @@ // These are wrappers to avoid the calls to CreateDirectory and CreateFile because of the Windows // defines. static FileSys::VirtualDir VfsFilesystemCreateDirectoryWrapper( - const FileSys::VirtualFilesystem& vfs, const std::string& path, FileSys::OpenMode mode) { + const FileSys::VirtualFilesystem& vfs, const std::string& path, FileSys::OpenMode mode) { return vfs->CreateDirectory(path, mode); } @@ -215,7 +215,7 @@ enum class CalloutFlag : uint32_t { * so this tracks which games are bad in this regard. */ constexpr std::array bad_update_games{ - 0x0100F2C0115B6000 // Tears of the Kingdom + 0x0100F2C0115B6000 // Tears of the Kingdom }; const int GMainWindow::max_recent_files_item; @@ -267,21 +267,21 @@ static QString PrettyProductName() { // After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2 // With that notation change they changed the registry key used to denote the current version QSettings windows_registry( - QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), - QSettings::NativeFormat); + QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), + QSettings::NativeFormat); const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString(); if (release_id == QStringLiteral("2009")) { const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt(); const QString display_version = - windows_registry.value(QStringLiteral("DisplayVersion")).toString(); + windows_registry.value(QStringLiteral("DisplayVersion")).toString(); const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt(); u32 version = 10; if (current_build >= 22000) { version = 11; } return QStringLiteral("Windows %1 Version %2 (Build %3.%4)") - .arg(QString::number(version), display_version, QString::number(current_build), - QString::number(ubr)); + .arg(QString::number(version), display_version, QString::number(current_build), + QString::number(ubr)); } #endif return QSysInfo::prettyProductName(); @@ -313,8 +313,7 @@ bool GMainWindow::CheckDarkMode() { GMainWindow::GMainWindow(bool has_broken_vulkan) : ui{std::make_unique()}, system{std::make_unique()}, - input_subsystem{std::make_shared()}, - user_data_migrator{this}, + input_subsystem{std::make_shared()}, user_data_migrator{this}, vfs{std::make_shared()}, provider{std::make_unique()} { Common::FS::CreateEdenPaths(); @@ -322,18 +321,19 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) if (user_data_migrator.migrated) { // Sort-of hack whereby we only move the old dir if it's a subfolder of the user dir - #define MIGRATE_DIR(type) std::string type##path = Common::FS::GetEdenPathString(Common::FS::EdenPath::type##Dir); \ - if (type##path.starts_with(user_data_migrator.selected_emu.get_user_dir())) { \ - boost::replace_all(type##path, user_data_migrator.selected_emu.lower_name(), "eden"); \ - Common::FS::SetEdenPath(Common::FS::EdenPath::type##Dir, type##path); \ - } +#define MIGRATE_DIR(type) \ + std::string type##path = Common::FS::GetEdenPathString(Common::FS::EdenPath::type##Dir); \ + if (type##path.starts_with(user_data_migrator.selected_emu.get_user_dir())) { \ + boost::replace_all(type##path, user_data_migrator.selected_emu.lower_name(), "eden"); \ + Common::FS::SetEdenPath(Common::FS::EdenPath::type##Dir, type##path); \ + } MIGRATE_DIR(NAND) MIGRATE_DIR(SDMC) MIGRATE_DIR(Dump) MIGRATE_DIR(Load) - #undef MIGRATE_DIR +#undef MIGRATE_DIR } #ifdef __unix__ @@ -392,7 +392,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) const auto yuzu_build = fmt::format("eden Development Build | {}-{}", branch_name, description); const auto override_build = - fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); + fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build; const auto processor_count = std::thread::hardware_concurrency(); @@ -426,7 +426,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) LOG_INFO(Frontend, "Host Timer Resolution: {:.4f} ms", std::chrono::duration_cast>( Common::Windows::SetCurrentTimerResolutionToMaximum()) - .count()); + .count()); system->CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution()); #endif UpdateWindowTitle(); @@ -436,13 +436,12 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) #ifdef ENABLE_QT_UPDATE_CHECKER if (UISettings::values.check_for_updates) { update_future = QtConcurrent::run([]() -> QString { - const bool is_prerelease = - ((strstr(Common::g_build_version, "pre-alpha") != NULL) || - (strstr(Common::g_build_version, "alpha") != NULL) || - (strstr(Common::g_build_version, "beta") != NULL) || - (strstr(Common::g_build_version, "rc") != NULL)); + const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != NULL) || + (strstr(Common::g_build_version, "alpha") != NULL) || + (strstr(Common::g_build_version, "beta") != NULL) || + (strstr(Common::g_build_version, "rc") != NULL)); const std::optional latest_release_tag = - UpdateChecker::GetLatestRelease(is_prerelease); + UpdateChecker::GetLatestRelease(is_prerelease); if (latest_release_tag && latest_release_tag.value() != Common::g_build_version) { return QString::fromStdString(latest_release_tag.value()); } @@ -676,26 +675,26 @@ void GMainWindow::RegisterMetaTypes() { // Cabinet Applet qRegisterMetaType("Core::Frontend::CabinetParameters"); qRegisterMetaType>( - "std::shared_ptr"); + "std::shared_ptr"); // Controller Applet qRegisterMetaType("Core::Frontend::ControllerParameters"); // Profile Select Applet qRegisterMetaType( - "Core::Frontend::ProfileSelectParameters"); + "Core::Frontend::ProfileSelectParameters"); // Software Keyboard Applet qRegisterMetaType( - "Core::Frontend::KeyboardInitializeParameters"); + "Core::Frontend::KeyboardInitializeParameters"); qRegisterMetaType( - "Core::Frontend::InlineAppearParameters"); + "Core::Frontend::InlineAppearParameters"); qRegisterMetaType("Core::Frontend::InlineTextParameters"); qRegisterMetaType("Service::AM::Frontend::SwkbdResult"); qRegisterMetaType( - "Service::AM::Frontend::SwkbdTextCheckResult"); + "Service::AM::Frontend::SwkbdTextCheckResult"); qRegisterMetaType( - "Service::AM::Frontend::SwkbdReplyType"); + "Service::AM::Frontend::SwkbdReplyType"); // Web Browser Applet qRegisterMetaType("Service::AM::Frontend::WebExitReason"); @@ -707,7 +706,7 @@ void GMainWindow::RegisterMetaTypes() { void GMainWindow::AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters, std::shared_ptr nfp_device) { cabinet_applet = - new QtAmiiboSettingsDialog(this, parameters, input_subsystem.get(), nfp_device); + new QtAmiiboSettingsDialog(this, parameters, input_subsystem.get(), nfp_device); SCOPE_EXIT { cabinet_applet->deleteLater(); cabinet_applet = nullptr; @@ -732,9 +731,9 @@ void GMainWindow::AmiiboSettingsRequestExit() { } void GMainWindow::ControllerSelectorReconfigureControllers( - const Core::Frontend::ControllerParameters& parameters) { + const Core::Frontend::ControllerParameters& parameters) { controller_applet = - new QtControllerSelectorDialog(this, parameters, input_subsystem.get(), *system); + new QtControllerSelectorDialog(this, parameters, input_subsystem.get(), *system); SCOPE_EXIT { controller_applet->deleteLater(); controller_applet = nullptr; @@ -763,7 +762,7 @@ void GMainWindow::ControllerSelectorRequestExit() { } void GMainWindow::ProfileSelectorSelectProfile( - const Core::Frontend::ProfileSelectParameters& parameters) { + const Core::Frontend::ProfileSelectParameters& parameters) { profile_select_applet = new QtProfileSelectionDialog(*system, this, parameters); SCOPE_EXIT { profile_select_applet->deleteLater(); @@ -780,7 +779,7 @@ void GMainWindow::ProfileSelectorSelectProfile( } const auto uuid = system->GetProfileManager().GetUser( - static_cast(profile_select_applet->GetIndex())); + static_cast(profile_select_applet->GetIndex())); if (!uuid.has_value()) { emit ProfileSelectorFinishedSelection(std::nullopt); return; @@ -796,7 +795,7 @@ void GMainWindow::ProfileSelectorRequestExit() { } void GMainWindow::SoftwareKeyboardInitialize( - bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) { + bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) { if (software_keyboard) { LOG_ERROR(Frontend, "The software keyboard is already initialized!"); return; @@ -807,20 +806,20 @@ void GMainWindow::SoftwareKeyboardInitialize( if (is_inline) { connect( - software_keyboard, &QtSoftwareKeyboardDialog::SubmitInlineText, this, - [this](Service::AM::Frontend::SwkbdReplyType reply_type, std::u16string submitted_text, - s32 cursor_position) { - emit SoftwareKeyboardSubmitInlineText(reply_type, submitted_text, cursor_position); - }, - Qt::QueuedConnection); + software_keyboard, &QtSoftwareKeyboardDialog::SubmitInlineText, this, + [this](Service::AM::Frontend::SwkbdReplyType reply_type, std::u16string submitted_text, + s32 cursor_position) { + emit SoftwareKeyboardSubmitInlineText(reply_type, submitted_text, cursor_position); + }, + Qt::QueuedConnection); } else { connect( - software_keyboard, &QtSoftwareKeyboardDialog::SubmitNormalText, this, - [this](Service::AM::Frontend::SwkbdResult result, std::u16string submitted_text, - bool confirmed) { - emit SoftwareKeyboardSubmitNormalText(result, submitted_text, confirmed); - }, - Qt::QueuedConnection); + software_keyboard, &QtSoftwareKeyboardDialog::SubmitNormalText, this, + [this](Service::AM::Frontend::SwkbdResult result, std::u16string submitted_text, + bool confirmed) { + emit SoftwareKeyboardSubmitNormalText(result, submitted_text, confirmed); + }, + Qt::QueuedConnection); } } @@ -843,8 +842,8 @@ void GMainWindow::SoftwareKeyboardShowNormal() { } void GMainWindow::SoftwareKeyboardShowTextCheck( - Service::AM::Frontend::SwkbdTextCheckResult text_check_result, - std::u16string text_check_message) { + Service::AM::Frontend::SwkbdTextCheckResult text_check_result, + std::u16string text_check_message) { if (!software_keyboard) { LOG_ERROR(Frontend, "The software keyboard is not initialized!"); return; @@ -854,7 +853,7 @@ void GMainWindow::SoftwareKeyboardShowTextCheck( } void GMainWindow::SoftwareKeyboardShowInline( - Core::Frontend::InlineAppearParameters appear_parameters) { + Core::Frontend::InlineAppearParameters appear_parameters) { if (!software_keyboard) { LOG_ERROR(Frontend, "The software keyboard is not initialized!"); return; @@ -863,13 +862,13 @@ void GMainWindow::SoftwareKeyboardShowInline( const auto& layout = render_window->GetFramebufferLayout(); const auto x = - static_cast(layout.screen.left + (0.5f * layout.screen.GetWidth() * - ((2.0f * appear_parameters.key_top_translate_x) + - (1.0f - appear_parameters.key_top_scale_x)))); + static_cast(layout.screen.left + (0.5f * layout.screen.GetWidth() * + ((2.0f * appear_parameters.key_top_translate_x) + + (1.0f - appear_parameters.key_top_scale_x)))); const auto y = - static_cast(layout.screen.top + (layout.screen.GetHeight() * - ((2.0f * appear_parameters.key_top_translate_y) + - (1.0f - appear_parameters.key_top_scale_y)))); + static_cast(layout.screen.top + (layout.screen.GetHeight() * + ((2.0f * appear_parameters.key_top_translate_y) + + (1.0f - appear_parameters.key_top_scale_y)))); const auto w = static_cast(layout.screen.GetWidth() * appear_parameters.key_top_scale_x); const auto h = static_cast(layout.screen.GetHeight() * appear_parameters.key_top_scale_y); const auto scale_ratio = devicePixelRatioF(); @@ -889,7 +888,7 @@ void GMainWindow::SoftwareKeyboardHideInline() { } void GMainWindow::SoftwareKeyboardInlineTextChanged( - Core::Frontend::InlineTextParameters text_parameters) { + Core::Frontend::InlineTextParameters text_parameters) { if (!software_keyboard) { LOG_ERROR(Frontend, "The software keyboard is not initialized!"); return; @@ -980,11 +979,11 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, QAction* exit_action = new QAction(tr("Disable Web Applet"), this); connect(exit_action, &QAction::triggered, this, [this] { const auto result = QMessageBox::warning( - this, tr("Disable Web Applet"), - tr("Disabling the web applet can lead to undefined behavior and should only be used " - "with Super Mario 3D All-Stars. Are you sure you want to disable the web " - "applet?\n(This can be re-enabled in the Debug settings.)"), - QMessageBox::Yes | QMessageBox::No); + this, tr("Disable Web Applet"), + tr("Disabling the web applet can lead to undefined behavior and should only be used " + "with Super Mario 3D All-Stars. Are you sure you want to disable the web " + "applet?\n(This can be re-enabled in the Debug settings.)"), + QMessageBox::Yes | QMessageBox::No); if (result == QMessageBox::Yes) { UISettings::values.disable_web_applet = true; web_applet->SetFinished(true); @@ -997,14 +996,14 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, if (!exit_check) { web_applet->page()->runJavaScript( - QStringLiteral("end_applet;"), [&](const QVariant& variant) { - exit_check = false; - if (variant.toBool()) { - web_applet->SetFinished(true); - web_applet->SetExitReason( - Service::AM::Frontend::WebExitReason::EndButtonPressed); - } - }); + QStringLiteral("end_applet;"), [&](const QVariant& variant) { + exit_check = false; + if (variant.toBool()) { + web_applet->SetFinished(true); + web_applet->SetExitReason( + Service::AM::Frontend::WebExitReason::EndButtonPressed); + } + }); exit_check = true; } @@ -1102,18 +1101,18 @@ void GMainWindow::InitializeWidgets() { res_scale_label->setToolTip(tr("The current selected resolution scaling multiplier.")); emu_speed_label = new QLabel(); emu_speed_label->setToolTip( - tr("Current emulation speed. Values higher or lower than 100% " - "indicate emulation is running faster or slower than a Switch.")); + tr("Current emulation speed. Values higher or lower than 100% " + "indicate emulation is running faster or slower than a Switch.")); game_fps_label = new QLabel(); game_fps_label->setToolTip(tr("How many frames per second the game is currently displaying. " "This will vary from game to game and scene to scene.")); emu_frametime_label = new QLabel(); emu_frametime_label->setToolTip( - tr("Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For " - "full-speed emulation this should be at most 16.67 ms.")); + tr("Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For " + "full-speed emulation this should be at most 16.67 ms.")); for (auto& label : {shader_building_label, res_scale_label, emu_speed_label, game_fps_label, - emu_frametime_label}) { + emu_frametime_label}) { label->setVisible(false); label->setFrameStyle(QFrame::NoFrame); label->setContentsMargins(4, 0, 4, 0); @@ -1167,21 +1166,21 @@ void GMainWindow::InitializeWidgets() { volume_button->setContextMenuPolicy(Qt::CustomContextMenu); connect(volume_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { - QMenu context_menu; - context_menu.addAction( + QMenu context_menu; + context_menu.addAction( Settings::values.audio_muted ? tr("Unmute") : tr("Mute"), [this] { - Settings::values.audio_muted = !Settings::values.audio_muted; - UpdateVolumeUI(); - }); + Settings::values.audio_muted = !Settings::values.audio_muted; + UpdateVolumeUI(); + }); - context_menu.addAction(tr("Reset Volume"), [this] { - Settings::values.volume.SetValue(100); - UpdateVolumeUI(); - }); + context_menu.addAction(tr("Reset Volume"), [this] { + Settings::values.volume.SetValue(100); + UpdateVolumeUI(); + }); - context_menu.exec(volume_button->mapToGlobal(menu_location)); - volume_button->repaint(); - }); + context_menu.exec(volume_button->mapToGlobal(menu_location)); + volume_button->repaint(); + }); connect(volume_button, &VolumeButton::VolumeChanged, this, &GMainWindow::UpdateVolumeUI); statusBar()->insertPermanentWidget(0, volume_button); @@ -1206,16 +1205,16 @@ void GMainWindow::InitializeWidgets() { aa_status_button->setContextMenuPolicy(Qt::CustomContextMenu); connect(aa_status_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { - QMenu context_menu; - for (auto const& aa_text_pair : ConfigurationShared::anti_aliasing_texts_map) { - context_menu.addAction(aa_text_pair.second, [this, aa_text_pair] { - Settings::values.anti_aliasing.SetValue(aa_text_pair.first); - UpdateAAText(); + QMenu context_menu; + for (auto const& aa_text_pair : ConfigurationShared::anti_aliasing_texts_map) { + context_menu.addAction(aa_text_pair.second, [this, aa_text_pair] { + Settings::values.anti_aliasing.SetValue(aa_text_pair.first); + UpdateAAText(); + }); + } + context_menu.exec(aa_status_button->mapToGlobal(menu_location)); + aa_status_button->repaint(); }); - } - context_menu.exec(aa_status_button->mapToGlobal(menu_location)); - aa_status_button->repaint(); - }); statusBar()->insertPermanentWidget(0, aa_status_button); // Setup Filter button @@ -1230,16 +1229,16 @@ void GMainWindow::InitializeWidgets() { filter_status_button->setContextMenuPolicy(Qt::CustomContextMenu); connect(filter_status_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { - QMenu context_menu; - for (auto const& filter_text_pair : ConfigurationShared::scaling_filter_texts_map) { - context_menu.addAction(filter_text_pair.second, [this, filter_text_pair] { - Settings::values.scaling_filter.SetValue(filter_text_pair.first); - UpdateFilterText(); + QMenu context_menu; + for (auto const& filter_text_pair : ConfigurationShared::scaling_filter_texts_map) { + context_menu.addAction(filter_text_pair.second, [this, filter_text_pair] { + Settings::values.scaling_filter.SetValue(filter_text_pair.first); + UpdateFilterText(); + }); + } + context_menu.exec(filter_status_button->mapToGlobal(menu_location)); + filter_status_button->repaint(); }); - } - context_menu.exec(filter_status_button->mapToGlobal(menu_location)); - filter_status_button->repaint(); - }); statusBar()->insertPermanentWidget(0, filter_status_button); // Setup Dock button @@ -1252,18 +1251,18 @@ void GMainWindow::InitializeWidgets() { dock_status_button->setContextMenuPolicy(Qt::CustomContextMenu); connect(dock_status_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { - QMenu context_menu; + QMenu context_menu; - for (auto const& pair : ConfigurationShared::use_docked_mode_texts_map) { - context_menu.addAction(pair.second, [this, &pair] { - if (pair.first != Settings::values.use_docked_mode.GetValue()) { - OnToggleDockedMode(); + for (auto const& pair : ConfigurationShared::use_docked_mode_texts_map) { + context_menu.addAction(pair.second, [this, &pair] { + if (pair.first != Settings::values.use_docked_mode.GetValue()) { + OnToggleDockedMode(); + } + }); } + context_menu.exec(dock_status_button->mapToGlobal(menu_location)); + dock_status_button->repaint(); }); - } - context_menu.exec(dock_status_button->mapToGlobal(menu_location)); - dock_status_button->repaint(); - }); statusBar()->insertPermanentWidget(0, dock_status_button); // Setup GPU Accuracy button @@ -1276,20 +1275,20 @@ void GMainWindow::InitializeWidgets() { gpu_accuracy_button->setContextMenuPolicy(Qt::CustomContextMenu); connect(gpu_accuracy_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { - QMenu context_menu; + QMenu context_menu; - for (auto const& gpu_accuracy_pair : ConfigurationShared::gpu_accuracy_texts_map) { - if (gpu_accuracy_pair.first == Settings::GpuAccuracy::Extreme) { - continue; - } - context_menu.addAction(gpu_accuracy_pair.second, [this, gpu_accuracy_pair] { - Settings::values.gpu_accuracy.SetValue(gpu_accuracy_pair.first); - UpdateGPUAccuracyButton(); + for (auto const& gpu_accuracy_pair : ConfigurationShared::gpu_accuracy_texts_map) { + if (gpu_accuracy_pair.first == Settings::GpuAccuracy::Extreme) { + continue; + } + context_menu.addAction(gpu_accuracy_pair.second, [this, gpu_accuracy_pair] { + Settings::values.gpu_accuracy.SetValue(gpu_accuracy_pair.first); + UpdateGPUAccuracyButton(); + }); + } + context_menu.exec(gpu_accuracy_button->mapToGlobal(menu_location)); + gpu_accuracy_button->repaint(); }); - } - context_menu.exec(gpu_accuracy_button->mapToGlobal(menu_location)); - gpu_accuracy_button->repaint(); - }); statusBar()->insertPermanentWidget(0, gpu_accuracy_button); // Setup Renderer API button @@ -1305,22 +1304,22 @@ void GMainWindow::InitializeWidgets() { renderer_status_button->setContextMenuPolicy(Qt::CustomContextMenu); connect(renderer_status_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { - QMenu context_menu; + QMenu context_menu; - for (auto const& renderer_backend_pair : - ConfigurationShared::renderer_backend_texts_map) { - if (renderer_backend_pair.first == Settings::RendererBackend::Null) { - continue; - } - context_menu.addAction( + for (auto const& renderer_backend_pair : + ConfigurationShared::renderer_backend_texts_map) { + if (renderer_backend_pair.first == Settings::RendererBackend::Null) { + continue; + } + context_menu.addAction( renderer_backend_pair.second, [this, renderer_backend_pair] { - Settings::values.renderer_backend.SetValue(renderer_backend_pair.first); - UpdateAPIText(); + Settings::values.renderer_backend.SetValue(renderer_backend_pair.first); + UpdateAPIText(); + }); + } + context_menu.exec(renderer_status_button->mapToGlobal(menu_location)); + renderer_status_button->repaint(); }); - } - context_menu.exec(renderer_status_button->mapToGlobal(menu_location)); - renderer_status_button->repaint(); - }); statusBar()->insertPermanentWidget(0, renderer_status_button); // Setup Refresh Button @@ -1385,24 +1384,24 @@ void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name static const auto main_window = std::string("Main Window"); action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name.toStdString())); action->setShortcutContext( - hotkey_registry.GetShortcutContext(main_window, action_name.toStdString())); + hotkey_registry.GetShortcutContext(main_window, action_name.toStdString())); action->setAutoRepeat(false); this->addAction(action); auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); const auto* controller_hotkey = - hotkey_registry.GetControllerHotkey(main_window, action_name.toStdString(), controller); + hotkey_registry.GetControllerHotkey(main_window, action_name.toStdString(), controller); connect( - controller_hotkey, &ControllerShortcut::Activated, this, - [action, tas_allowed, this] { - auto [tas_status, current_tas_frame, total_tas_frames] = + controller_hotkey, &ControllerShortcut::Activated, this, + [action, tas_allowed, this] { + auto [tas_status, current_tas_frame, total_tas_frames] = input_subsystem->GetTas()->GetStatus(); - if (tas_allowed || tas_status == InputCommon::TasInput::TasState::Stopped) { - action->trigger(); - } - }, - Qt::QueuedConnection); + if (tas_allowed || tas_status == InputCommon::TasInput::TasState::Stopped) { + action->trigger(); + } + }, + Qt::QueuedConnection); } void GMainWindow::InitializeHotkeys() { @@ -1433,15 +1432,15 @@ void GMainWindow::InitializeHotkeys() { static const QString main_window = QStringLiteral("Main Window"); const auto connect_shortcut = [&](const QString& action_name, const Fn& function) { - const auto* hotkey = + const auto* hotkey = hotkey_registry.GetHotkey(main_window.toStdString(), action_name.toStdString(), this); - auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); - const auto* controller_hotkey = hotkey_registry.GetControllerHotkey( - main_window.toStdString(), action_name.toStdString(), controller); - connect(hotkey, &QShortcut::activated, this, function); - connect(controller_hotkey, &ControllerShortcut::Activated, this, function, - Qt::QueuedConnection); -}; + auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); + const auto* controller_hotkey = hotkey_registry.GetControllerHotkey( + main_window.toStdString(), action_name.toStdString(), controller); + connect(hotkey, &QShortcut::activated, this, function); + connect(controller_hotkey, &ControllerShortcut::Activated, this, function, + Qt::QueuedConnection); + }; connect_shortcut(QStringLiteral("Exit Fullscreen"), [&] { if (emulation_running && ui->action_Fullscreen->isChecked()) { @@ -1508,7 +1507,7 @@ void GMainWindow::RestoreUIState() { ui->action_Fullscreen->setChecked(UISettings::values.fullscreen.GetValue()); ui->action_Display_Dock_Widget_Headers->setChecked( - UISettings::values.display_titlebar.GetValue()); + UISettings::values.display_titlebar.GetValue()); OnDisplayTitleBars(ui->action_Display_Dock_Widget_Headers->isChecked()); ui->action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar.GetValue()); @@ -1521,7 +1520,7 @@ void GMainWindow::RestoreUIState() { void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { if (state != Qt::ApplicationHidden && state != Qt::ApplicationInactive && - state != Qt::ApplicationActive) { + state != Qt::ApplicationActive) { LOG_DEBUG(Frontend, "ApplicationState unusual flag: {} ", state); } if (!emulation_running) { @@ -1529,7 +1528,7 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { } if (UISettings::values.pause_when_in_background) { if (emu_thread->IsRunning() && - (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { + (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { auto_paused = true; OnPauseGame(); } else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) { @@ -1539,7 +1538,7 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { } if (UISettings::values.mute_when_in_background) { if (!Settings::values.audio_muted && - (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { + (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { Settings::values.audio_muted = true; auto_muted = true; } else if (auto_muted && state == Qt::ApplicationActive) { @@ -1600,12 +1599,12 @@ void GMainWindow::ConnectWidgetEvents() { void GMainWindow::ConnectMenuEvents() { const auto connect_menu = [&](QAction* action, const Fn& event_fn) { - connect(action, &QAction::triggered, this, event_fn); - // Add actions to this window so that hiding menus in fullscreen won't disable them - addAction(action); - // Add actions to the render window so that they work outside of single window mode - render_window->addAction(action); -}; + connect(action, &QAction::triggered, this, event_fn); + // Add actions to this window so that hiding menus in fullscreen won't disable them + addAction(action); + // Add actions to the render window so that they work outside of single window mode + render_window->addAction(action); + }; // File connect_menu(ui->action_Load_File, &GMainWindow::OnMenuLoadFile); @@ -1667,7 +1666,8 @@ void GMainWindow::ConnectMenuEvents() { connect_menu(ui->action_Load_Home_Menu, &GMainWindow::OnHomeMenu); connect_menu(ui->action_Open_Setup, &GMainWindow::OnInitialSetup); connect_menu(ui->action_Desktop, &GMainWindow::OnCreateHomeMenuDesktopShortcut); - connect_menu(ui->action_Application_Menu, &GMainWindow::OnCreateHomeMenuApplicationMenuShortcut); + connect_menu(ui->action_Application_Menu, + &GMainWindow::OnCreateHomeMenuApplicationMenuShortcut); connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot); // TAS @@ -1697,21 +1697,21 @@ void GMainWindow::UpdateMenuState() { const std::array running_actions{ ui->action_Stop, - ui->action_Restart, - ui->action_Configure_Current_Game, - ui->action_Report_Compatibility, - ui->action_Load_Amiibo, - ui->action_Pause, + ui->action_Restart, + ui->action_Configure_Current_Game, + ui->action_Report_Compatibility, + ui->action_Load_Amiibo, + ui->action_Pause, }; const std::array applet_actions{ui->action_Load_Album, - ui->action_Load_Cabinet_Nickname_Owner, - ui->action_Load_Cabinet_Eraser, - ui->action_Load_Cabinet_Restorer, - ui->action_Load_Cabinet_Formatter, - ui->action_Load_Mii_Edit, - ui->action_Load_Home_Menu, - ui->action_Open_Controller_Menu}; + ui->action_Load_Cabinet_Nickname_Owner, + ui->action_Load_Cabinet_Eraser, + ui->action_Load_Cabinet_Restorer, + ui->action_Load_Cabinet_Formatter, + ui->action_Load_Mii_Edit, + ui->action_Load_Home_Menu, + ui->action_Open_Controller_Menu}; for (QAction* action : running_actions) { action->setEnabled(emulation_running); @@ -1761,9 +1761,9 @@ void GMainWindow::SetupPrepareForSleep() { auto bus = QDBusConnection::systemBus(); if (bus.isConnected()) { const bool success = bus.connect( - QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"), - QStringLiteral("org.freedesktop.login1.Manager"), QStringLiteral("PrepareForSleep"), - QStringLiteral("b"), this, SLOT(OnPrepareForSleep(bool))); + QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"), + QStringLiteral("org.freedesktop.login1.Manager"), QStringLiteral("PrepareForSleep"), + QStringLiteral("b"), this, SLOT(OnPrepareForSleep(bool))); if (!success) { LOG_WARNING(Frontend, "Couldn't register PrepareForSleep signal"); @@ -1872,21 +1872,20 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa system->GetUserChannel().clear(); } - system->SetFrontendAppletSet({ - std::make_unique(*this), // Amiibo Settings - (UISettings::values.controller_applet_disabled.GetValue() == true) - ? nullptr - : std::make_unique(*this), // Controller Selector - std::make_unique(*this), // Error Display - nullptr, // Mii Editor - nullptr, // Parental Controls - nullptr, // Photo Viewer - std::make_unique(*this), // Profile Selector - std::make_unique(*this), // Software Keyboard - std::make_unique(*this), // Web Browser - nullptr, // Net Connect - }); + std::make_unique(*this), // Amiibo Settings + (UISettings::values.controller_applet_disabled.GetValue() == true) + ? nullptr + : std::make_unique(*this), // Controller Selector + std::make_unique(*this), // Error Display + nullptr, // Mii Editor + nullptr, // Parental Controls + nullptr, // Photo Viewer + std::make_unique(*this), // Profile Selector + std::make_unique(*this), // Software Keyboard + std::make_unique(*this), // Web Browser + nullptr, // Net Connect + }); /** Game Updates check */ @@ -1894,26 +1893,29 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa QSettings settings; QStringList currentIgnored = settings.value("ignoredBadUpdates", {}).toStringList(); - if (std::find(bad_update_games.begin(), bad_update_games.end(), params.program_id) != bad_update_games.end() - && !currentIgnored.contains(QString::number(params.program_id))) { - QMessageBox *msg = new QMessageBox(this); + if (std::find(bad_update_games.begin(), bad_update_games.end(), params.program_id) != + bad_update_games.end() && + !currentIgnored.contains(QString::number(params.program_id))) { + QMessageBox* msg = new QMessageBox(this); msg->setWindowTitle(tr("Game Updates Warning")); msg->setIcon(QMessageBox::Warning); - msg->setText(tr("The game you are trying to launch is known to have performance or booting " - "issues when updates are applied. Please try increasing the memory layout to " - "6GB or 8GB if any issues occur.

Press \"OK\" to continue launching, or " - "\"Cancel\" to cancel the launch.")); + msg->setText( + tr("The game you are trying to launch is known to have performance or booting " + "issues when updates are applied. Please try increasing the memory layout to " + "6GB or 8GB if any issues occur.

Press \"OK\" to continue launching, or " + "\"Cancel\" to cancel the launch.")); msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - QCheckBox *dontShowAgain = new QCheckBox(msg); + QCheckBox* dontShowAgain = new QCheckBox(msg); dontShowAgain->setText(tr("Don't show again for this game")); msg->setCheckBox(dontShowAgain); int result = msg->exec(); // wtf - QMessageBox::ButtonRole role = msg->buttonRole(msg->button((QMessageBox::StandardButton) result)); + QMessageBox::ButtonRole role = + msg->buttonRole(msg->button((QMessageBox::StandardButton)result)); switch (role) { case QMessageBox::RejectRole: @@ -1929,19 +1931,22 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa } } - if (FirmwareManager::GameRequiresFirmware(params.program_id) && !FirmwareManager::CheckFirmwarePresence(*system)) { - QMessageBox *msg = new QMessageBox(this); + if (FirmwareManager::GameRequiresFirmware(params.program_id) && + !FirmwareManager::CheckFirmwarePresence(*system)) { + QMessageBox* msg = new QMessageBox(this); msg->setWindowTitle(tr("Game Requires Firmware")); msg->setIcon(QMessageBox::Warning); - msg->setText(tr("The game you are trying to launch requires firmware to boot or to get past the " - "opening menu. Please " - "dump and install firmware, or press \"OK\" to launch anyways.")); + msg->setText( + tr("The game you are trying to launch requires firmware to boot or to get past the " + "opening menu. Please " + "dump and install firmware, or press \"OK\" to launch anyways.")); msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); int exec_result = msg->exec(); - QMessageBox::ButtonRole role = msg->buttonRole(msg->button((QMessageBox::StandardButton) exec_result)); + QMessageBox::ButtonRole role = + msg->buttonRole(msg->button((QMessageBox::StandardButton)exec_result)); switch (role) { case QMessageBox::RejectRole: @@ -1960,18 +1965,19 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa static_cast(CalloutFlag::DRDDeprecation)) == 0; if (result == Core::SystemResultStatus::Success && - system->GetAppLoader().GetFileType() == Loader::FileType::DeconstructedRomDirectory && - drd_callout) { + system->GetAppLoader().GetFileType() == Loader::FileType::DeconstructedRomDirectory && + drd_callout) { UISettings::values.callout_flags = UISettings::values.callout_flags.GetValue() | - static_cast(CalloutFlag::DRDDeprecation); + static_cast(CalloutFlag::DRDDeprecation); QMessageBox::warning( - this, tr("Warning: Outdated Game Format"), - tr("You are using the deconstructed ROM directory format for this game, which is an " - "outdated format that has been superseded by others such as NCA, NAX, XCI, or " - "NSP. Deconstructed ROM directories lack icons, metadata, and update " - "support.

For an explanation of the various Switch formats eden supports, check out our " - "wiki. This message will not be shown again.")); + this, tr("Warning: Outdated Game Format"), + tr("You are using the deconstructed ROM directory format for this game, which is an " + "outdated format that has been superseded by others such as NCA, NAX, XCI, or " + "NSP. Deconstructed ROM directories lack icons, metadata, and update " + "support.

For an explanation of the various Switch formats eden supports, check " + "out our " + "wiki. This message will not be shown again.")); } if (result != Core::SystemResultStatus::Success) { @@ -1983,13 +1989,13 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa break; case Core::SystemResultStatus::ErrorVideoCore: QMessageBox::critical( - this, tr("An error occurred initializing the video core."), - tr("eden has encountered an error while running the video core. " - "This is usually caused by outdated GPU drivers, including integrated ones. " - "Please see the log for more details. " - "For more information on accessing the log, please see the following page: " - "" - "How to Upload the Log File. ")); + this, tr("An error occurred initializing the video core."), + tr("eden has encountered an error while running the video core. " + "This is usually caused by outdated GPU drivers, including integrated ones. " + "Please see the log for more details. " + "For more information on accessing the log, please see the following page: " + "" + "How to Upload the Log File. ")); break; default: if (result > Core::SystemResultStatus::ErrorLoader) { @@ -1999,19 +2005,19 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa LOG_CRITICAL(Frontend, "Failed to load ROM! {}", error_code); const auto title = - tr("Error while loading ROM! %1", "%1 signifies a numeric error code.") + tr("Error while loading ROM! %1", "%1 signifies a numeric error code.") .arg(QString::fromStdString(error_code)); const auto description = - tr("%1
Please redump your files or ask on Discord for help.", - "%1 signifies an error string.") + tr("%1
Please redump your files or ask on Discord for help.", + "%1 signifies an error string.") .arg(QString::fromStdString( - GetResultStatusString(static_cast(error_id)))); + GetResultStatusString(static_cast(error_id)))); QMessageBox::critical(this, title, description); } else { QMessageBox::critical( - this, tr("Error while loading ROM!"), - tr("An unknown error occurred. Please see the log for more details.")); + this, tr("Error while loading ROM!"), + tr("An unknown error occurred. Please see the log for more details.")); } break; } @@ -2023,7 +2029,7 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa } bool GMainWindow::SelectAndSetCurrentUser( - const Core::Frontend::ProfileSelectParameters& parameters) { + const Core::Frontend::ProfileSelectParameters& parameters) { QtProfileSelectionDialog dialog(*system, this, parameters); dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); @@ -2063,8 +2069,8 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) { } else if (res2 == Loader::ResultStatus::Success && (file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) { const auto nsp = file_type == Loader::FileType::NSP - ? std::make_shared(file) - : FileSys::XCI{file}.GetSecurePartitionNSP(); + ? std::make_shared(file) + : FileSys::XCI{file}.GetSecurePartitionNSP(); for (const auto& title : nsp->GetNCAs()) { for (const auto& entry : title.second) { provider->AddEntry(entry.first.first, entry.first.second, title.first, @@ -2079,7 +2085,7 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP LOG_INFO(Frontend, "eden starting..."); if (params.program_id == 0 || - params.program_id > static_cast(Service::AM::AppletProgramId::MaxProgramId)) { + params.program_id > static_cast(Service::AM::AppletProgramId::MaxProgramId)) { StoreRecentFile(filename); // Put the filename on top of the list } @@ -2097,13 +2103,13 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP const auto loader = Loader::GetLoader(*system, v_file, params.program_id, params.program_index); if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success && - type == StartGameType::Normal) { + type == StartGameType::Normal) { // Load per game settings const auto file_path = - std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())}; + std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())}; const auto config_file_name = title_id == 0 - ? Common::FS::PathToUTF8String(file_path.filename()) - : fmt::format("{:016X}", title_id); + ? Common::FS::PathToUTF8String(file_path.filename()) + : fmt::format("{:016X}", title_id); QtConfig per_game_config(config_file_name, Config::ConfigType::PerGameConfig); system->HIDCore().ReloadInputDevices(); system->ApplySettings(); @@ -2114,9 +2120,9 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP if (UISettings::values.select_user_on_boot && !user_flag_cmd_line) { const Core::Frontend::ProfileSelectParameters parameters{ .mode = Service::AM::Frontend::UiMode::UserSelector, - .invalid_uid_list = {}, - .display_options = {}, - .purpose = Service::AM::Frontend::UserSelectionPurpose::General, + .invalid_uid_list = {}, + .display_options = {}, + .purpose = Service::AM::Frontend::UserSelectionPurpose::General, }; if (SelectAndSetCurrentUser(parameters) == false) { return; @@ -2142,7 +2148,7 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP // Register an ExecuteProgram callback such that Core can execute a sub-program system->RegisterExecuteProgramCallback( - [this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); }); + [this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); }); system->RegisterExitCallback([this] { emu_thread->ForceStop(); @@ -2197,14 +2203,14 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP } if (res != Loader::ResultStatus::Success || title_name.empty()) { title_name = Common::FS::PathToUTF8String( - std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())} - .filename()); + std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())} + .filename()); } const bool is_64bit = system->Kernel().ApplicationProcess()->Is64Bit(); const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)"); title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit") - .arg(QString::fromStdString(title_name), instruction_set_suffix) - .toStdString(); + .arg(QString::fromStdString(title_name), instruction_set_suffix) + .toStdString(); LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); const auto gpu_vendor = system->GPU().Renderer().GetDeviceVendor(); UpdateWindowTitle(title_name, title_version, gpu_vendor); @@ -2384,11 +2390,11 @@ void GMainWindow::StoreRecentFile(const QString& filename) { void GMainWindow::UpdateRecentFiles() { const int num_recent_files = - std::min(static_cast(UISettings::values.recent_files.size()), max_recent_files_item); + std::min(static_cast(UISettings::values.recent_files.size()), max_recent_files_item); for (int i = 0; i < num_recent_files; i++) { const QString text = QStringLiteral("&%1. %2").arg(i + 1).arg( - QFileInfo(UISettings::values.recent_files[i]).fileName()); + QFileInfo(UISettings::values.recent_files[i]).fileName()); actions_recent_files[i]->setText(text); actions_recent_files[i]->setData(UISettings::values.recent_files[i]); actions_recent_files[i]->setToolTip(UISettings::values.recent_files[i]); @@ -2417,7 +2423,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target const auto [user_save_size, device_save_size] = [this, &game_path, &program_id] { const FileSys::PatchManager pm{program_id, system->GetFileSystemController(), - system->GetContentProvider()}; + system->GetContentProvider()}; const auto control = pm.GetControlMetadata().first; if (control != nullptr) { return std::make_pair(control->GetDefaultNormalSaveSize(), @@ -2443,16 +2449,16 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target open_target = tr("Save Data"); const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir); auto vfs_nand_dir = - vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); + vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); if (has_user_save) { // User save data const auto select_profile = [this] { const Core::Frontend::ProfileSelectParameters parameters{ .mode = Service::AM::Frontend::UiMode::UserSelector, - .invalid_uid_list = {}, - .display_options = {}, - .purpose = Service::AM::Frontend::UserSelectionPurpose::General, + .invalid_uid_list = {}, + .display_options = {}, + .purpose = Service::AM::Frontend::UserSelectionPurpose::General, }; QtProfileSelectionDialog dialog(*system, this, parameters); dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | @@ -2472,19 +2478,19 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target } const auto user_id = - system->GetProfileManager().GetUser(static_cast(index)); + system->GetProfileManager().GetUser(static_cast(index)); ASSERT(user_id); const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( - {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, - program_id, user_id->AsU128(), 0); + {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, + program_id, user_id->AsU128(), 0); path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); } else { // Device save data const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( - {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, - program_id, {}, 0); + {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, + program_id, {}, 0); path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); } @@ -2498,7 +2504,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target case GameListOpenTarget::ModData: { open_target = tr("Mod Data"); path = Common::FS::GetEdenPath(Common::FS::EdenPath::LoadDir) / - fmt::format("{:016X}", program_id); + fmt::format("{:016X}", program_id); break; } default: @@ -2543,7 +2549,7 @@ static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& auto last_timestamp = std::chrono::steady_clock::now(); const auto QtRawCopy = [&](const FileSys::VirtualFile& src_file, - const FileSys::VirtualFile& dest_file) { + const FileSys::VirtualFile& dest_file) { if (src_file == nullptr || dest_file == nullptr) { return false; } @@ -2563,7 +2569,7 @@ static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& if ((new_timestamp - last_timestamp) > 33ms) { last_timestamp = new_timestamp; dialog.setValue( - static_cast(std::min(read_size, total_size) * 100 / total_size)); + static_cast(std::min(read_size, total_size) * 100 / total_size)); QCoreApplication::processEvents(); } @@ -2645,14 +2651,14 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT void GMainWindow::RemoveBaseContent(u64 program_id, InstalledEntryType type) { const auto res = - ContentManager::RemoveBaseContent(system->GetFileSystemController(), program_id); + ContentManager::RemoveBaseContent(system->GetFileSystemController(), program_id); if (res) { QMessageBox::information(this, tr("Successfully Removed"), tr("Successfully removed the installed base game.")); } else { QMessageBox::warning( - this, GetGameListErrorRemoving(type), - tr("The base game is not installed in the NAND and cannot be removed.")); + this, GetGameListErrorRemoving(type), + tr("The base game is not installed in the NAND and cannot be removed.")); } } @@ -2799,10 +2805,10 @@ void GMainWindow::RemoveAllTransferableShaderCaches(u64 program_id) { void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& game_path) { const auto file_path = std::filesystem::path(Common::FS::ToU8String(game_path)); const auto config_file_name = - program_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()).append(".ini") - : fmt::format("{:016X}.ini", program_id); + program_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()).append(".ini") + : fmt::format("{:016X}.ini", program_id); const auto custom_config_file_path = - Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom" / config_file_name; + Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom" / config_file_name; if (!Common::FS::Exists(custom_config_file_path)) { QMessageBox::warning(this, tr("Error Removing Custom Configuration"), @@ -2822,11 +2828,11 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& g void GMainWindow::RemoveCacheStorage(u64 program_id) { const auto nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir); auto vfs_nand_dir = - vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); + vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); const auto cache_storage_path = FileSys::SaveDataFactory::GetFullPath( - {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Cache, - 0 /* program_id */, {}, 0); + {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Cache, + 0 /* program_id */, {}, 0); const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path); @@ -2843,7 +2849,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa }; const auto loader = - Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::OpenMode::Read)); + Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::OpenMode::Read)); if (loader == nullptr) { failed(); return; @@ -2870,14 +2876,14 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa const FileSys::NCA update_nca{packed_update_raw, nullptr}; if (type != FileSys::ContentRecordType::Program || - update_nca.GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS || - update_nca.GetTitleId() != FileSys::GetUpdateTitleID(title_id)) { + update_nca.GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS || + update_nca.GetTitleId() != FileSys::GetUpdateTitleID(title_id)) { packed_update_raw = {}; } const auto base_romfs = base_nca->GetRomFS(); const auto dump_dir = - target == DumpRomFSTarget::Normal + target == DumpRomFSTarget::Normal ? Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir) : Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "atmosphere" / "contents"; const auto romfs_dir = fmt::format("{:016X}/romfs", title_id); @@ -2898,11 +2904,11 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa bool ok = false; const QStringList selections{tr("Full"), tr("Skeleton")}; const auto res = QInputDialog::getItem( - this, tr("Select RomFS Dump Mode"), - tr("Please select the how you would like the RomFS dumped.
Full will copy all of the " - "files into the new directory while
skeleton will only create the directory " - "structure."), - selections, 0, false, &ok); + this, tr("Select RomFS Dump Mode"), + tr("Please select the how you would like the RomFS dumped.
Full will copy all of the " + "files into the new directory while
skeleton will only create the directory " + "structure."), + selections, 0, false, &ok); if (!ok) { failed(); vfs->DeleteDirectory(path); @@ -2925,7 +2931,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa tr("There is not enough free space at %1 to extract the RomFS. Please " "free up space or select a different dump directory at " "Emulation > Configure > System > Filesystem > Dump Root") - .arg(QString::fromStdString(path))); + .arg(QString::fromStdString(path))); return; } @@ -2996,7 +3002,8 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id, directory = it->second.second; } - QDesktopServices::openUrl(QUrl(QStringLiteral("https://eden-emulator.github.io/game/") + directory)); + QDesktopServices::openUrl( + QUrl(QStringLiteral("https://eden-emulator.github.io/game/") + directory)); } bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path, @@ -3109,8 +3116,8 @@ bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QSt case GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES: buttons = QMessageBox::Yes | QMessageBox::No; result = - QMessageBox::information(parent, tr("Create Shortcut"), - tr("Do you want to launch the game in fullscreen?"), buttons); + QMessageBox::information(parent, tr("Create Shortcut"), + tr("Do you want to launch the game in fullscreen?"), buttons); return result == QMessageBox::Yes; case GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS: QMessageBox::information(parent, tr("Create Shortcut"), @@ -3119,10 +3126,10 @@ bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QSt case GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING: buttons = QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel; result = - QMessageBox::warning(this, tr("Create Shortcut"), - tr("This will create a shortcut to the current AppImage. This may " - "not work well if you update. Continue?"), - buttons); + QMessageBox::warning(this, tr("Create Shortcut"), + tr("This will create a shortcut to the current AppImage. This may " + "not work well if you update. Continue?"), + buttons); return result == QMessageBox::Ok; default: buttons = QMessageBox::Ok; @@ -3145,10 +3152,10 @@ bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_vi // Create icons directory if it doesn't exist if (!Common::FS::CreateDirs(out_icon_path)) { QMessageBox::critical( - this, tr("Create Icon"), - tr("Cannot create icon file. Path \"%1\" does not exist and cannot be created.") - .arg(QString::fromStdString(out_icon_path.string())), - QMessageBox::StandardButton::Ok); + this, tr("Create Icon"), + tr("Cannot create icon file. Path \"%1\" does not exist and cannot be created.") + .arg(QString::fromStdString(out_icon_path.string())), + QMessageBox::StandardButton::Ok); out_icon_path.clear(); return false; } @@ -3171,13 +3178,13 @@ void GMainWindow::OnGameListOpenDirectory(const QString& directory) { std::filesystem::path fs_path; if (directory == QStringLiteral("SDMC")) { fs_path = - Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "Nintendo/Contents/registered"; + Common::FS::GetEdenPath(Common::FS::EdenPath::SDMCDir) / "Nintendo/Contents/registered"; } else if (directory == QStringLiteral("UserNAND")) { fs_path = - Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "user/Contents/registered"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "user/Contents/registered"; } else if (directory == QStringLiteral("SysNAND")) { fs_path = - Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/Contents/registered"; + Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/Contents/registered"; } else { fs_path = directory.toStdString(); } @@ -3238,14 +3245,14 @@ void GMainWindow::OnMenuLoadFile() { is_load_file_select_active = true; const QString extensions = - QStringLiteral("*.") + QStringLiteral("*.") .append(GameList::supported_file_extensions.join(QStringLiteral(" *."))) .append(QStringLiteral(" main")); const QString file_filter = tr("Switch Executable (%1);;All Files (*.*)", "%1 is an identifier for the Switch executable file extensions.") - .arg(extensions); + .arg(extensions); const QString filename = QFileDialog::getOpenFileName( - this, tr("Load File"), QString::fromStdString(UISettings::values.roms_path), file_filter); + this, tr("Load File"), QString::fromStdString(UISettings::values.roms_path), file_filter); is_load_file_select_active = false; if (filename.isEmpty()) { @@ -3258,7 +3265,7 @@ void GMainWindow::OnMenuLoadFile() { void GMainWindow::OnMenuLoadFolder() { const QString dir_path = - QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory")); + QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory")); if (dir_path.isNull()) { return; @@ -3280,13 +3287,13 @@ void GMainWindow::IncrementInstallProgress() { void GMainWindow::OnMenuInstallToNAND() { const QString file_filter = - tr("Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive " - "(*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge " - "Image (*.xci)"); + tr("Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive " + "(*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge " + "Image (*.xci)"); QStringList filenames = QFileDialog::getOpenFileNames( - this, tr("Install Files"), QString::fromStdString(UISettings::values.roms_path), - file_filter); + this, tr("Install Files"), QString::fromStdString(UISettings::values.roms_path), + file_filter); if (filenames.isEmpty()) { return; @@ -3334,7 +3341,7 @@ void GMainWindow::OnMenuInstallToNAND() { for (const QString& file : files) { install_progress->setWindowTitle(tr("%n file(s) remaining", "", remaining)); install_progress->setLabelText( - tr("Installing file \"%1\"...").arg(QFileInfo(file).fileName())); + tr("Installing file \"%1\"...").arg(QFileInfo(file).fileName())); QFuture future; ContentManager::InstallResult result; @@ -3388,19 +3395,19 @@ void GMainWindow::OnMenuInstallToNAND() { if (detected_base_install) { QMessageBox::warning( - this, tr("Install Results"), - tr("To avoid possible conflicts, we discourage users from installing base games to the " - "NAND.\nPlease, only use this feature to install updates and DLC.")); + this, tr("Install Results"), + tr("To avoid possible conflicts, we discourage users from installing base games to the " + "NAND.\nPlease, only use this feature to install updates and DLC.")); } const QString install_results = - (new_files.isEmpty() ? QString{} - : tr("%n file(s) were newly installed\n", "", new_files.size())) + - (overwritten_files.isEmpty() + (new_files.isEmpty() ? QString{} + : tr("%n file(s) were newly installed\n", "", new_files.size())) + + (overwritten_files.isEmpty() ? QString{} : tr("%n file(s) were overwritten\n", "", overwritten_files.size())) + - (failed_files.isEmpty() ? QString{} - : tr("%n file(s) failed to install\n", "", failed_files.size())); + (failed_files.isEmpty() ? QString{} + : tr("%n file(s) failed to install\n", "", failed_files.size())); QMessageBox::information(this, tr("Install Results"), install_results); Common::FS::RemoveDirRecursively(Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / @@ -3411,20 +3418,20 @@ void GMainWindow::OnMenuInstallToNAND() { ContentManager::InstallResult GMainWindow::InstallNCA(const QString& filename) { const QStringList tt_options{tr("System Application"), - tr("System Archive"), - tr("System Application Update"), - tr("Firmware Package (Type A)"), - tr("Firmware Package (Type B)"), - tr("Game"), - tr("Game Update"), - tr("Game DLC"), - tr("Delta Title")}; + tr("System Archive"), + tr("System Application Update"), + tr("Firmware Package (Type A)"), + tr("Firmware Package (Type B)"), + tr("Game"), + tr("Game Update"), + tr("Game DLC"), + tr("Delta Title")}; bool ok; const auto item = QInputDialog::getItem( - this, tr("Select NCA Install Type..."), - tr("Please select the type of title you would like to install this NCA as:\n(In " - "most instances, the default 'Game' is fine.)"), - tt_options, 5, false, &ok); + this, tr("Select NCA Install Type..."), + tr("Please select the type of title you would like to install this NCA as:\n(In " + "most instances, the default 'Game' is fine.)"), + tt_options, 5, false, &ok); auto index = tt_options.indexOf(item); if (!ok || index == -1) { @@ -3436,7 +3443,7 @@ ContentManager::InstallResult GMainWindow::InstallNCA(const QString& filename) { // If index is equal to or past Game, add the jump in TitleType. if (index >= 5) { index += static_cast(FileSys::TitleType::Application) - - static_cast(FileSys::TitleType::FirmwarePackageB); + static_cast(FileSys::TitleType::FirmwarePackageB); } const bool is_application = index >= static_cast(FileSys::TitleType::Application); @@ -3551,7 +3558,7 @@ bool GMainWindow::ConfirmShutdownGame() { } else { if (UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game && - system->GetExitLocked()) { + system->GetExitLocked()) { if (!ConfirmForceLockedExit()) { return false; } @@ -3617,14 +3624,14 @@ void GMainWindow::OnMenuReportCompatibility() { } if (!Settings::values.eden_token.GetValue().empty() && - !Settings::values.eden_username.GetValue().empty()) { + !Settings::values.eden_username.GetValue().empty()) { } else { QMessageBox::critical( - this, tr("Missing yuzu Account"), - tr("In order to submit a game compatibility test case, you must link your eden " - "account.

To link your eden account, go to Emulation > Configuration " - "> " - "Web.")); + this, tr("Missing yuzu Account"), + tr("In order to submit a game compatibility test case, you must link your eden " + "account.

To link your eden account, go to Emulation > Configuration " + "> " + "Web.")); } #else QMessageBox::critical(this, tr("Hardware requirements not met"), @@ -3653,8 +3660,7 @@ void GMainWindow::OnOpenFAQ() { OpenURL(QUrl(QStringLiteral("https://eden-emulator.github.io/"))); } -void GMainWindow::OnOpenDiscord() -{ +void GMainWindow::OnOpenDiscord() { OpenURL(QUrl(QStringLiteral("https://discord.gg/edenemu"))); } @@ -3673,18 +3679,18 @@ void GMainWindow::ToggleFullscreen() { static QScreen* GuessCurrentScreen(QWidget* window) { const QList screens = QGuiApplication::screens(); return *std::max_element( - screens.cbegin(), screens.cend(), [window](const QScreen* left, const QScreen* right) { - const QSize left_size = left->geometry().intersected(window->geometry()).size(); - const QSize right_size = right->geometry().intersected(window->geometry()).size(); - return (left_size.height() * left_size.width()) < - (right_size.height() * right_size.width()); - }); + screens.cbegin(), screens.cend(), [window](const QScreen* left, const QScreen* right) { + const QSize left_size = left->geometry().intersected(window->geometry()).size(); + const QSize right_size = right->geometry().intersected(window->geometry()).size(); + return (left_size.height() * left_size.width()) < + (right_size.height() * right_size.width()); + }); } bool GMainWindow::UsingExclusiveFullscreen() { return Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive || - QGuiApplication::platformName() == QStringLiteral("wayland") || - QGuiApplication::platformName() == QStringLiteral("wayland-egl"); + QGuiApplication::platformName() == QStringLiteral("wayland") || + QGuiApplication::platformName() == QStringLiteral("wayland-egl"); } void GMainWindow::ShowFullscreen() { @@ -3771,8 +3777,8 @@ void GMainWindow::ToggleWindowMode() { void GMainWindow::ResetWindowSize(u32 width, u32 height) { const auto aspect_ratio = Layout::EmulationAspectRatio( - static_cast(Settings::values.aspect_ratio.GetValue()), - static_cast(height) / width); + static_cast(Settings::values.aspect_ratio.GetValue()), + static_cast(height) / width); if (!ui->action_Single_Window_Mode->isChecked()) { render_window->resize(height / aspect_ratio, height); } else { @@ -3811,7 +3817,7 @@ void GMainWindow::OnConfigure() { const auto result = configure_dialog.exec(); if (result != QDialog::Accepted && !UISettings::values.configuration_applied && - !UISettings::values.reset_to_defaults) { + !UISettings::values.reset_to_defaults) { // Runs if the user hit Cancel or closed the window, and did not ever press the Apply button // or `Reset to Defaults` button return; @@ -3826,11 +3832,11 @@ void GMainWindow::OnConfigure() { LOG_WARNING(Frontend, "Failed to remove configuration file"); } if (!Common::FS::RemoveDirContentsRecursively( - Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom")) { + Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir) / "custom")) { LOG_WARNING(Frontend, "Failed to remove custom configuration files"); } if (!Common::FS::RemoveDirRecursively( - Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { + Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "game_list")) { LOG_WARNING(Frontend, "Failed to remove game metadata cache files"); } @@ -4144,12 +4150,12 @@ bool GMainWindow::question(QWidget* parent, const QString& title, const QString& box_dialog->setDefaultButton(defaultButton); ControllerNavigation* controller_navigation = - new ControllerNavigation(system->HIDCore(), box_dialog); + new ControllerNavigation(system->HIDCore(), box_dialog); connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent, [box_dialog](Qt::Key key) { - QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); - QCoreApplication::postEvent(box_dialog, event); - }); + QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); + QCoreApplication::postEvent(box_dialog, event); + }); int res = box_dialog->exec(); controller_navigation->UnloadController(); @@ -4185,32 +4191,28 @@ void GMainWindow::LoadAmiibo(const QString& filename) { } void GMainWindow::OnOpenRootDataFolder() { - QDesktopServices::openUrl(QUrl( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir)))); + QDesktopServices::openUrl( + QUrl(QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::EdenDir)))); } -void GMainWindow::OnOpenNANDFolder() -{ +void GMainWindow::OnOpenNANDFolder() { QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir)))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir)))); } -void GMainWindow::OnOpenSDMCFolder() -{ +void GMainWindow::OnOpenSDMCFolder() { QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir)))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir)))); } -void GMainWindow::OnOpenModFolder() -{ +void GMainWindow::OnOpenModFolder() { QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir)))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir)))); } -void GMainWindow::OnOpenLogFolder() -{ +void GMainWindow::OnOpenLogFolder() { QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir)))); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::LogDir)))); } void GMainWindow::OnVerifyInstalledContents() { @@ -4228,7 +4230,7 @@ void GMainWindow::OnVerifyInstalledContents() { }; const std::vector result = - ContentManager::VerifyInstalledContents(*system, *provider, QtProgressCallback); + ContentManager::VerifyInstalledContents(*system, *provider, QtProgressCallback); progress.close(); if (result.empty()) { @@ -4236,15 +4238,14 @@ void GMainWindow::OnVerifyInstalledContents() { tr("The operation completed successfully.")); } else { const auto failed_names = - QString::fromStdString(fmt::format("{}", fmt::join(result, "\n"))); + QString::fromStdString(fmt::format("{}", fmt::join(result, "\n"))); QMessageBox::critical( - this, tr("Integrity verification failed!"), - tr("Verification failed for the following files:\n\n%1").arg(failed_names)); + this, tr("Integrity verification failed!"), + tr("Verification failed for the following files:\n\n%1").arg(failed_names)); } } -void GMainWindow::InstallFirmware(const QString &location, bool recursive) -{ +void GMainWindow::InstallFirmware(const QString& location, bool recursive) { QProgressDialog progress(tr("Installing Firmware..."), tr("Cancel"), 0, 100, this); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(100); @@ -4270,20 +4271,22 @@ void GMainWindow::InstallFirmware(const QString &location, bool recursive) std::vector out; const Common::FS::DirEntryCallable callback = - [&out](const std::filesystem::directory_entry& entry) { - if (entry.path().has_extension() && entry.path().extension() == ".nca") { - out.emplace_back(entry.path()); - } + [&out](const std::filesystem::directory_entry& entry) { + if (entry.path().has_extension() && entry.path().extension() == ".nca") { + out.emplace_back(entry.path()); + } - return true; - }; + return true; + }; QtProgressCallback(100, 10); if (recursive) { - Common::FS::IterateDirEntriesRecursively(firmware_source_path, callback, Common::FS::DirEntryFilter::File); + Common::FS::IterateDirEntriesRecursively(firmware_source_path, callback, + Common::FS::DirEntryFilter::File); } else { - Common::FS::IterateDirEntries(firmware_source_path, callback, Common::FS::DirEntryFilter::File); + Common::FS::IterateDirEntries(firmware_source_path, callback, + Common::FS::DirEntryFilter::File); } if (out.size() <= 0) { @@ -4314,9 +4317,9 @@ void GMainWindow::InstallFirmware(const QString &location, bool recursive) for (const auto& firmware_src_path : out) { i++; auto firmware_src_vfile = - vfs->OpenFile(firmware_src_path.generic_string(), FileSys::OpenMode::Read); + vfs->OpenFile(firmware_src_path.generic_string(), FileSys::OpenMode::Read); auto firmware_dst_vfile = - firmware_vdir->CreateFileRelative(firmware_src_path.filename().string()); + firmware_vdir->CreateFileRelative(firmware_src_path.filename().string()); if (!VfsRawCopy(firmware_src_vfile, firmware_dst_vfile)) { LOG_ERROR(Frontend, "Failed to copy firmware file {} to {} in registered folder!", @@ -4325,12 +4328,12 @@ void GMainWindow::InstallFirmware(const QString &location, bool recursive) } if (QtProgressCallback( - 100, 20 + static_cast(((i) / static_cast(out.size())) * 70.0))) { + 100, 20 + static_cast(((i) / static_cast(out.size())) * 70.0))) { progress.close(); QMessageBox::warning( - this, tr("Firmware install failed"), - tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. " - "Restart Eden or re-install firmware.")); + this, tr("Firmware install failed"), + tr("Firmware installation cancelled, firmware may be in a bad state or corrupted. " + "Restart Eden or re-install firmware.")); return; } } @@ -4351,15 +4354,15 @@ void GMainWindow::InstallFirmware(const QString &location, bool recursive) }; auto result = - ContentManager::VerifyInstalledContents(*system, *provider, VerifyFirmwareCallback, true); + ContentManager::VerifyInstalledContents(*system, *provider, VerifyFirmwareCallback, true); if (result.size() > 0) { const auto failed_names = - QString::fromStdString(fmt::format("{}", fmt::join(result, "\n"))); + QString::fromStdString(fmt::format("{}", fmt::join(result, "\n"))); progress.close(); QMessageBox::critical( - this, tr("Firmware integrity verification failed!"), - tr("Verification failed for the following files:\n\n%1").arg(failed_names)); + this, tr("Firmware integrity verification failed!"), + tr("Verification failed for the following files:\n\n%1").arg(failed_names)); return; } @@ -4377,13 +4380,13 @@ void GMainWindow::OnInstallFirmware() { // Check for installed keys, error out, suggest restart? if (!ContentManager::AreKeysPresent()) { QMessageBox::information( - this, tr("Keys not installed"), - tr("Install decryption keys and restart Eden before attempting to install firmware.")); + this, tr("Keys not installed"), + tr("Install decryption keys and restart Eden before attempting to install firmware.")); return; } const QString firmware_source_location = QFileDialog::getExistingDirectory( - this, tr("Select Dumped Firmware Source Location"), {}, QFileDialog::ShowDirsOnly); + this, tr("Select Dumped Firmware Source Location"), {}, QFileDialog::ShowDirsOnly); if (firmware_source_location.isEmpty()) { return; } @@ -4391,8 +4394,7 @@ void GMainWindow::OnInstallFirmware() { InstallFirmware(firmware_source_location); } -void GMainWindow::OnInstallFirmwareFromZIP() -{ +void GMainWindow::OnInstallFirmwareFromZIP() { // Don't do this while emulation is running, that'd probably be a bad idea. if (emu_thread != nullptr && emu_thread->IsRunning()) { return; @@ -4401,58 +4403,93 @@ void GMainWindow::OnInstallFirmwareFromZIP() // Check for installed keys, error out, suggest restart? if (!ContentManager::AreKeysPresent()) { QMessageBox::information( - this, tr("Keys not installed"), - tr("Install decryption keys and restart Eden before attempting to install firmware.")); + this, tr("Keys not installed"), + tr("Install decryption keys and restart Eden before attempting to install firmware.")); return; } const QString firmware_zip_location = QFileDialog::getOpenFileName( - this, tr("Select Dumped Firmware ZIP"), {}, tr("Zipped Archives (*.zip)")); + this, tr("Select Dumped Firmware ZIP"), {}, tr("Zipped Archives (*.zip)")); if (firmware_zip_location.isEmpty()) { return; } namespace fs = std::filesystem; - fs::path tmp{std::filesystem::temp_directory_path()}; - - if (!std::filesystem::create_directories(tmp / "eden" / "firmware")) { - goto unzipFailed; - } + fs::path tmp = std::filesystem::temp_directory_path() / "eden" / "firmware"; + QString cache_dir = QString::fromStdString(tmp.string()); { - tmp /= "eden"; - tmp /= "firmware"; - - QString qCacheDir = QString::fromStdString(tmp.string()); - - QFile zip(firmware_zip_location); - - QStringList result = JlCompress::extractDir(&zip, qCacheDir); - if (result.isEmpty()) { - goto unzipFailed; + if (!QDir().mkpath(cache_dir)) { + QMessageBox::critical( + this, tr("Firmware unzip failed"), + tr("Failed to create temp directory.\n" + "Check write permissions in the system temp directory and try again.")); + return; } + int err = 0; + zip_t* zip = zip_open(firmware_zip_location.toUtf8(), 0, &err); + if (zip == nullptr) { + QMessageBox::critical( + this, tr("Firmware unzip failed"), + tr("Failed to open the firmware zip file.\n" + "Check file format and avoid special characters in file path.")); + return; + } + + zip_int64_t num_entries = zip_get_num_entries(zip, 0); + for (zip_int64_t i = 0; i < num_entries; i++) { + const char* name = zip_get_name(zip, i, 0); + if (!name) { + continue; + } + + zip_file_t* zip_file = zip_fopen_index(zip, i, 0); + if (!zip_file) { + continue; + } + + QString file_path = QString::fromStdString(tmp / name); + QFileInfo file_info(file_path); + + QDir().mkpath(file_info.path()); + QFile file(file_path); + + if (!file.open(QIODevice::WriteOnly)) { + zip_fclose(zip_file); + continue; + } + + zip_stat_t sb; + zip_stat_index(zip, i, 0, &sb); + char* contents = new char[sb.size]; + zip_fread(zip_file, contents, sb.size); + file.write(contents, sb.size); + delete[] contents; + + file.close(); + zip_fclose(zip_file); + } + + zip_close(zip); + // In this case, it has to be done recursively, since sometimes people // will pack it into a subdirectory after dumping - InstallFirmware(qCacheDir, true); + InstallFirmware(cache_dir, true); std::error_code ec; std::filesystem::remove_all(tmp, ec); if (ec) { - QMessageBox::warning(this, tr("Firmware cleanup failed"), - tr("Failed to clean up extracted firmware cache.\n" - "Check write permissions in the system temp directory and try again.\nOS reported error: %1") + QMessageBox::warning(this, tr("Firmware cleanup failed"), + tr("Failed to clean up extracted firmware cache.\n" + "Check write permissions in the system temp directory and try " + "again.\nOS reported error: %1") .arg(QString::fromStdString(ec.message()))); } return; } -unzipFailed: - QMessageBox::critical(this, tr("Firmware unzip failed"), - tr("Check write permissions in the system temp directory and try again.")); - return; - } void GMainWindow::OnInstallDecryptionKeys() { @@ -4462,13 +4499,14 @@ void GMainWindow::OnInstallDecryptionKeys() { } const QString key_source_location = QFileDialog::getOpenFileName( - this, tr("Select Dumped Keys Location"), {}, QStringLiteral("Decryption Keys (*.keys)"), {}, - QFileDialog::ReadOnly); + this, tr("Select Dumped Keys Location"), {}, QStringLiteral("Decryption Keys (*.keys)"), {}, + QFileDialog::ReadOnly); if (key_source_location.isEmpty()) { return; } - FirmwareManager::KeyInstallResult result = FirmwareManager::InstallKeys(key_source_location.toStdString(), "keys"); + FirmwareManager::KeyInstallResult result = + FirmwareManager::InstallKeys(key_source_location.toStdString(), "keys"); system->GetFileSystemController().CreateFactories(*vfs); game_list->PopulateAsync(UISettings::values.game_dirs); @@ -4479,9 +4517,8 @@ void GMainWindow::OnInstallDecryptionKeys() { tr("Decryption Keys were successfully installed")); break; default: - QMessageBox::critical( - this, tr("Decryption Keys install failed"), - tr(FirmwareManager::GetKeyInstallResultString(result))); + QMessageBox::critical(this, tr("Decryption Keys install failed"), + tr(FirmwareManager::GetKeyInstallResultString(result))); break; } @@ -4507,8 +4544,7 @@ void GMainWindow::OnToggleStatusBar() { statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked()); } -void GMainWindow::OnGameListRefresh() -{ +void GMainWindow::OnGameListRefresh() { // force reload add-ons etc game_list->ForceRefreshGameDirectory(); } @@ -4593,7 +4629,7 @@ void GMainWindow::OnOpenControllerMenu() { } auto controller_applet_nca = - bis_system->GetEntry(ControllerAppletId, FileSys::ContentRecordType::Program); + bis_system->GetEntry(ControllerAppletId, FileSys::ContentRecordType::Program); if (!controller_applet_nca) { QMessageBox::warning(this, tr("Controller Applet"), tr("Controller Menu is not available. Please reinstall firmware.")); @@ -4631,8 +4667,7 @@ void GMainWindow::OnHomeMenu() { BootGame(filename, LibraryAppletParameters(QLaunchId, Service::AM::AppletId::QLaunch)); } -void GMainWindow::OnInitialSetup() -{ +void GMainWindow::OnInitialSetup() { constexpr u64 Starter = static_cast(Service::AM::AppletProgramId::Starter); auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); if (!bis_system) { @@ -4655,18 +4690,15 @@ void GMainWindow::OnInitialSetup() BootGame(filename, LibraryAppletParameters(Starter, Service::AM::AppletId::Starter)); } -void GMainWindow::OnCreateHomeMenuDesktopShortcut() -{ +void GMainWindow::OnCreateHomeMenuDesktopShortcut() { OnCreateHomeMenuShortcut(GameListShortcutTarget::Desktop); } -void GMainWindow::OnCreateHomeMenuApplicationMenuShortcut() -{ +void GMainWindow::OnCreateHomeMenuApplicationMenuShortcut() { OnCreateHomeMenuShortcut(GameListShortcutTarget::Applications); } -std::filesystem::path GMainWindow::GetEdenCommand() -{ +std::filesystem::path GMainWindow::GetEdenCommand() { std::filesystem::path command; QString appimage = QString::fromLocal8Bit(getenv("APPIMAGE")); @@ -4685,21 +4717,22 @@ std::filesystem::path GMainWindow::GetEdenCommand() return command; } -std::filesystem::path GMainWindow::GetShortcutPath(GameListShortcutTarget target) -{ +std::filesystem::path GMainWindow::GetShortcutPath(GameListShortcutTarget target) { std::filesystem::path shortcut_path{}; if (target == GameListShortcutTarget::Desktop) { shortcut_path = - QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).toStdString(); + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).toStdString(); } else if (target == GameListShortcutTarget::Applications) { shortcut_path = - QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString(); + QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString(); } return shortcut_path; } -void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program_id, const std::string& game_title_, GameListShortcutTarget target, std::string arguments_, const bool needs_title) { +void GMainWindow::CreateShortcut(const std::string& game_path, const u64 program_id, + const std::string& game_title_, GameListShortcutTarget target, + std::string arguments_, const bool needs_title) { // Get path to yuzu executable std::filesystem::path command = GetEdenCommand(); @@ -4708,17 +4741,17 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program if (!std::filesystem::exists(shortcut_path)) { GMainWindow::CreateShortcutMessagesGUI( - this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR, - QString::fromStdString(shortcut_path.generic_string())); + this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR, + QString::fromStdString(shortcut_path.generic_string())); LOG_ERROR(Frontend, "Invalid shortcut target {}", shortcut_path.generic_string()); return; } const FileSys::PatchManager pm{program_id, system->GetFileSystemController(), - system->GetContentProvider()}; + system->GetContentProvider()}; const auto control = pm.GetControlMetadata(); const auto loader = - Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::OpenMode::Read)); + Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::OpenMode::Read)); std::string game_title{game_title_}; @@ -4750,7 +4783,7 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program } QImage icon_data = - QImage::fromData(icon_image_file.data(), static_cast(icon_image_file.size())); + QImage::fromData(icon_image_file.data(), static_cast(icon_image_file.size())); std::filesystem::path out_icon_path; if (GMainWindow::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) { if (!SaveIconToFile(out_icon_path, icon_data)) { @@ -4763,7 +4796,7 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program // Warn once if we are making a shortcut to a volatile AppImage if (command.string().ends_with(".AppImage") && !UISettings::values.shortcut_already_warned) { if (!GMainWindow::CreateShortcutMessagesGUI( - this, GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING, qgame_title)) { + this, GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING, qgame_title)) { return; } UISettings::values.shortcut_already_warned = true; @@ -4773,15 +4806,15 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program // Create shortcut std::string arguments{arguments_}; if (GMainWindow::CreateShortcutMessagesGUI( - this, GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, qgame_title)) { + this, GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, qgame_title)) { arguments = "-f " + arguments; } const std::string comment = fmt::format("Start {:s} with the eden Emulator", game_title); const std::string categories = "Game;Emulator;Qt;"; const std::string keywords = "Switch;Nintendo;"; - if (GMainWindow::CreateShortcutLink(shortcut_path, comment, out_icon_path, command, - arguments, categories, keywords, game_title)) { + if (GMainWindow::CreateShortcutLink(shortcut_path, comment, out_icon_path, command, arguments, + categories, keywords, game_title)) { GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS, qgame_title); return; @@ -4790,8 +4823,7 @@ void GMainWindow::CreateShortcut(const std::string &game_path, const u64 program qgame_title); } -void GMainWindow::OnCreateHomeMenuShortcut(GameListShortcutTarget target) -{ +void GMainWindow::OnCreateHomeMenuShortcut(GameListShortcutTarget target) { constexpr u64 QLaunchId = static_cast(Service::AM::AppletProgramId::QLaunch); auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); if (!bis_system) { @@ -4820,13 +4852,13 @@ void GMainWindow::OnCaptureScreenshot() { const u64 title_id = system->GetApplicationProcessProgramID(); const auto screenshot_path = - QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::ScreenshotsDir)); + QString::fromStdString(Common::FS::GetEdenPathString(Common::FS::EdenPath::ScreenshotsDir)); const auto date = - QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd_hh-mm-ss-zzz")); + QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd_hh-mm-ss-zzz")); QString filename = QStringLiteral("%1/%2_%3.png") - .arg(screenshot_path) - .arg(title_id, 16, 16, QLatin1Char{'0'}) - .arg(date); + .arg(screenshot_path) + .arg(title_id, 16, 16, QLatin1Char{'0'}) + .arg(date); if (!Common::FS::CreateDir(screenshot_path.toStdString())) { return; @@ -4850,7 +4882,7 @@ void GMainWindow::OnCaptureScreenshot() { void GMainWindow::MigrateConfigFiles() { const auto config_dir_fs_path = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir); const QDir config_dir = - QDir(QString::fromStdString(Common::FS::PathToUTF8String(config_dir_fs_path))); + QDir(QString::fromStdString(Common::FS::PathToUTF8String(config_dir_fs_path))); const QStringList config_dir_list = config_dir.entryList(QStringList(QStringLiteral("*.ini"))); if (!Common::FS::CreateDirs(config_dir_fs_path / "custom")) { @@ -4884,13 +4916,13 @@ void GMainWindow::OnEmulatorUpdateAvailable() { update_prompt.setIcon(QMessageBox::Information); update_prompt.addButton(QMessageBox::Yes); update_prompt.addButton(QMessageBox::Ignore); - update_prompt.setText(tr("Update %1 for Eden is available.\nWould you like to download it?") - .arg(version_string)); + update_prompt.setText( + tr("Update %1 for Eden is available.\nWould you like to download it?").arg(version_string)); update_prompt.exec(); if (update_prompt.button(QMessageBox::Yes) == update_prompt.clickedButton()) { QDesktopServices::openUrl( - QUrl(QString::fromStdString("https://github.com/eden-emulator/Releases/releases/tag/") + - version_string)); + QUrl(QString::fromStdString("https://github.com/eden-emulator/Releases/releases/tag/") + + version_string)); } } #endif @@ -4908,7 +4940,7 @@ void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_vie } const auto override_title = - fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); + fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); const auto window_title = override_title.empty() ? yuzu_title : override_title; if (title_name.empty()) { @@ -4926,7 +4958,7 @@ void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_vie } std::string GMainWindow::CreateTASFramesString( - std::array frames) const { + std::array frames) const { std::string string = ""; size_t maxPlayerIndex = 0; for (size_t i = 0; i < frames.size(); i++) { @@ -4947,14 +4979,14 @@ QString GMainWindow::GetTasStateDescription() const { switch (tas_status) { case InputCommon::TasInput::TasState::Running: return tr("TAS state: Running %1/%2") - .arg(current_tas_frame) - .arg(QString::fromStdString(tas_frames_string)); + .arg(current_tas_frame) + .arg(QString::fromStdString(tas_frames_string)); case InputCommon::TasInput::TasState::Recording: return tr("TAS state: Recording %1").arg(total_tas_frames[0]); case InputCommon::TasInput::TasState::Stopped: return tr("TAS state: Idle %1/%2") - .arg(current_tas_frame) - .arg(QString::fromStdString(tas_frames_string)); + .arg(current_tas_frame) + .arg(QString::fromStdString(tas_frames_string)); default: return tr("TAS State: Invalid"); } @@ -4965,7 +4997,7 @@ void GMainWindow::OnTasStateChanged() { bool is_recording = false; if (emulation_running) { const InputCommon::TasInput::TasState tas_status = - std::get<0>(input_subsystem->GetTas()->GetStatus()); + std::get<0>(input_subsystem->GetTas()->GetStatus()); is_running = tas_status == InputCommon::TasInput::TasState::Running; is_recording = tas_status == InputCommon::TasInput::TasState::Recording; } @@ -5004,18 +5036,19 @@ void GMainWindow::UpdateStatusBar() { const auto res_info = Settings::values.resolution_info; const auto res_scale = res_info.up_factor; res_scale_label->setText( - tr("Scale: %1x", "%1 is the resolution scaling factor").arg(res_scale)); + tr("Scale: %1x", "%1 is the resolution scaling factor").arg(res_scale)); if (Settings::values.use_speed_limit.GetValue()) { emu_speed_label->setText(tr("Speed: %1% / %2%") - .arg(results.emulation_speed * 100.0, 0, 'f', 0) - .arg(Settings::values.speed_limit.GetValue())); + .arg(results.emulation_speed * 100.0, 0, 'f', 0) + .arg(Settings::values.speed_limit.GetValue())); } else { emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); } game_fps_label->setText( - tr("Game: %1 FPS").arg(std::round(results.average_game_fps), 0, 'f', 0) + tr(Settings::values.use_speed_limit ? "" : " (Unlocked)")); + tr("Game: %1 FPS").arg(std::round(results.average_game_fps), 0, 'f', 0) + + tr(Settings::values.use_speed_limit ? "" : " (Unlocked)")); emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); @@ -5029,7 +5062,7 @@ void GMainWindow::UpdateStatusBar() { void GMainWindow::UpdateGPUAccuracyButton() { const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue(); const auto gpu_accuracy_text = - ConfigurationShared::gpu_accuracy_texts_map.find(gpu_accuracy)->second; + ConfigurationShared::gpu_accuracy_texts_map.find(gpu_accuracy)->second; gpu_accuracy_button->setText(gpu_accuracy_text.toUpper()); gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GpuAccuracy::Normal); } @@ -5038,20 +5071,20 @@ void GMainWindow::UpdateDockedButton() { const auto console_mode = Settings::values.use_docked_mode.GetValue(); dock_status_button->setChecked(Settings::IsDockedMode()); dock_status_button->setText( - ConfigurationShared::use_docked_mode_texts_map.find(console_mode)->second.toUpper()); + ConfigurationShared::use_docked_mode_texts_map.find(console_mode)->second.toUpper()); } void GMainWindow::UpdateAPIText() { const auto api = Settings::values.renderer_backend.GetValue(); const auto renderer_status_text = - ConfigurationShared::renderer_backend_texts_map.find(api)->second; + ConfigurationShared::renderer_backend_texts_map.find(api)->second; renderer_status_button->setText( - api == Settings::RendererBackend::OpenGL - ? tr("%1 %2").arg(renderer_status_text.toUpper(), - ConfigurationShared::shader_backend_texts_map + api == Settings::RendererBackend::OpenGL + ? tr("%1 %2").arg(renderer_status_text.toUpper(), + ConfigurationShared::shader_backend_texts_map .find(Settings::values.shader_backend.GetValue()) ->second) - : renderer_status_text.toUpper()); + : renderer_status_text.toUpper()); } void GMainWindow::UpdateFilterText() { @@ -5065,8 +5098,8 @@ void GMainWindow::UpdateAAText() { const auto aa_mode = Settings::values.anti_aliasing.GetValue(); const auto aa_text = ConfigurationShared::anti_aliasing_texts_map.find(aa_mode)->second; aa_status_button->setText(aa_mode == Settings::AntiAliasing::None - ? QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "NO AA")) - : aa_text.toUpper()); + ? QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "NO AA")) + : aa_text.toUpper()); } void GMainWindow::UpdateVolumeUI() { @@ -5142,25 +5175,22 @@ void GMainWindow::OnMouseActivity() { void GMainWindow::OnCheckFirmwareDecryption() { system->GetFileSystemController().CreateFactories(*vfs); if (!ContentManager::AreKeysPresent()) { - QMessageBox::warning( - this, tr("Derivation Components Missing"), - tr("Encryption keys are missing.")); + QMessageBox::warning(this, tr("Derivation Components Missing"), + tr("Encryption keys are missing.")); } SetFirmwareVersion(); UpdateMenuState(); } -void GMainWindow::OnCheckFirmware() -{ +void GMainWindow::OnCheckFirmware() { auto result = FirmwareManager::VerifyFirmware(*system.get()); switch (result) { - case FirmwareManager::FirmwareGood: + case FirmwareManager::FirmwareGood: break; default: - QMessageBox::warning( - this, tr("Firmware Read Error"), - tr(FirmwareManager::GetFirmwareCheckString(result))); + QMessageBox::warning(this, tr("Firmware Read Error"), + tr(FirmwareManager::GetFirmwareCheckString(result))); break; } } @@ -5197,11 +5227,11 @@ bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installe boost::container::flat_set available_title_ids; const auto RetrieveEntries = [&](FileSys::TitleType title_type, - FileSys::ContentRecordType record_type) { + FileSys::ContentRecordType record_type) { const auto entries = installed.ListEntriesFilter(title_type, record_type); for (const auto& entry : entries) { if (FileSys::GetBaseTitleID(entry.title_id) == program_id && - installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success) { + installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success) { available_title_ids.insert({entry.title_id, title_type, record_type}); } } @@ -5230,14 +5260,14 @@ bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installe list.push_back(QStringLiteral("Legal information [%1]").arg(hex_title_id)); } else { list.push_back( - QStringLiteral("DLC %1 [%2]").arg(title_id & 0x7FF).arg(hex_title_id)); + QStringLiteral("DLC %1 [%2]").arg(title_id & 0x7FF).arg(hex_title_id)); } } bool ok; const auto res = QInputDialog::getItem( - this, tr("Select RomFS Dump Target"), - tr("Please select which RomFS you would like to dump."), list, 0, false, &ok); + this, tr("Select RomFS Dump Target"), + tr("Please select which RomFS you would like to dump."), list, 0, false, &ok); if (!ok) { return false; } @@ -5253,11 +5283,11 @@ bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installe bool GMainWindow::ConfirmClose() { if (emu_thread == nullptr || - UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) { + UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) { return true; } if (!system->GetExitLocked() && - UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) { + UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) { return true; } const auto text = tr("Are you sure you want to close eden?"); @@ -5341,9 +5371,9 @@ bool GMainWindow::ConfirmChangeGame() { // Use custom question to link controller navigation return question( - this, tr("eden"), - tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + this, tr("eden"), + tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); } bool GMainWindow::ConfirmForceLockedExit() { @@ -5384,7 +5414,7 @@ static void AdjustLinkColor() { void GMainWindow::UpdateUITheme() { const QString default_theme = QString::fromUtf8( - UISettings::themes[static_cast(UISettings::default_theme)].second); + UISettings::themes[static_cast(UISettings::default_theme)].second); QString current_theme = QString::fromStdString(UISettings::values.theme); if (current_theme.isEmpty()) { @@ -5507,16 +5537,16 @@ void GMainWindow::changeEvent(QEvent* event) { Service::AM::FrontendAppletParameters GMainWindow::ApplicationAppletParameters() { return Service::AM::FrontendAppletParameters{ .applet_id = Service::AM::AppletId::Application, - .applet_type = Service::AM::AppletType::Application, + .applet_type = Service::AM::AppletType::Application, }; } Service::AM::FrontendAppletParameters GMainWindow::LibraryAppletParameters( - u64 program_id, Service::AM::AppletId applet_id) { + u64 program_id, Service::AM::AppletId applet_id) { return Service::AM::FrontendAppletParameters{ .program_id = program_id, - .applet_id = applet_id, - .applet_type = Service::AM::AppletType::LibraryApplet, + .applet_id = applet_id, + .applet_type = Service::AM::AppletType::LibraryApplet, }; } @@ -5529,10 +5559,10 @@ void VolumeButton::wheelEvent(QWheelEvent* event) { if (num_steps > 0) { Settings::values.volume.SetValue( - std::min(200, Settings::values.volume.GetValue() + num_steps)); + std::min(200, Settings::values.volume.GetValue() + num_steps)); } else { Settings::values.volume.SetValue( - std::max(0, Settings::values.volume.GetValue() + num_steps)); + std::max(0, Settings::values.volume.GetValue() + num_steps)); } scroll_multiplier = std::min(MaxMultiplier, scroll_multiplier * 2); @@ -5584,15 +5614,15 @@ static void SetHighDPIAttributes() { if (max_ratio > real_ratio) { QApplication::setHighDpiScaleFactorRoundingPolicy( - Qt::HighDpiScaleFactorRoundingPolicy::Round); + Qt::HighDpiScaleFactorRoundingPolicy::Round); } else { QApplication::setHighDpiScaleFactorRoundingPolicy( - Qt::HighDpiScaleFactorRoundingPolicy::Floor); + Qt::HighDpiScaleFactorRoundingPolicy::Floor); } #else // Other OSes should be better than Windows at fractional scaling. QApplication::setHighDpiScaleFactorRoundingPolicy( - Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); + Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 7e7c00ec0b..4e640d6c23 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -608,12 +608,9 @@ private: std::filesystem::path GetEdenCommand(); - void CreateShortcut(const std::string& game_path, - const u64 program_id, - const std::string& game_title, - GameListShortcutTarget target, - std::string arguments, - const bool needs_title); + void CreateShortcut(const std::string& game_path, const u64 program_id, + const std::string& game_title, GameListShortcutTarget target, + std::string arguments, const bool needs_title); void InstallFirmware(const QString& location, bool recursive = false); diff --git a/src/yuzu/migration_dialog.cpp b/src/yuzu/migration_dialog.cpp index 9cc40841e8..d7f2d6132f 100644 --- a/src/yuzu/migration_dialog.cpp +++ b/src/yuzu/migration_dialog.cpp @@ -6,11 +6,8 @@ #include #include -MigrationDialog::MigrationDialog( - QWidget *parent) - : QDialog(parent) -{ - QVBoxLayout *layout = new QVBoxLayout(this); +MigrationDialog::MigrationDialog(QWidget* parent) : QDialog(parent) { + QVBoxLayout* layout = new QVBoxLayout(this); m_text = new QLabel(this); m_boxes = new QVBoxLayout; @@ -26,23 +23,16 @@ MigrationDialog::~MigrationDialog() { m_buttons->deleteLater(); } -void MigrationDialog::setText( - const QString &text) -{ +void MigrationDialog::setText(const QString& text) { m_text->setText(text); } -void MigrationDialog::addBox( - QWidget *box) -{ +void MigrationDialog::addBox(QWidget* box) { m_boxes->addWidget(box); - } -QAbstractButton *MigrationDialog::addButton( - const QString &text, const bool reject) -{ - QAbstractButton *button = new QPushButton(this); +QAbstractButton* MigrationDialog::addButton(const QString& text, const bool reject) { + QAbstractButton* button = new QPushButton(this); button->setText(text); m_buttons->addWidget(button, 1); @@ -58,7 +48,6 @@ QAbstractButton *MigrationDialog::addButton( return button; } -QAbstractButton *MigrationDialog::clickedButton() const -{ +QAbstractButton* MigrationDialog::clickedButton() const { return m_clickedButton; } diff --git a/src/yuzu/migration_dialog.h b/src/yuzu/migration_dialog.h index 7123fd6b87..02ad17d324 100644 --- a/src/yuzu/migration_dialog.h +++ b/src/yuzu/migration_dialog.h @@ -1,30 +1,30 @@ #ifndef MIGRATION_DIALOG_H #define MIGRATION_DIALOG_H -#include -#include #include +#include #include +#include class MigrationDialog : public QDialog { Q_OBJECT public: - MigrationDialog(QWidget *parent = nullptr); + MigrationDialog(QWidget* parent = nullptr); virtual ~MigrationDialog(); - void setText(const QString &text); - void addBox(QWidget *box); - QAbstractButton *addButton(const QString &text, const bool reject = false); + void setText(const QString& text); + void addBox(QWidget* box); + QAbstractButton* addButton(const QString& text, const bool reject = false); - QAbstractButton *clickedButton() const; + QAbstractButton* clickedButton() const; private: - QLabel *m_text; - QVBoxLayout *m_boxes; - QHBoxLayout *m_buttons; + QLabel* m_text; + QVBoxLayout* m_boxes; + QHBoxLayout* m_buttons; - QAbstractButton *m_clickedButton; + QAbstractButton* m_clickedButton; }; #endif // MIGRATION_DIALOG_H diff --git a/src/yuzu/migration_worker.cpp b/src/yuzu/migration_worker.cpp index 42ec006026..8507f50a95 100644 --- a/src/yuzu/migration_worker.cpp +++ b/src/yuzu/migration_worker.cpp @@ -3,41 +3,36 @@ #include "migration_worker.h" +#include #include #include #include -#include #include #include "common/fs/path_util.h" MigrationWorker::MigrationWorker(const Emulator selected_legacy_emu_, - const bool clear_shader_cache_, - const MigrationStrategy strategy_) - : QObject() - , selected_legacy_emu(selected_legacy_emu_) - , clear_shader_cache(clear_shader_cache_) - , strategy(strategy_) -{} + const bool clear_shader_cache_, const MigrationStrategy strategy_) + : QObject(), selected_legacy_emu(selected_legacy_emu_), clear_shader_cache(clear_shader_cache_), + strategy(strategy_) {} -void MigrationWorker::process() -{ +void MigrationWorker::process() { namespace fs = std::filesystem; constexpr auto copy_options = fs::copy_options::update_existing | fs::copy_options::recursive; - const fs::path legacy_user_dir = selected_legacy_emu.get_user_dir(); + const fs::path legacy_user_dir = selected_legacy_emu.get_user_dir(); const fs::path legacy_config_dir = selected_legacy_emu.get_config_dir(); - const fs::path legacy_cache_dir = selected_legacy_emu.get_cache_dir(); + const fs::path legacy_cache_dir = selected_legacy_emu.get_cache_dir(); // TODO(crueter): Make these constexpr since they're defaulted - const fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir); + const fs::path eden_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::EdenDir); const fs::path config_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir); - const fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); + const fs::path cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); const fs::path shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir); try { fs::remove_all(eden_dir); - } catch (fs::filesystem_error &_) { + } catch (fs::filesystem_error& _) { // ignore because linux does stupid crap sometimes. } @@ -48,7 +43,7 @@ void MigrationWorker::process() // Windows 11 has random permission nonsense to deal with. try { fs::create_directory_symlink(legacy_user_dir, eden_dir); - } catch (const fs::filesystem_error &e) { + } catch (const fs::filesystem_error& e) { emit error(tr("Linking the old directory failed. You may need to re-run with " "administrative privileges on Windows.\nOS gave error: %1") .arg(tr(e.what()))); diff --git a/src/yuzu/migration_worker.h b/src/yuzu/migration_worker.h index 4d678e7751..1653a6eab4 100644 --- a/src/yuzu/migration_worker.h +++ b/src/yuzu/migration_worker.h @@ -10,7 +10,7 @@ using namespace Common::FS; typedef struct Emulator { - const char *name; + const char* name; LegacyPath e_user_dir; LegacyPath e_config_dir; @@ -31,13 +31,16 @@ typedef struct Emulator { const std::string lower_name() const { std::string lower_name{name}; std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), - [](unsigned char c){ return std::tolower(c); }); + [](unsigned char c) { return std::tolower(c); }); return lower_name; } } Emulator; -#define EMU(name) Emulator{#name, name##Dir, name##ConfigDir, name##CacheDir} +#define EMU(name) \ + Emulator { \ + #name, name##Dir, name##ConfigDir, name##CacheDir \ + } static constexpr std::array legacy_emus = { EMU(Citron), EMU(Sudachi), @@ -46,8 +49,7 @@ static constexpr std::array legacy_emus = { }; #undef EMU -class MigrationWorker : public QObject -{ +class MigrationWorker : public QObject { Q_OBJECT public: enum class MigrationStrategy { @@ -56,16 +58,15 @@ public: Link, }; - MigrationWorker(const Emulator selected_legacy_emu, - const bool clear_shader_cache, + MigrationWorker(const Emulator selected_legacy_emu, const bool clear_shader_cache, const MigrationStrategy strategy); public slots: void process(); signals: - void finished(const QString &success_text, const std::string &user_dir); - void error(const QString &error_message); + void finished(const QString& success_text, const std::string& user_dir); + void error(const QString& error_message); private: Emulator selected_legacy_emu; diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp index 6471ad1632..eb7dccbe8d 100644 --- a/src/yuzu/multiplayer/host_room.cpp +++ b/src/yuzu/multiplayer/host_room.cpp @@ -34,8 +34,7 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list, std::shared_ptr session, Core::System& system_) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), - ui(std::make_unique()), - announce_multiplayer_session(session), system{system_} { + ui(std::make_unique()), announce_multiplayer_session(session), system{system_} { ui->setupUi(this); // set up validation for all of the fields diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp index 93ff56a652..214fb8b6d0 100644 --- a/src/yuzu/multiplayer/lobby.cpp +++ b/src/yuzu/multiplayer/lobby.cpp @@ -30,8 +30,7 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, std::shared_ptr session, Core::System& system_) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), - ui(std::make_unique()), - announce_multiplayer_session(session), system{system_} { + ui(std::make_unique()), announce_multiplayer_session(session), system{system_} { ui->setupUi(this); // setup the watcher for background connections diff --git a/src/yuzu/update_checker.cpp b/src/yuzu/update_checker.cpp index 8291987d73..d1762f5ea6 100644 --- a/src/yuzu/update_checker.cpp +++ b/src/yuzu/update_checker.cpp @@ -5,16 +5,15 @@ // SPDX-FileCopyrightText: eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later -#include "update_checker.h" -#include "common/logging/log.h" +#include +#include #include #include #include -#include -#include +#include "common/logging/log.h" +#include "update_checker.h" -std::optional UpdateChecker::GetResponse(std::string url, std::string path) -{ +std::optional UpdateChecker::GetResponse(std::string url, std::string path) { constexpr std::size_t timeout_seconds = 15; std::unique_ptr client = std::make_unique(url); @@ -41,7 +40,8 @@ std::optional UpdateChecker::GetResponse(std::string url, std::stri const auto& response = result.value(); if (response.status >= 400) { - LOG_ERROR(Frontend, "GET to {}{} returned error status code: {}", url, path, response.status); + LOG_ERROR(Frontend, "GET to {}{} returned error status code: {}", url, path, + response.status); return {}; } if (!response.headers.contains("content-type")) { @@ -52,8 +52,7 @@ std::optional UpdateChecker::GetResponse(std::string url, std::stri return response.body; } -std::optional UpdateChecker::GetLatestRelease(bool include_prereleases) -{ +std::optional UpdateChecker::GetLatestRelease(bool include_prereleases) { constexpr auto update_check_url = "http://api.github.com"; std::string update_check_path = "/repos/eden-emulator/Releases"; try { @@ -63,16 +62,17 @@ std::optional UpdateChecker::GetLatestRelease(bool include_prerelea const auto update_check_releases_path = update_check_path + "/releases"; const auto tags_response = GetResponse(update_check_url, update_check_tags_path); - const auto releases_response = GetResponse(update_check_url, update_check_releases_path); + const auto releases_response = + GetResponse(update_check_url, update_check_releases_path); if (!tags_response || !releases_response) return {}; - const std::string latest_tag - = nlohmann::json::parse(tags_response.value()).at(0).at("name"); - const bool latest_tag_has_release = releases_response.value().find( - fmt::format("\"{}\"", latest_tag)) - != std::string::npos; + const std::string latest_tag = + nlohmann::json::parse(tags_response.value()).at(0).at("name"); + const bool latest_tag_has_release = + releases_response.value().find(fmt::format("\"{}\"", latest_tag)) != + std::string::npos; // If there is a newer tag, but that tag has no associated release, don't prompt the // user to update. @@ -95,15 +95,13 @@ std::optional UpdateChecker::GetLatestRelease(bool include_prerelea LOG_ERROR(Frontend, "Parsing JSON response from {}{} failed during update check: " "nlohmann::detail::out_of_range", - update_check_url, - update_check_path); + update_check_url, update_check_path); return {}; } catch (nlohmann::detail::type_error&) { LOG_ERROR(Frontend, "Parsing JSON response from {}{} failed during update check: " "nlohmann::detail::type_error", - update_check_url, - update_check_path); + update_check_url, update_check_path); return {}; } } diff --git a/src/yuzu/user_data_migration.cpp b/src/yuzu/user_data_migration.cpp index df6b7be434..662ae3f5bf 100644 --- a/src/yuzu/user_data_migration.cpp +++ b/src/yuzu/user_data_migration.cpp @@ -5,66 +5,65 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "user_data_migration.h" #include #include #include #include #include "common/fs/path_util.h" #include "migration_dialog.h" +#include "user_data_migration.h" // Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263 +#include #include #include #include #include #include #include -#include namespace fs = std::filesystem; -UserDataMigrator::UserDataMigrator(QMainWindow *main_window) -{ +UserDataMigrator::UserDataMigrator(QMainWindow* main_window) { // NOTE: Logging is not initialized yet, do not produce logs here. // Check migration if config directory does not exist - // TODO: ProfileManager messes with us a bit here, and force-creates the /nand/system/save/8000000000000010/su/avators/profiles.dat - // file. Find a way to reorder operations and have it create after this guy runs. + // TODO: ProfileManager messes with us a bit here, and force-creates the + // /nand/system/save/8000000000000010/su/avators/profiles.dat file. Find a way to reorder + // operations and have it create after this guy runs. if (!fs::is_directory(Common::FS::GetEdenPath(Common::FS::EdenPath::ConfigDir))) { ShowMigrationPrompt(main_window); } } -void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) -{ +void UserDataMigrator::ShowMigrationPrompt(QMainWindow* main_window) { namespace fs = std::filesystem; // define strings here for easy access - static constexpr const char *prompt_prefix_text - = "Eden has detected user data for the following emulators:"; + static constexpr const char* prompt_prefix_text = + "Eden has detected user data for the following emulators:"; - static constexpr const char *migration_prompt_message - = "Would you like to migrate your data for use in Eden?\n" - "Select the corresponding button to migrate data from that emulator.\n" - "This may take a while."; + static constexpr const char* migration_prompt_message = + "Would you like to migrate your data for use in Eden?\n" + "Select the corresponding button to migrate data from that emulator.\n" + "This may take a while."; - static constexpr const char *clear_shader_tooltip - = "Clearing shader cache is recommended for all " - "users.\nDo not uncheck unless you know what " - "you're doing."; + static constexpr const char* clear_shader_tooltip = + "Clearing shader cache is recommended for all " + "users.\nDo not uncheck unless you know what " + "you're doing."; - static constexpr const char *keep_old_data_tooltip - = "Keeps the old data directory. This is recommended if you aren't\n" - "space-constrained and want to keep separate data for the old emulator."; + static constexpr const char* keep_old_data_tooltip = + "Keeps the old data directory. This is recommended if you aren't\n" + "space-constrained and want to keep separate data for the old emulator."; - static constexpr const char *clear_old_data_tooltip - = "Deletes the old data directory.\nThis is recommended on " - "devices with space constraints."; + static constexpr const char* clear_old_data_tooltip = + "Deletes the old data directory.\nThis is recommended on " + "devices with space constraints."; - static constexpr const char *link_old_dir_tooltip - = "Creates a filesystem link between the old directory and Eden directory.\n" - "This is recommended if you want to share data between emulators."; + static constexpr const char* link_old_dir_tooltip = + "Creates a filesystem link between the old directory and Eden directory.\n" + "This is recommended if you want to share data between emulators."; // actual migration code @@ -72,23 +71,23 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) migration_prompt.setWindowTitle(QObject::tr("Migration")); // mutually exclusive - QButtonGroup *group = new QButtonGroup(&migration_prompt); + QButtonGroup* group = new QButtonGroup(&migration_prompt); // MACRO MADNESS -#define BUTTON(clazz, name, text, tooltip, checkState) \ - clazz *name = new clazz(&migration_prompt); \ - name->setText(QObject::tr(text)); \ - name->setToolTip(QObject::tr(tooltip)); \ - name->setChecked(checkState); \ +#define BUTTON(clazz, name, text, tooltip, checkState) \ + clazz* name = new clazz(&migration_prompt); \ + name->setText(QObject::tr(text)); \ + name->setToolTip(QObject::tr(tooltip)); \ + name->setChecked(checkState); \ migration_prompt.addBox(name); BUTTON(QCheckBox, clear_shaders, "Clear Shader Cache", clear_shader_tooltip, true) u32 id = 0; -#define RADIO(name, text, tooltip, checkState) \ - BUTTON(QRadioButton, name, text, tooltip, checkState) \ +#define RADIO(name, text, tooltip, checkState) \ + BUTTON(QRadioButton, name, text, tooltip, checkState) \ group->addButton(name, ++id); RADIO(keep_old, "Keep Old Data", keep_old_data_tooltip, true) @@ -100,7 +99,7 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) std::vector found{}; - for (const Emulator &emu : legacy_emus) + for (const Emulator& emu : legacy_emus) if (fs::is_directory(emu.get_user_dir())) found.emplace_back(emu); @@ -114,10 +113,10 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) QString prompt_text = QObject::tr(prompt_prefix_text); // natural language processing is a nightmare - for (const Emulator &emu : found) { + for (const Emulator& emu : found) { prompt_text.append(QStringLiteral("\n- %1").arg(QObject::tr(emu.name))); - QAbstractButton *button = migration_prompt.addButton(QObject::tr(emu.name)); + QAbstractButton* button = migration_prompt.addButton(QObject::tr(emu.name)); // This is cursed, but it's actually the most efficient way by a mile button->setProperty("emulator", QVariant::fromValue(emu)); @@ -131,7 +130,7 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) migration_prompt.exec(); - QAbstractButton *button = migration_prompt.clickedButton(); + QAbstractButton* button = migration_prompt.clickedButton(); if (button->text() == QObject::tr("No")) { return ShowMigrationCancelledMessage(main_window); @@ -153,16 +152,12 @@ void UserDataMigrator::ShowMigrationPrompt(QMainWindow *main_window) break; } - MigrateUserData(main_window, - button->property("emulator").value(), - clear_shaders->isChecked(), - strategy); + MigrateUserData(main_window, button->property("emulator").value(), + clear_shaders->isChecked(), strategy); } -void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow *main_window) -{ - QMessageBox::information(main_window, - QObject::tr("Migration"), +void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow* main_window) { + QMessageBox::information(main_window, QObject::tr("Migration"), QObject::tr("You can manually re-trigger this prompt by deleting the " "new config directory:\n%1") .arg(QString::fromStdString(Common::FS::GetEdenPathString( @@ -170,37 +165,35 @@ void UserDataMigrator::ShowMigrationCancelledMessage(QMainWindow *main_window) QMessageBox::Ok); } -void UserDataMigrator::MigrateUserData(QMainWindow *main_window, - const Emulator selected_legacy_emu, +void UserDataMigrator::MigrateUserData(QMainWindow* main_window, const Emulator selected_legacy_emu, const bool clear_shader_cache, - const MigrationWorker::MigrationStrategy strategy) -{ + const MigrationWorker::MigrationStrategy strategy) { selected_emu = selected_legacy_emu; // Create a dialog to let the user know it's migrating - QProgressDialog *progress = new QProgressDialog(main_window); + QProgressDialog* progress = new QProgressDialog(main_window); progress->setWindowTitle(QObject::tr("Migrating")); progress->setLabelText(QObject::tr("Migrating, this may take a while...")); progress->setRange(0, 0); progress->setCancelButton(nullptr); progress->setWindowModality(Qt::WindowModality::ApplicationModal); - QThread *thread = new QThread(main_window); - MigrationWorker *worker = new MigrationWorker(selected_legacy_emu, clear_shader_cache, strategy); + QThread* thread = new QThread(main_window); + MigrationWorker* worker = + new MigrationWorker(selected_legacy_emu, clear_shader_cache, strategy); worker->moveToThread(thread); thread->connect(thread, &QThread::started, worker, &MigrationWorker::process); - thread->connect(worker, &MigrationWorker::finished, progress, [=, this](const QString &success_text, const std::string &path) { - progress->close(); - QMessageBox::information(main_window, - QObject::tr("Migration"), - success_text, - QMessageBox::Ok); + thread->connect(worker, &MigrationWorker::finished, progress, + [=, this](const QString& success_text, const std::string& path) { + progress->close(); + QMessageBox::information(main_window, QObject::tr("Migration"), + success_text, QMessageBox::Ok); - migrated = true; - thread->quit(); - }); + migrated = true; + thread->quit(); + }); thread->connect(worker, &MigrationWorker::finished, worker, &QObject::deleteLater); thread->connect(thread, &QThread::finished, thread, &QObject::deleteLater); diff --git a/src/yuzu/user_data_migration.h b/src/yuzu/user_data_migration.h index 3684d14916..26085c4040 100644 --- a/src/yuzu/user_data_migration.h +++ b/src/yuzu/user_data_migration.h @@ -20,8 +20,7 @@ public: private: void ShowMigrationPrompt(QMainWindow* main_window); void ShowMigrationCancelledMessage(QMainWindow* main_window); - void MigrateUserData(QMainWindow* main_window, - const Emulator selected_legacy_emu, + void MigrateUserData(QMainWindow* main_window, const Emulator selected_legacy_emu, const bool clear_shader_cache, const MigrationWorker::MigrationStrategy strategy); }; diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index ebd8fd7387..9d1e08c04c 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -40,6 +40,11 @@ target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR}) target_link_libraries(yuzu-cmd PRIVATE SDL2::SDL2 Vulkan::Headers) +# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so +if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") + target_link_libraries(yuzu-cmd PRIVATE X11) +endif() + if(UNIX AND NOT APPLE) install(TARGETS yuzu-cmd) endif() diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 3974e4b357..68a51997e8 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -223,12 +223,10 @@ void EmuWindow_SDL2::WaitEvent() { const u32 current_time = SDL_GetTicks(); if (current_time > last_time + 2000) { const auto results = system.GetAndResetPerfStats(); - const auto title = fmt::format("eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)", - Common::g_build_fullname, - Common::g_scm_branch, - Common::g_scm_desc, - results.average_game_fps, - results.emulation_speed * 100.0); + const auto title = + fmt::format("eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname, + Common::g_scm_branch, Common::g_scm_desc, results.average_game_fps, + results.emulation_speed * 100.0); SDL_SetWindowTitle(render_window, title.c_str()); last_time = current_time; } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index f4980932ed..6557aa4060 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -18,10 +18,8 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) : EmuWindow_SDL2{input_subsystem_, system_} { - const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)", - Common::g_build_name, - Common::g_scm_branch, - Common::g_scm_desc); + const std::string window_title = fmt::format("eden {} | {}-{} (Vulkan)", Common::g_build_name, + Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index c1d714be77..090fc667f3 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -410,9 +410,7 @@ int main(int argc, char** argv) { "While attempting to load the ROM requested, an error occurred. Please " "refer to the eden wiki for more information or the eden discord for " "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", - loader_id, - error_id, - static_cast(error_id)); + loader_id, error_id, static_cast(error_id)); } break; } diff --git a/src/yuzu_room_standalone/main.cpp b/src/yuzu_room_standalone/main.cpp index 3129fb9dd9..5bc3b38bfc 100644 --- a/src/yuzu_room_standalone/main.cpp +++ b/src/yuzu_room_standalone/main.cpp @@ -2,8 +2,7 @@ using namespace std; -int main() -{ +int main() { cout << "Hello World!" << endl; return 0; } diff --git a/src/yuzu_room_standalone/yuzu_room_standalone.cpp b/src/yuzu_room_standalone/yuzu_room_standalone.cpp index 3063a2962b..9baf214b6b 100644 --- a/src/yuzu_room_standalone/yuzu_room_standalone.cpp +++ b/src/yuzu_room_standalone/yuzu_room_standalone.cpp @@ -3,7 +3,6 @@ #include "dedicated_room/yuzu_room.h" -int main(int argc, char* argv[]) -{ +int main(int argc, char* argv[]) { LaunchRoom(argc, argv, false); } diff --git a/tools/clang-format.sh b/tools/clang-format.sh index 77c3c847ad..835e5b3424 100755 --- a/tools/clang-format.sh +++ b/tools/clang-format.sh @@ -1,3 +1,3 @@ #! /bin/sh -exec find src -iname *.h -o -iname *.cpp | xargs clang-format-15 -i -style=file:src/.clang-format +exec find src -iname *.h -o -iname *.cpp | xargs clang-format -i -style=file:src/.clang-format diff --git a/vcpkg.json b/vcpkg.json index 99ed06cf25..a5d288eef3 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -15,10 +15,11 @@ "boost-heap", "boost-icl", "boost-intrusive", + "boost-locale", "boost-mpl", + "boost-process", "boost-range", "boost-spirit", - "boost-process", "boost-test", "boost-timer", "boost-variant", @@ -27,12 +28,23 @@ "nlohmann-json", "zlib", "zstd", - "sdl2" + "sdl2", + { + "name": "dbus", + "default-features": false, + "platform": "linux" + }, + { + "name": "libzip", + "platform": "!android" + } ], "features": { "yuzu-tests": { "description": "Compile tests", - "dependencies": [ "catch2" ] + "dependencies": [ + "catch2" + ] }, "web-service": { "description": "Enable web services (telemetry, etc.)", @@ -52,6 +64,5 @@ "name": "boost-process", "version": "1.81.0" } - ] -} +} \ No newline at end of file