diff options
51 files changed, 370 insertions, 42 deletions
diff --git a/.travis.yml b/.travis.yml index dee34a8e3..4d363cbc9 100644 --- a/.travis.yml +++ b/.travis.yml | |||
| @@ -29,6 +29,19 @@ matrix: | |||
| 29 | script: "./.travis/macos/build.sh" | 29 | script: "./.travis/macos/build.sh" |
| 30 | after_success: "./.travis/macos/upload.sh" | 30 | after_success: "./.travis/macos/upload.sh" |
| 31 | cache: ccache | 31 | cache: ccache |
| 32 | - os: linux | ||
| 33 | env: NAME="MinGW build" | ||
| 34 | sudo: required | ||
| 35 | dist: trusty | ||
| 36 | services: docker | ||
| 37 | addons: | ||
| 38 | apt: | ||
| 39 | packages: | ||
| 40 | - p7zip-full | ||
| 41 | install: "./.travis/linux-mingw/deps.sh" | ||
| 42 | script: "./.travis/linux-mingw/build.sh" | ||
| 43 | after_success: "./.travis/linux-mingw/upload.sh" | ||
| 44 | cache: ccache | ||
| 32 | 45 | ||
| 33 | deploy: | 46 | deploy: |
| 34 | provider: releases | 47 | provider: releases |
diff --git a/.travis/common/post-upload.sh b/.travis/common/post-upload.sh index 90deaaec8..28735a9cf 100755 --- a/.travis/common/post-upload.sh +++ b/.travis/common/post-upload.sh | |||
| @@ -11,6 +11,9 @@ if [ -z $TRAVIS_TAG ]; then | |||
| 11 | RELEASE_NAME=head | 11 | RELEASE_NAME=head |
| 12 | else | 12 | else |
| 13 | RELEASE_NAME=$(echo $TRAVIS_TAG | cut -d- -f1) | 13 | RELEASE_NAME=$(echo $TRAVIS_TAG | cut -d- -f1) |
| 14 | if [ "$NAME" = "MinGW build" ]; then | ||
| 15 | RELEASE_NAME="${RELEASE_NAME}-mingw" | ||
| 16 | fi | ||
| 14 | fi | 17 | fi |
| 15 | 18 | ||
| 16 | mv "$REV_NAME" $RELEASE_NAME | 19 | mv "$REV_NAME" $RELEASE_NAME |
diff --git a/.travis/linux-mingw/build.sh b/.travis/linux-mingw/build.sh new file mode 100755 index 000000000..be03cc0f3 --- /dev/null +++ b/.travis/linux-mingw/build.sh | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | #!/bin/bash -ex | ||
| 2 | mkdir "$HOME/.ccache" || true | ||
| 3 | docker run --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/root/.ccache ubuntu:18.04 /bin/bash -ex /yuzu/.travis/linux-mingw/docker.sh | ||
diff --git a/.travis/linux-mingw/deps.sh b/.travis/linux-mingw/deps.sh new file mode 100755 index 000000000..540bb934a --- /dev/null +++ b/.travis/linux-mingw/deps.sh | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | #!/bin/sh -ex | ||
| 2 | |||
| 3 | docker pull ubuntu:18.04 | ||
diff --git a/.travis/linux-mingw/docker.sh b/.travis/linux-mingw/docker.sh new file mode 100755 index 000000000..d15c3f6e8 --- /dev/null +++ b/.travis/linux-mingw/docker.sh | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | #!/bin/bash -ex | ||
| 2 | |||
| 3 | cd /yuzu | ||
| 4 | MINGW_PACKAGES="sdl2-mingw-w64 qt5base-mingw-w64 qt5tools-mingw-w64 libsamplerate-mingw-w64 qt5multimedia-mingw-w64" | ||
| 5 | apt-get update | ||
| 6 | apt-get install -y gpg wget git python3-pip python ccache g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64-tools cmake | ||
| 7 | echo 'deb http://ppa.launchpad.net/tobydox/mingw-w64/ubuntu bionic main ' > /etc/apt/sources.list.d/extras.list | ||
| 8 | apt-key adv --keyserver keyserver.ubuntu.com --recv '72931B477E22FEFD47F8DECE02FE5F12ADDE29B2' | ||
| 9 | apt-get update | ||
| 10 | apt-get install -y ${MINGW_PACKAGES} | ||
| 11 | |||
| 12 | # fix a problem in current MinGW headers | ||
| 13 | wget -q https://raw.githubusercontent.com/Alexpux/mingw-w64/d0d7f784833bbb0b2d279310ddc6afb52fe47a46/mingw-w64-headers/crt/errno.h -O /usr/x86_64-w64-mingw32/include/errno.h | ||
| 14 | # override Travis CI unreasonable ccache size | ||
| 15 | echo 'max_size = 3.0G' > "$HOME/.ccache/ccache.conf" | ||
| 16 | |||
| 17 | # Dirty hack to trick unicorn makefile into believing we are in a MINGW system | ||
| 18 | mv /bin/uname /bin/uname1 && echo -e '#!/bin/sh\necho MINGW64' >> /bin/uname | ||
| 19 | chmod +x /bin/uname | ||
| 20 | |||
| 21 | # Dirty hack to trick unicorn makefile into believing we have cmd | ||
| 22 | echo '' >> /bin/cmd | ||
| 23 | chmod +x /bin/cmd | ||
| 24 | |||
| 25 | mkdir build && cd build | ||
| 26 | cmake .. -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DYUZU_USE_BUNDLED_UNICORN=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release | ||
| 27 | make -j4 | ||
| 28 | |||
| 29 | # Clean up the dirty hacks | ||
| 30 | rm /bin/uname && mv /bin/uname1 /bin/uname | ||
| 31 | rm /bin/cmd | ||
| 32 | |||
| 33 | ccache -s | ||
| 34 | |||
| 35 | echo "Tests skipped" | ||
| 36 | #ctest -VV -C Release | ||
| 37 | |||
| 38 | echo 'Prepare binaries...' | ||
| 39 | cd .. | ||
| 40 | mkdir package | ||
| 41 | |||
| 42 | QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/' | ||
| 43 | find build/ -name "yuzu*.exe" -exec cp {} 'package' \; | ||
| 44 | |||
| 45 | # copy Qt plugins | ||
| 46 | mkdir package/platforms | ||
| 47 | cp "${QT_PLATFORM_DLL_PATH}/qwindows.dll" package/platforms/ | ||
| 48 | cp -rv "${QT_PLATFORM_DLL_PATH}/../mediaservice/" package/ | ||
| 49 | cp -rv "${QT_PLATFORM_DLL_PATH}/../imageformats/" package/ | ||
| 50 | rm -f package/mediaservice/*d.dll | ||
| 51 | |||
| 52 | for i in package/*.exe; do | ||
| 53 | # we need to process pdb here, however, cv2pdb | ||
| 54 | # does not work here, so we just simply strip all the debug symbols | ||
| 55 | x86_64-w64-mingw32-strip "${i}" | ||
| 56 | done | ||
| 57 | |||
| 58 | pip3 install pefile | ||
| 59 | python3 .travis/linux-mingw/scan_dll.py package/*.exe "package/" | ||
diff --git a/.travis/linux-mingw/scan_dll.py b/.travis/linux-mingw/scan_dll.py new file mode 100644 index 000000000..163183f2e --- /dev/null +++ b/.travis/linux-mingw/scan_dll.py | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | import pefile | ||
| 2 | import sys | ||
| 3 | import re | ||
| 4 | import os | ||
| 5 | import queue | ||
| 6 | import shutil | ||
| 7 | |||
| 8 | # constant definitions | ||
| 9 | KNOWN_SYS_DLLS = ['WINMM.DLL', 'MSVCRT.DLL', 'VERSION.DLL', 'MPR.DLL', | ||
| 10 | 'DWMAPI.DLL', 'UXTHEME.DLL', 'DNSAPI.DLL', 'IPHLPAPI.DLL'] | ||
| 11 | # below is for Ubuntu 18.04 with specified PPA enabled, if you are using | ||
| 12 | # other distro or different repositories, change the following accordingly | ||
| 13 | DLL_PATH = [ | ||
| 14 | '/usr/x86_64-w64-mingw32/bin/', | ||
| 15 | '/usr/x86_64-w64-mingw32/lib/', | ||
| 16 | '/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/' | ||
| 17 | ] | ||
| 18 | |||
| 19 | missing = [] | ||
| 20 | |||
| 21 | |||
| 22 | def parse_imports(file_name): | ||
| 23 | results = [] | ||
| 24 | pe = pefile.PE(file_name, fast_load=True) | ||
| 25 | pe.parse_data_directories() | ||
| 26 | |||
| 27 | for entry in pe.DIRECTORY_ENTRY_IMPORT: | ||
| 28 | current = entry.dll.decode() | ||
| 29 | current_u = current.upper() # b/c Windows is often case insensitive | ||
| 30 | # here we filter out system dlls | ||
| 31 | # dll w/ names like *32.dll are likely to be system dlls | ||
| 32 | if current_u.upper() not in KNOWN_SYS_DLLS and not re.match(string=current_u, pattern=r'.*32\.DLL'): | ||
| 33 | results.append(current) | ||
| 34 | |||
| 35 | return results | ||
| 36 | |||
| 37 | |||
| 38 | def parse_imports_recursive(file_name, path_list=[]): | ||
| 39 | q = queue.Queue() # create a FIFO queue | ||
| 40 | # file_name can be a string or a list for the convience | ||
| 41 | if isinstance(file_name, str): | ||
| 42 | q.put(file_name) | ||
| 43 | elif isinstance(file_name, list): | ||
| 44 | for i in file_name: | ||
| 45 | q.put(i) | ||
| 46 | full_list = [] | ||
| 47 | while q.qsize(): | ||
| 48 | current = q.get_nowait() | ||
| 49 | print('> %s' % current) | ||
| 50 | deps = parse_imports(current) | ||
| 51 | # if this dll does not have any import, ignore it | ||
| 52 | if not deps: | ||
| 53 | continue | ||
| 54 | for dep in deps: | ||
| 55 | # the dependency already included in the list, skip | ||
| 56 | if dep in full_list: | ||
| 57 | continue | ||
| 58 | # find the requested dll in the provided paths | ||
| 59 | full_path = find_dll(dep) | ||
| 60 | if not full_path: | ||
| 61 | missing.append(dep) | ||
| 62 | continue | ||
| 63 | full_list.append(dep) | ||
| 64 | q.put(full_path) | ||
| 65 | path_list.append(full_path) | ||
| 66 | return full_list | ||
| 67 | |||
| 68 | |||
| 69 | def find_dll(name): | ||
| 70 | for path in DLL_PATH: | ||
| 71 | for root, _, files in os.walk(path): | ||
| 72 | for f in files: | ||
| 73 | if name.lower() == f.lower(): | ||
| 74 | return os.path.join(root, f) | ||
| 75 | |||
| 76 | |||
| 77 | def deploy(name, dst, dry_run=False): | ||
| 78 | dlls_path = [] | ||
| 79 | parse_imports_recursive(name, dlls_path) | ||
| 80 | for dll_entry in dlls_path: | ||
| 81 | if not dry_run: | ||
| 82 | shutil.copy(dll_entry, dst) | ||
| 83 | else: | ||
| 84 | print('[Dry-Run] Copy %s to %s' % (dll_entry, dst)) | ||
| 85 | print('Deploy completed.') | ||
| 86 | return dlls_path | ||
| 87 | |||
| 88 | |||
| 89 | def main(): | ||
| 90 | if len(sys.argv) < 3: | ||
| 91 | print('Usage: %s [files to examine ...] [target deploy directory]') | ||
| 92 | return 1 | ||
| 93 | to_deploy = sys.argv[1:-1] | ||
| 94 | tgt_dir = sys.argv[-1] | ||
| 95 | if not os.path.isdir(tgt_dir): | ||
| 96 | print('%s is not a directory.' % tgt_dir) | ||
| 97 | return 1 | ||
| 98 | print('Scanning dependencies...') | ||
| 99 | deploy(to_deploy, tgt_dir) | ||
| 100 | if missing: | ||
| 101 | print('Following DLLs are not found: %s' % ('\n'.join(missing))) | ||
| 102 | return 0 | ||
| 103 | |||
| 104 | |||
| 105 | if __name__ == '__main__': | ||
| 106 | main() | ||
diff --git a/.travis/linux-mingw/upload.sh b/.travis/linux-mingw/upload.sh new file mode 100755 index 000000000..66e896bc4 --- /dev/null +++ b/.travis/linux-mingw/upload.sh | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | #!/bin/bash -ex | ||
| 2 | |||
| 3 | . .travis/common/pre-upload.sh | ||
| 4 | |||
| 5 | REV_NAME="yuzu-windows-mingw-${GITDATE}-${GITREV}" | ||
| 6 | ARCHIVE_NAME="${REV_NAME}.tar.gz" | ||
| 7 | COMPRESSION_FLAGS="-czvf" | ||
| 8 | |||
| 9 | mkdir "$REV_NAME" | ||
| 10 | # get around the permission issues | ||
| 11 | cp -r package/* "$REV_NAME" | ||
| 12 | |||
| 13 | . .travis/common/post-upload.sh | ||
diff --git a/.travis/linux/docker.sh b/.travis/linux/docker.sh index 459d6bc75..892d2480a 100755 --- a/.travis/linux/docker.sh +++ b/.travis/linux/docker.sh | |||
| @@ -6,7 +6,9 @@ apt-get install --no-install-recommends -y build-essential git libqt5opengl5-dev | |||
| 6 | cd /yuzu | 6 | cd /yuzu |
| 7 | 7 | ||
| 8 | mkdir build && cd build | 8 | mkdir build && cd build |
| 9 | cmake .. -DYUZU_BUILD_UNICORN=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -G Ninja | 9 | cmake .. -DYUZU_USE_BUNDLED_UNICORN=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -G Ninja |
| 10 | ninja | 10 | ninja |
| 11 | 11 | ||
| 12 | ccache -s | ||
| 13 | |||
| 12 | ctest -VV -C Release | 14 | ctest -VV -C Release |
diff --git a/.travis/macos/build.sh b/.travis/macos/build.sh index b76a153be..b881fa190 100755 --- a/.travis/macos/build.sh +++ b/.travis/macos/build.sh | |||
| @@ -9,7 +9,9 @@ export PATH="/usr/local/opt/ccache/libexec:$PATH" | |||
| 9 | 9 | ||
| 10 | mkdir build && cd build | 10 | mkdir build && cd build |
| 11 | cmake --version | 11 | cmake --version |
| 12 | cmake .. -DYUZU_BUILD_UNICORN=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON | 12 | cmake .. -DYUZU_USE_BUNDLED_UNICORN=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON |
| 13 | make -j4 | 13 | make -j4 |
| 14 | 14 | ||
| 15 | ccache -s | ||
| 16 | |||
| 15 | ctest -VV -C Release | 17 | ctest -VV -C Release |
diff --git a/CMakeLists.txt b/CMakeLists.txt index 500d099fc..30642edd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -269,10 +269,18 @@ if (YUZU_USE_BUNDLED_UNICORN) | |||
| 269 | 269 | ||
| 270 | find_package(PythonInterp 2.7 REQUIRED) | 270 | find_package(PythonInterp 2.7 REQUIRED) |
| 271 | 271 | ||
| 272 | add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY} | 272 | if (MINGW) |
| 273 | COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh macos-universal-no | 273 | add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY} |
| 274 | WORKING_DIRECTORY ${UNICORN_PREFIX} | 274 | COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh cross-win64 |
| 275 | ) | 275 | WORKING_DIRECTORY ${UNICORN_PREFIX} |
| 276 | ) | ||
| 277 | else() | ||
| 278 | add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY} | ||
| 279 | COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh macos-universal-no | ||
| 280 | WORKING_DIRECTORY ${UNICORN_PREFIX} | ||
| 281 | ) | ||
| 282 | endif() | ||
| 283 | |||
| 276 | # ALL makes this custom target build every time | 284 | # ALL makes this custom target build every time |
| 277 | # but it won't actually build if LIBUNICORN_LIBRARY is up to date | 285 | # but it won't actually build if LIBUNICORN_LIBRARY is up to date |
| 278 | add_custom_target(unicorn-build ALL | 286 | add_custom_target(unicorn-build ALL |
| @@ -286,6 +294,7 @@ endif() | |||
| 286 | 294 | ||
| 287 | if (UNICORN_FOUND) | 295 | if (UNICORN_FOUND) |
| 288 | add_library(unicorn INTERFACE) | 296 | add_library(unicorn INTERFACE) |
| 297 | add_dependencies(unicorn unicorn-build) | ||
| 289 | target_link_libraries(unicorn INTERFACE "${LIBUNICORN_LIBRARY}") | 298 | target_link_libraries(unicorn INTERFACE "${LIBUNICORN_LIBRARY}") |
| 290 | target_include_directories(unicorn INTERFACE "${LIBUNICORN_INCLUDE_DIR}") | 299 | target_include_directories(unicorn INTERFACE "${LIBUNICORN_INCLUDE_DIR}") |
| 291 | else() | 300 | else() |
diff --git a/CMakeModules/MinGWCross.cmake b/CMakeModules/MinGWCross.cmake new file mode 100644 index 000000000..29ecd1ac4 --- /dev/null +++ b/CMakeModules/MinGWCross.cmake | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | set(MINGW_PREFIX /usr/x86_64-w64-mingw32/) | ||
| 2 | set(CMAKE_SYSTEM_NAME Windows) | ||
| 3 | set(CMAKE_SYSTEM_PROCESSOR x86_64) | ||
| 4 | # Actually a hack, w/o this will cause some strange errors | ||
| 5 | set(CMAKE_HOST_WIN32 TRUE) | ||
| 6 | |||
| 7 | |||
| 8 | set(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX}) | ||
| 9 | set(SDL2_PATH ${MINGW_PREFIX}) | ||
| 10 | set(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-) | ||
| 11 | |||
| 12 | # Specify the cross compiler | ||
| 13 | set(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}gcc-posix) | ||
| 14 | set(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}g++-posix) | ||
| 15 | set(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres) | ||
| 16 | |||
| 17 | # Mingw tools | ||
| 18 | set(STRIP ${MINGW_TOOL_PREFIX}strip) | ||
| 19 | set(WINDRES ${MINGW_TOOL_PREFIX}windres) | ||
| 20 | set(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config) | ||
| 21 | |||
| 22 | # ccache wrapper | ||
| 23 | option(USE_CCACHE "Use ccache for compilation" OFF) | ||
| 24 | if(USE_CCACHE) | ||
| 25 | find_program(CCACHE ccache) | ||
| 26 | if(CCACHE) | ||
| 27 | message(STATUS "Using ccache found in PATH") | ||
| 28 | set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE}) | ||
| 29 | set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE}) | ||
| 30 | else(CCACHE) | ||
| 31 | message(WARNING "USE_CCACHE enabled, but no ccache found") | ||
| 32 | endif(CCACHE) | ||
| 33 | endif(USE_CCACHE) | ||
| 34 | |||
| 35 | # Search for programs in the build host directories | ||
| 36 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | ||
| 37 | |||
| 38 | |||
| 39 | # Echo modified cmake vars to screen for debugging purposes | ||
| 40 | if(NOT DEFINED ENV{MINGW_DEBUG_INFO}) | ||
| 41 | message("") | ||
| 42 | message("Custom cmake vars: (blank = system default)") | ||
| 43 | message("-----------------------------------------") | ||
| 44 | message("* CMAKE_C_COMPILER : ${CMAKE_C_COMPILER}") | ||
| 45 | message("* CMAKE_CXX_COMPILER : ${CMAKE_CXX_COMPILER}") | ||
| 46 | message("* CMAKE_RC_COMPILER : ${CMAKE_RC_COMPILER}") | ||
| 47 | message("* WINDRES : ${WINDRES}") | ||
| 48 | message("* ENV{PKG_CONFIG} : $ENV{PKG_CONFIG}") | ||
| 49 | message("* STRIP : ${STRIP}") | ||
| 50 | message("* USE_CCACHE : ${USE_CCACHE}") | ||
| 51 | message("") | ||
| 52 | # So that the debug info only appears once | ||
| 53 | set(ENV{MINGW_DEBUG_INFO} SHOWN) | ||
| 54 | endif() | ||
diff --git a/appveyor.yml b/appveyor.yml index d475816ab..2a003ca5e 100644 --- a/appveyor.yml +++ b/appveyor.yml | |||
| @@ -163,13 +163,3 @@ artifacts: | |||
| 163 | name: build | 163 | name: build |
| 164 | type: zip | 164 | type: zip |
| 165 | 165 | ||
| 166 | deploy: | ||
| 167 | provider: GitHub | ||
| 168 | release: $(appveyor_repo_tag_name) | ||
| 169 | auth_token: | ||
| 170 | secure: QqePPnXbkzmXct5c8hZ2X5AbsthbI6cS1Sr+VBzcD8oUOIjfWJJKXVAQGUbQAbb0 | ||
| 171 | artifact: update,build | ||
| 172 | draft: false | ||
| 173 | prerelease: false | ||
| 174 | on: | ||
| 175 | appveyor_repo_tag: true | ||
diff --git a/src/common/ring_buffer.h b/src/common/ring_buffer.h index 45926c9ec..abe3b4dc2 100644 --- a/src/common/ring_buffer.h +++ b/src/common/ring_buffer.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <atomic> | 9 | #include <atomic> |
| 10 | #include <cstddef> | 10 | #include <cstddef> |
| 11 | #include <cstring> | 11 | #include <cstring> |
| 12 | #include <new> | ||
| 12 | #include <type_traits> | 13 | #include <type_traits> |
| 13 | #include <vector> | 14 | #include <vector> |
| 14 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| @@ -29,7 +30,7 @@ class RingBuffer { | |||
| 29 | static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2 / granularity); | 30 | static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2 / granularity); |
| 30 | static_assert((capacity & (capacity - 1)) == 0, "capacity must be a power of two"); | 31 | static_assert((capacity & (capacity - 1)) == 0, "capacity must be a power of two"); |
| 31 | // Ensure lock-free. | 32 | // Ensure lock-free. |
| 32 | static_assert(std::atomic<std::size_t>::is_always_lock_free); | 33 | static_assert(std::atomic_size_t::is_always_lock_free); |
| 33 | 34 | ||
| 34 | public: | 35 | public: |
| 35 | /// Pushes slots into the ring buffer | 36 | /// Pushes slots into the ring buffer |
| @@ -102,8 +103,15 @@ public: | |||
| 102 | private: | 103 | private: |
| 103 | // It is important to align the below variables for performance reasons: | 104 | // It is important to align the below variables for performance reasons: |
| 104 | // Having them on the same cache-line would result in false-sharing between them. | 105 | // Having them on the same cache-line would result in false-sharing between them. |
| 105 | alignas(128) std::atomic<std::size_t> m_read_index{0}; | 106 | // TODO: Remove this ifdef whenever clang and GCC support |
| 106 | alignas(128) std::atomic<std::size_t> m_write_index{0}; | 107 | // std::hardware_destructive_interference_size. |
| 108 | #if defined(_MSC_VER) && _MSC_VER >= 1911 | ||
| 109 | alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_read_index{0}; | ||
| 110 | alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_write_index{0}; | ||
| 111 | #else | ||
| 112 | alignas(128) std::atomic_size_t m_read_index{0}; | ||
| 113 | alignas(128) std::atomic_size_t m_write_index{0}; | ||
| 114 | #endif | ||
| 107 | 115 | ||
| 108 | std::array<T, granularity * capacity> m_data; | 116 | std::array<T, granularity * capacity> m_data; |
| 109 | }; | 117 | }; |
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 867e34932..16d528994 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -6,7 +6,10 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/hle/kernel/vm_manager.h" | 9 | |
| 10 | namespace Kernel { | ||
| 11 | enum class VMAPermission : u8; | ||
| 12 | } | ||
| 10 | 13 | ||
| 11 | namespace Core { | 14 | namespace Core { |
| 12 | 15 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 32cd5746e..7be5a38de 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "core/gdbstub/gdbstub.h" | 15 | #include "core/gdbstub/gdbstub.h" |
| 16 | #include "core/hle/kernel/process.h" | 16 | #include "core/hle/kernel/process.h" |
| 17 | #include "core/hle/kernel/svc.h" | 17 | #include "core/hle/kernel/svc.h" |
| 18 | #include "core/hle/kernel/vm_manager.h" | ||
| 18 | #include "core/memory.h" | 19 | #include "core/memory.h" |
| 19 | 20 | ||
| 20 | namespace Core { | 21 | namespace Core { |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index e61382d3d..4ee92ee27 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | #include "core/arm/exclusive_monitor.h" | 12 | #include "core/arm/exclusive_monitor.h" |
| 13 | #include "core/arm/unicorn/arm_unicorn.h" | 13 | #include "core/arm/unicorn/arm_unicorn.h" |
| 14 | 14 | ||
| 15 | namespace Memory { | ||
| 16 | struct PageTable; | ||
| 17 | } | ||
| 18 | |||
| 15 | namespace Core { | 19 | namespace Core { |
| 16 | 20 | ||
| 17 | class ARM_Dynarmic_Callbacks; | 21 | class ARM_Dynarmic_Callbacks; |
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 45fc0b574..aa1b3c17d 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -463,6 +463,8 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_, u64 bktr_base_ivfc_off | |||
| 463 | status = Loader::ResultStatus::Success; | 463 | status = Loader::ResultStatus::Success; |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | NCA::~NCA() = default; | ||
| 467 | |||
| 466 | Loader::ResultStatus NCA::GetStatus() const { | 468 | Loader::ResultStatus NCA::GetStatus() const { |
| 467 | return status; | 469 | return status; |
| 468 | } | 470 | } |
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index 00eca52da..f9f66cae9 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h | |||
| @@ -81,6 +81,8 @@ class NCA : public ReadOnlyVfsDirectory { | |||
| 81 | public: | 81 | public: |
| 82 | explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr, | 82 | explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr, |
| 83 | u64 bktr_base_ivfc_offset = 0); | 83 | u64 bktr_base_ivfc_offset = 0); |
| 84 | ~NCA() override; | ||
| 85 | |||
| 84 | Loader::ResultStatus GetStatus() const; | 86 | Loader::ResultStatus GetStatus() const; |
| 85 | 87 | ||
| 86 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; | 88 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; |
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index f11b91399..5b1177a03 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp | |||
| @@ -28,6 +28,8 @@ NACP::NACP(VirtualFile file) : raw(std::make_unique<RawNACP>()) { | |||
| 28 | file->ReadObject(raw.get()); | 28 | file->ReadObject(raw.get()); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | NACP::~NACP() = default; | ||
| 32 | |||
| 31 | const LanguageEntry& NACP::GetLanguageEntry(Language language) const { | 33 | const LanguageEntry& NACP::GetLanguageEntry(Language language) const { |
| 32 | if (language != Language::Default) { | 34 | if (language != Language::Default) { |
| 33 | return raw->language_entries.at(static_cast<u8>(language)); | 35 | return raw->language_entries.at(static_cast<u8>(language)); |
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index 319bae821..43d6f0719 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h | |||
| @@ -73,6 +73,8 @@ extern const std::array<const char*, 15> LANGUAGE_NAMES; | |||
| 73 | class NACP { | 73 | class NACP { |
| 74 | public: | 74 | public: |
| 75 | explicit NACP(VirtualFile file); | 75 | explicit NACP(VirtualFile file); |
| 76 | ~NACP(); | ||
| 77 | |||
| 76 | const LanguageEntry& GetLanguageEntry(Language language = Language::Default) const; | 78 | const LanguageEntry& GetLanguageEntry(Language language = Language::Default) const; |
| 77 | std::string GetApplicationName(Language language = Language::Default) const; | 79 | std::string GetApplicationName(Language language = Language::Default) const; |
| 78 | std::string GetDeveloperName(Language language = Language::Default) const; | 80 | std::string GetDeveloperName(Language language = Language::Default) const; |
diff --git a/src/core/file_sys/nca_metadata.cpp b/src/core/file_sys/nca_metadata.cpp index 479916b69..6f34b7836 100644 --- a/src/core/file_sys/nca_metadata.cpp +++ b/src/core/file_sys/nca_metadata.cpp | |||
| @@ -51,6 +51,8 @@ CNMT::CNMT(CNMTHeader header, OptionalHeader opt_header, std::vector<ContentReco | |||
| 51 | : header(std::move(header)), opt_header(std::move(opt_header)), | 51 | : header(std::move(header)), opt_header(std::move(opt_header)), |
| 52 | content_records(std::move(content_records)), meta_records(std::move(meta_records)) {} | 52 | content_records(std::move(content_records)), meta_records(std::move(meta_records)) {} |
| 53 | 53 | ||
| 54 | CNMT::~CNMT() = default; | ||
| 55 | |||
| 54 | u64 CNMT::GetTitleID() const { | 56 | u64 CNMT::GetTitleID() const { |
| 55 | return header.title_id; | 57 | return header.title_id; |
| 56 | } | 58 | } |
diff --git a/src/core/file_sys/nca_metadata.h b/src/core/file_sys/nca_metadata.h index da5a8dbe8..a05d155f4 100644 --- a/src/core/file_sys/nca_metadata.h +++ b/src/core/file_sys/nca_metadata.h | |||
| @@ -87,6 +87,7 @@ public: | |||
| 87 | explicit CNMT(VirtualFile file); | 87 | explicit CNMT(VirtualFile file); |
| 88 | CNMT(CNMTHeader header, OptionalHeader opt_header, std::vector<ContentRecord> content_records, | 88 | CNMT(CNMTHeader header, OptionalHeader opt_header, std::vector<ContentRecord> content_records, |
| 89 | std::vector<MetaRecord> meta_records); | 89 | std::vector<MetaRecord> meta_records); |
| 90 | ~CNMT(); | ||
| 90 | 91 | ||
| 91 | u64 GetTitleID() const; | 92 | u64 GetTitleID() const; |
| 92 | u32 GetTitleVersion() const; | 93 | u32 GetTitleVersion() const; |
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index f5b3b0175..5791c76ff 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp | |||
| @@ -72,6 +72,8 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) { | |||
| 72 | status = Loader::ResultStatus::Success; | 72 | status = Loader::ResultStatus::Success; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | PartitionFilesystem::~PartitionFilesystem() = default; | ||
| 76 | |||
| 75 | Loader::ResultStatus PartitionFilesystem::GetStatus() const { | 77 | Loader::ResultStatus PartitionFilesystem::GetStatus() const { |
| 76 | return status; | 78 | return status; |
| 77 | } | 79 | } |
diff --git a/src/core/file_sys/partition_filesystem.h b/src/core/file_sys/partition_filesystem.h index e80d2456b..739c63a7f 100644 --- a/src/core/file_sys/partition_filesystem.h +++ b/src/core/file_sys/partition_filesystem.h | |||
| @@ -25,6 +25,8 @@ namespace FileSys { | |||
| 25 | class PartitionFilesystem : public ReadOnlyVfsDirectory { | 25 | class PartitionFilesystem : public ReadOnlyVfsDirectory { |
| 26 | public: | 26 | public: |
| 27 | explicit PartitionFilesystem(std::shared_ptr<VfsFile> file); | 27 | explicit PartitionFilesystem(std::shared_ptr<VfsFile> file); |
| 28 | ~PartitionFilesystem() override; | ||
| 29 | |||
| 28 | Loader::ResultStatus GetStatus() const; | 30 | Loader::ResultStatus GetStatus() const; |
| 29 | 31 | ||
| 30 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; | 32 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; |
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index b37b4c68b..aebc69d52 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -41,6 +41,8 @@ std::string FormatPatchTypeName(PatchType type) { | |||
| 41 | 41 | ||
| 42 | PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} | 42 | PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} |
| 43 | 43 | ||
| 44 | PatchManager::~PatchManager() = default; | ||
| 45 | |||
| 44 | VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { | 46 | VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { |
| 45 | LOG_INFO(Loader, "Patching ExeFS for title_id={:016X}", title_id); | 47 | LOG_INFO(Loader, "Patching ExeFS for title_id={:016X}", title_id); |
| 46 | 48 | ||
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index b521977b2..209cab1dc 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h | |||
| @@ -34,6 +34,7 @@ std::string FormatPatchTypeName(PatchType type); | |||
| 34 | class PatchManager { | 34 | class PatchManager { |
| 35 | public: | 35 | public: |
| 36 | explicit PatchManager(u64 title_id); | 36 | explicit PatchManager(u64 title_id); |
| 37 | ~PatchManager(); | ||
| 37 | 38 | ||
| 38 | // Currently tracked ExeFS patches: | 39 | // Currently tracked ExeFS patches: |
| 39 | // - Game Updates | 40 | // - Game Updates |
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 9d19aaa6d..02319ce0f 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | 12 | ||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | 14 | ||
| 15 | ProgramMetadata::ProgramMetadata() = default; | ||
| 16 | |||
| 17 | ProgramMetadata::~ProgramMetadata() = default; | ||
| 18 | |||
| 15 | Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { | 19 | Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { |
| 16 | std::size_t total_size = static_cast<std::size_t>(file->GetSize()); | 20 | std::size_t total_size = static_cast<std::size_t>(file->GetSize()); |
| 17 | if (total_size < sizeof(Header)) | 21 | if (total_size < sizeof(Header)) |
diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index 3c0a49f16..1143e36c4 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h | |||
| @@ -36,6 +36,9 @@ enum class ProgramFilePermission : u64 { | |||
| 36 | */ | 36 | */ |
| 37 | class ProgramMetadata { | 37 | class ProgramMetadata { |
| 38 | public: | 38 | public: |
| 39 | ProgramMetadata(); | ||
| 40 | ~ProgramMetadata(); | ||
| 41 | |||
| 39 | Loader::ResultStatus Load(VirtualFile file); | 42 | Loader::ResultStatus Load(VirtualFile file); |
| 40 | 43 | ||
| 41 | bool Is64BitProgram() const; | 44 | bool Is64BitProgram() const; |
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index d9d90939e..3d1a3685e 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp | |||
| @@ -28,6 +28,8 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) { | |||
| 28 | ivfc_offset = app_loader.ReadRomFSIVFCOffset(); | 28 | ivfc_offset = app_loader.ReadRomFSIVFCOffset(); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | RomFSFactory::~RomFSFactory() = default; | ||
| 32 | |||
| 31 | ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() { | 33 | ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() { |
| 32 | if (!updatable) | 34 | if (!updatable) |
| 33 | return MakeResult<VirtualFile>(file); | 35 | return MakeResult<VirtualFile>(file); |
diff --git a/src/core/file_sys/romfs_factory.h b/src/core/file_sys/romfs_factory.h index 26b8f46cc..2cace8180 100644 --- a/src/core/file_sys/romfs_factory.h +++ b/src/core/file_sys/romfs_factory.h | |||
| @@ -30,6 +30,7 @@ enum class StorageId : u8 { | |||
| 30 | class RomFSFactory { | 30 | class RomFSFactory { |
| 31 | public: | 31 | public: |
| 32 | explicit RomFSFactory(Loader::AppLoader& app_loader); | 32 | explicit RomFSFactory(Loader::AppLoader& app_loader); |
| 33 | ~RomFSFactory(); | ||
| 33 | 34 | ||
| 34 | ResultVal<VirtualFile> OpenCurrentProcess(); | 35 | ResultVal<VirtualFile> OpenCurrentProcess(); |
| 35 | ResultVal<VirtualFile> Open(u64 title_id, StorageId storage, ContentRecordType type); | 36 | ResultVal<VirtualFile> Open(u64 title_id, StorageId storage, ContentRecordType type); |
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index cddb014fc..9b2c51bbd 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -20,6 +20,8 @@ std::string SaveDataDescriptor::DebugInfo() const { | |||
| 20 | 20 | ||
| 21 | SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) {} | 21 | SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) {} |
| 22 | 22 | ||
| 23 | SaveDataFactory::~SaveDataFactory() = default; | ||
| 24 | |||
| 23 | ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, SaveDataDescriptor meta) { | 25 | ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, SaveDataDescriptor meta) { |
| 24 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { | 26 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { |
| 25 | if (meta.zero_1 != 0) { | 27 | if (meta.zero_1 != 0) { |
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index ba978695b..d69ef6741 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h | |||
| @@ -48,6 +48,7 @@ static_assert(sizeof(SaveDataDescriptor) == 0x40, "SaveDataDescriptor has incorr | |||
| 48 | class SaveDataFactory { | 48 | class SaveDataFactory { |
| 49 | public: | 49 | public: |
| 50 | explicit SaveDataFactory(VirtualDir dir); | 50 | explicit SaveDataFactory(VirtualDir dir); |
| 51 | ~SaveDataFactory(); | ||
| 51 | 52 | ||
| 52 | ResultVal<VirtualDir> Open(SaveDataSpaceId space, SaveDataDescriptor meta); | 53 | ResultVal<VirtualDir> Open(SaveDataSpaceId space, SaveDataDescriptor meta); |
| 53 | 54 | ||
diff --git a/src/core/file_sys/submission_package.h b/src/core/file_sys/submission_package.h index 1120a4920..e85a2b76e 100644 --- a/src/core/file_sys/submission_package.h +++ b/src/core/file_sys/submission_package.h | |||
| @@ -24,7 +24,7 @@ enum class ContentRecordType : u8; | |||
| 24 | class NSP : public ReadOnlyVfsDirectory { | 24 | class NSP : public ReadOnlyVfsDirectory { |
| 25 | public: | 25 | public: |
| 26 | explicit NSP(VirtualFile file); | 26 | explicit NSP(VirtualFile file); |
| 27 | ~NSP(); | 27 | ~NSP() override; |
| 28 | 28 | ||
| 29 | Loader::ResultStatus GetStatus() const; | 29 | Loader::ResultStatus GetStatus() const; |
| 30 | Loader::ResultStatus GetProgramStatus(u64 title_id) const; | 30 | Loader::ResultStatus GetProgramStatus(u64 title_id) const; |
diff --git a/src/core/file_sys/vfs_concat.cpp b/src/core/file_sys/vfs_concat.cpp index 25a980cbb..dc7a279a9 100644 --- a/src/core/file_sys/vfs_concat.cpp +++ b/src/core/file_sys/vfs_concat.cpp | |||
| @@ -27,6 +27,8 @@ ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::s | |||
| 27 | } | 27 | } |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | ConcatenatedVfsFile::~ConcatenatedVfsFile() = default; | ||
| 31 | |||
| 30 | std::string ConcatenatedVfsFile::GetName() const { | 32 | std::string ConcatenatedVfsFile::GetName() const { |
| 31 | if (files.empty()) | 33 | if (files.empty()) |
| 32 | return ""; | 34 | return ""; |
diff --git a/src/core/file_sys/vfs_concat.h b/src/core/file_sys/vfs_concat.h index 31775db7e..717d04bdc 100644 --- a/src/core/file_sys/vfs_concat.h +++ b/src/core/file_sys/vfs_concat.h | |||
| @@ -22,6 +22,8 @@ class ConcatenatedVfsFile : public VfsFile { | |||
| 22 | ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string name); | 22 | ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string name); |
| 23 | 23 | ||
| 24 | public: | 24 | public: |
| 25 | ~ConcatenatedVfsFile() override; | ||
| 26 | |||
| 25 | std::string GetName() const override; | 27 | std::string GetName() const override; |
| 26 | std::size_t GetSize() const override; | 28 | std::size_t GetSize() const override; |
| 27 | bool Resize(std::size_t new_size) override; | 29 | bool Resize(std::size_t new_size) override; |
diff --git a/src/core/file_sys/vfs_offset.cpp b/src/core/file_sys/vfs_offset.cpp index f5ed291ea..a4c6719a0 100644 --- a/src/core/file_sys/vfs_offset.cpp +++ b/src/core/file_sys/vfs_offset.cpp | |||
| @@ -14,6 +14,8 @@ OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, std::size_t size_, | |||
| 14 | : file(file_), offset(offset_), size(size_), name(std::move(name_)), | 14 | : file(file_), offset(offset_), size(size_), name(std::move(name_)), |
| 15 | parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {} | 15 | parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {} |
| 16 | 16 | ||
| 17 | OffsetVfsFile::~OffsetVfsFile() = default; | ||
| 18 | |||
| 17 | std::string OffsetVfsFile::GetName() const { | 19 | std::string OffsetVfsFile::GetName() const { |
| 18 | return name.empty() ? file->GetName() : name; | 20 | return name.empty() ? file->GetName() : name; |
| 19 | } | 21 | } |
diff --git a/src/core/file_sys/vfs_offset.h b/src/core/file_sys/vfs_offset.h index 34cb180b3..8062702a7 100644 --- a/src/core/file_sys/vfs_offset.h +++ b/src/core/file_sys/vfs_offset.h | |||
| @@ -19,6 +19,7 @@ class OffsetVfsFile : public VfsFile { | |||
| 19 | public: | 19 | public: |
| 20 | OffsetVfsFile(std::shared_ptr<VfsFile> file, std::size_t size, std::size_t offset = 0, | 20 | OffsetVfsFile(std::shared_ptr<VfsFile> file, std::size_t size, std::size_t offset = 0, |
| 21 | std::string new_name = "", VirtualDir new_parent = nullptr); | 21 | std::string new_name = "", VirtualDir new_parent = nullptr); |
| 22 | ~OffsetVfsFile() override; | ||
| 22 | 23 | ||
| 23 | std::string GetName() const override; | 24 | std::string GetName() const override; |
| 24 | std::size_t GetSize() const override; | 25 | std::size_t GetSize() const override; |
diff --git a/src/core/file_sys/vfs_vector.cpp b/src/core/file_sys/vfs_vector.cpp index 98e7c4598..ec7f735b5 100644 --- a/src/core/file_sys/vfs_vector.cpp +++ b/src/core/file_sys/vfs_vector.cpp | |||
| @@ -13,6 +13,8 @@ VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_, | |||
| 13 | : files(std::move(files_)), dirs(std::move(dirs_)), parent(std::move(parent_)), | 13 | : files(std::move(files_)), dirs(std::move(dirs_)), parent(std::move(parent_)), |
| 14 | name(std::move(name_)) {} | 14 | name(std::move(name_)) {} |
| 15 | 15 | ||
| 16 | VectorVfsDirectory::~VectorVfsDirectory() = default; | ||
| 17 | |||
| 16 | std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const { | 18 | std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const { |
| 17 | return files; | 19 | return files; |
| 18 | } | 20 | } |
diff --git a/src/core/file_sys/vfs_vector.h b/src/core/file_sys/vfs_vector.h index 179f62e4b..cba44a7a6 100644 --- a/src/core/file_sys/vfs_vector.h +++ b/src/core/file_sys/vfs_vector.h | |||
| @@ -15,6 +15,7 @@ public: | |||
| 15 | explicit VectorVfsDirectory(std::vector<VirtualFile> files = {}, | 15 | explicit VectorVfsDirectory(std::vector<VirtualFile> files = {}, |
| 16 | std::vector<VirtualDir> dirs = {}, std::string name = "", | 16 | std::vector<VirtualDir> dirs = {}, std::string name = "", |
| 17 | VirtualDir parent = nullptr); | 17 | VirtualDir parent = nullptr); |
| 18 | ~VectorVfsDirectory() override; | ||
| 18 | 19 | ||
| 19 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; | 20 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; |
| 20 | std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; | 21 | std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; |
diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp index e937d1403..b2b164368 100644 --- a/src/core/file_sys/xts_archive.cpp +++ b/src/core/file_sys/xts_archive.cpp | |||
| @@ -69,6 +69,8 @@ NAX::NAX(VirtualFile file_, std::array<u8, 0x10> nca_id) | |||
| 69 | Common::HexArrayToString(nca_id, false))); | 69 | Common::HexArrayToString(nca_id, false))); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | NAX::~NAX() = default; | ||
| 73 | |||
| 72 | Loader::ResultStatus NAX::Parse(std::string_view path) { | 74 | Loader::ResultStatus NAX::Parse(std::string_view path) { |
| 73 | if (file->ReadObject(header.get()) != sizeof(NAXHeader)) | 75 | if (file->ReadObject(header.get()) != sizeof(NAXHeader)) |
| 74 | return Loader::ResultStatus::ErrorBadNAXHeader; | 76 | return Loader::ResultStatus::ErrorBadNAXHeader; |
diff --git a/src/core/file_sys/xts_archive.h b/src/core/file_sys/xts_archive.h index 6e2fc4d2e..8fedd8585 100644 --- a/src/core/file_sys/xts_archive.h +++ b/src/core/file_sys/xts_archive.h | |||
| @@ -33,6 +33,7 @@ class NAX : public ReadOnlyVfsDirectory { | |||
| 33 | public: | 33 | public: |
| 34 | explicit NAX(VirtualFile file); | 34 | explicit NAX(VirtualFile file); |
| 35 | explicit NAX(VirtualFile file, std::array<u8, 0x10> nca_id); | 35 | explicit NAX(VirtualFile file, std::array<u8, 0x10> nca_id); |
| 36 | ~NAX() override; | ||
| 36 | 37 | ||
| 37 | Loader::ResultStatus GetStatus() const; | 38 | Loader::ResultStatus GetStatus() const; |
| 38 | 39 | ||
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 51f4544be..81675eac5 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include "core/hle/kernel/object.h" | 16 | #include "core/hle/kernel/object.h" |
| 17 | #include "core/hle/kernel/thread.h" | 17 | #include "core/hle/kernel/thread.h" |
| 18 | #include "core/hle/result.h" | 18 | #include "core/hle/result.h" |
| 19 | #include "core/memory.h" | ||
| 19 | 20 | ||
| 20 | namespace Kernel { | 21 | namespace Kernel { |
| 21 | 22 | ||
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 7a272d031..914bbe0a1 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -125,7 +125,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 125 | vm_manager.LogLayout(); | 125 | vm_manager.LogLayout(); |
| 126 | status = ProcessStatus::Running; | 126 | status = ProcessStatus::Running; |
| 127 | 127 | ||
| 128 | Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, this); | 128 | Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | 131 | void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index d4183d6e3..c2d7535c9 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -311,13 +311,13 @@ void Thread::BoostPriority(u32 priority) { | |||
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, | 313 | SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, |
| 314 | SharedPtr<Process> owner_process) { | 314 | Process& owner_process) { |
| 315 | // Setup page table so we can write to memory | 315 | // Setup page table so we can write to memory |
| 316 | SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table); | 316 | SetCurrentPageTable(&owner_process.vm_manager.page_table); |
| 317 | 317 | ||
| 318 | // Initialize new "main" thread | 318 | // Initialize new "main" thread |
| 319 | auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0, | 319 | auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0, |
| 320 | Memory::STACK_AREA_VADDR_END, std::move(owner_process)); | 320 | Memory::STACK_AREA_VADDR_END, &owner_process); |
| 321 | 321 | ||
| 322 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); | 322 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); |
| 323 | 323 | ||
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index df4748942..91e9b79ec 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -281,7 +281,7 @@ private: | |||
| 281 | * @return A shared pointer to the main thread | 281 | * @return A shared pointer to the main thread |
| 282 | */ | 282 | */ |
| 283 | SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, | 283 | SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, |
| 284 | SharedPtr<Process> owner_process); | 284 | Process& owner_process); |
| 285 | 285 | ||
| 286 | /** | 286 | /** |
| 287 | * Gets the current thread | 287 | * Gets the current thread |
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index b6075f256..10611ed6a 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp | |||
| @@ -31,7 +31,7 @@ public: | |||
| 31 | {1, &IRequest::GetResult, "GetResult"}, | 31 | {1, &IRequest::GetResult, "GetResult"}, |
| 32 | {2, &IRequest::GetSystemEventReadableHandles, "GetSystemEventReadableHandles"}, | 32 | {2, &IRequest::GetSystemEventReadableHandles, "GetSystemEventReadableHandles"}, |
| 33 | {3, &IRequest::Cancel, "Cancel"}, | 33 | {3, &IRequest::Cancel, "Cancel"}, |
| 34 | {4, nullptr, "Submit"}, | 34 | {4, &IRequest::Submit, "Submit"}, |
| 35 | {5, nullptr, "SetRequirement"}, | 35 | {5, nullptr, "SetRequirement"}, |
| 36 | {6, nullptr, "SetRequirementPreset"}, | 36 | {6, nullptr, "SetRequirementPreset"}, |
| 37 | {8, nullptr, "SetPriority"}, | 37 | {8, nullptr, "SetPriority"}, |
| @@ -61,11 +61,17 @@ public: | |||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | private: | 63 | private: |
| 64 | void Submit(Kernel::HLERequestContext& ctx) { | ||
| 65 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | ||
| 66 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 67 | rb.Push(RESULT_SUCCESS); | ||
| 68 | } | ||
| 69 | |||
| 64 | void GetRequestState(Kernel::HLERequestContext& ctx) { | 70 | void GetRequestState(Kernel::HLERequestContext& ctx) { |
| 65 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | 71 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); |
| 66 | IPC::ResponseBuilder rb{ctx, 3}; | 72 | IPC::ResponseBuilder rb{ctx, 3}; |
| 67 | rb.Push(RESULT_SUCCESS); | 73 | rb.Push(RESULT_SUCCESS); |
| 68 | rb.Push<u32>(3); | 74 | rb.Push<u32>(0); |
| 69 | } | 75 | } |
| 70 | 76 | ||
| 71 | void GetResult(Kernel::HLERequestContext& ctx) { | 77 | void GetResult(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 3c6306818..78a4438c4 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -32,11 +32,18 @@ static_assert(sizeof(NsoSegmentHeader) == 0x10, "NsoSegmentHeader has incorrect | |||
| 32 | 32 | ||
| 33 | struct NsoHeader { | 33 | struct NsoHeader { |
| 34 | u32_le magic; | 34 | u32_le magic; |
| 35 | INSERT_PADDING_BYTES(0xc); | 35 | u32_le version; |
| 36 | INSERT_PADDING_WORDS(1); | ||
| 37 | u8 flags; | ||
| 36 | std::array<NsoSegmentHeader, 3> segments; // Text, RoData, Data (in that order) | 38 | std::array<NsoSegmentHeader, 3> segments; // Text, RoData, Data (in that order) |
| 37 | u32_le bss_size; | 39 | u32_le bss_size; |
| 38 | INSERT_PADDING_BYTES(0x1c); | 40 | INSERT_PADDING_BYTES(0x1c); |
| 39 | std::array<u32_le, 3> segments_compressed_size; | 41 | std::array<u32_le, 3> segments_compressed_size; |
| 42 | |||
| 43 | bool IsSegmentCompressed(size_t segment_num) const { | ||
| 44 | ASSERT_MSG(segment_num < 3, "Invalid segment {}", segment_num); | ||
| 45 | return ((flags >> segment_num) & 1); | ||
| 46 | } | ||
| 40 | }; | 47 | }; |
| 41 | static_assert(sizeof(NsoHeader) == 0x6c, "NsoHeader has incorrect size."); | 48 | static_assert(sizeof(NsoHeader) == 0x6c, "NsoHeader has incorrect size."); |
| 42 | static_assert(std::is_trivially_copyable_v<NsoHeader>, "NsoHeader isn't trivially copyable."); | 49 | static_assert(std::is_trivially_copyable_v<NsoHeader>, "NsoHeader isn't trivially copyable."); |
| @@ -105,9 +112,11 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) { | |||
| 105 | Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(kernel, ""); | 112 | Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(kernel, ""); |
| 106 | std::vector<u8> program_image; | 113 | std::vector<u8> program_image; |
| 107 | for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { | 114 | for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { |
| 108 | const std::vector<u8> compressed_data = | 115 | std::vector<u8> data = |
| 109 | file->ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset); | 116 | file->ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset); |
| 110 | std::vector<u8> data = DecompressSegment(compressed_data, nso_header.segments[i]); | 117 | if (nso_header.IsSegmentCompressed(i)) { |
| 118 | data = DecompressSegment(data, nso_header.segments[i]); | ||
| 119 | } | ||
| 111 | program_image.resize(nso_header.segments[i].location); | 120 | program_image.resize(nso_header.segments[i].location); |
| 112 | program_image.insert(program_image.end(), data.begin(), data.end()); | 121 | program_image.insert(program_image.end(), data.begin(), data.end()); |
| 113 | codeset->segments[i].addr = nso_header.segments[i].location; | 122 | codeset->segments[i].addr = nso_header.segments[i].location; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e37acbfac..70fb54507 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -383,7 +383,7 @@ void RasterizerOpenGL::Clear() { | |||
| 383 | bool use_stencil{}; | 383 | bool use_stencil{}; |
| 384 | 384 | ||
| 385 | OpenGLState clear_state; | 385 | OpenGLState clear_state; |
| 386 | clear_state.draw.draw_framebuffer = state.draw.draw_framebuffer; | 386 | clear_state.draw.draw_framebuffer = framebuffer.handle; |
| 387 | clear_state.color_mask.red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE; | 387 | clear_state.color_mask.red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE; |
| 388 | clear_state.color_mask.green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE; | 388 | clear_state.color_mask.green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE; |
| 389 | clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE; | 389 | clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE; |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index f2a7e23f0..a3b1fd357 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "core/hle/kernel/thread.h" | 15 | #include "core/hle/kernel/thread.h" |
| 16 | #include "core/hle/kernel/timer.h" | 16 | #include "core/hle/kernel/timer.h" |
| 17 | #include "core/hle/kernel/wait_object.h" | 17 | #include "core/hle/kernel/wait_object.h" |
| 18 | #include "core/memory.h" | ||
| 18 | 19 | ||
| 19 | WaitTreeItem::WaitTreeItem() = default; | 20 | WaitTreeItem::WaitTreeItem() = default; |
| 20 | WaitTreeItem::~WaitTreeItem() = default; | 21 | WaitTreeItem::~WaitTreeItem() = default; |
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 3b3b551bb..e8b2f720a 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -89,15 +89,7 @@ bool GameList::SearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* e | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | void GameList::SearchField::setFilterResult(int visible, int total) { | 91 | void GameList::SearchField::setFilterResult(int visible, int total) { |
| 92 | QString result_of_text = tr("of"); | 92 | label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); |
| 93 | QString result_text; | ||
| 94 | if (total == 1) { | ||
| 95 | result_text = tr("result"); | ||
| 96 | } else { | ||
| 97 | result_text = tr("results"); | ||
| 98 | } | ||
| 99 | label_filter_result->setText( | ||
| 100 | QString("%1 %2 %3 %4").arg(visible).arg(result_of_text).arg(total).arg(result_text)); | ||
| 101 | } | 93 | } |
| 102 | 94 | ||
| 103 | void GameList::SearchField::clear() { | 95 | void GameList::SearchField::clear() { |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index b1c364fbb..b2559b717 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -20,8 +20,10 @@ | |||
| 20 | #include "common/string_util.h" | 20 | #include "common/string_util.h" |
| 21 | #include "common/telemetry.h" | 21 | #include "common/telemetry.h" |
| 22 | #include "core/core.h" | 22 | #include "core/core.h" |
| 23 | #include "core/crypto/key_manager.h" | ||
| 23 | #include "core/file_sys/vfs_real.h" | 24 | #include "core/file_sys/vfs_real.h" |
| 24 | #include "core/gdbstub/gdbstub.h" | 25 | #include "core/gdbstub/gdbstub.h" |
| 26 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 25 | #include "core/loader/loader.h" | 27 | #include "core/loader/loader.h" |
| 26 | #include "core/settings.h" | 28 | #include "core/settings.h" |
| 27 | #include "core/telemetry_session.h" | 29 | #include "core/telemetry_session.h" |
| @@ -29,7 +31,6 @@ | |||
| 29 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" | 31 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" |
| 30 | 32 | ||
| 31 | #include <getopt.h> | 33 | #include <getopt.h> |
| 32 | #include "core/crypto/key_manager.h" | ||
| 33 | #ifndef _MSC_VER | 34 | #ifndef _MSC_VER |
| 34 | #include <unistd.h> | 35 | #include <unistd.h> |
| 35 | #endif | 36 | #endif |
| @@ -169,6 +170,7 @@ int main(int argc, char** argv) { | |||
| 169 | 170 | ||
| 170 | Core::System& system{Core::System::GetInstance()}; | 171 | Core::System& system{Core::System::GetInstance()}; |
| 171 | system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); | 172 | system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); |
| 173 | Service::FileSystem::CreateFactories(system.GetFilesystem()); | ||
| 172 | 174 | ||
| 173 | SCOPE_EXIT({ system.Shutdown(); }); | 175 | SCOPE_EXIT({ system.Shutdown(); }); |
| 174 | 176 | ||