Compare commits

..

2 Commits

Author SHA1 Message Date
Moonlacer f510f95b71 copyright: Update year and names of many .cpp and .h files 2021-08-10 13:07:49 -05:00
Moonlacer 128bdd127b yuzu-copyright: Update year and names of many .cpp and .h files 2021-08-10 13:00:50 -05:00
420 changed files with 6762 additions and 7992 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dis
fi
# Default clang-format points to default 3.5 version one
CLANG_FORMAT=clang-format-12
CLANG_FORMAT=clang-format-10
$CLANG_FORMAT --version
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
-4
View File
@@ -1,8 +1,6 @@
jobs:
- job: merge
displayName: 'pull requests'
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
submodules: recursive
@@ -26,8 +24,6 @@ jobs:
- job: upload_source
displayName: 'upload'
dependsOn: merge
pool:
vmImage: 'ubuntu-latest'
steps:
- template: ./sync-source.yml
parameters:
-4
View File
@@ -1,8 +1,6 @@
jobs:
- job: merge
displayName: 'pull requests'
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
submodules: recursive
@@ -25,8 +23,6 @@ jobs:
- job: upload_source
displayName: 'upload'
dependsOn: merge
pool:
vmImage: 'ubuntu-latest'
steps:
- template: ./sync-source.yml
parameters:
-3
View File
@@ -1,9 +1,6 @@
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: merge
displayName: 'merge'
-2
View File
@@ -66,7 +66,5 @@ stages:
jobs:
- job: github
displayName: 'github'
pool:
vmImage: ubuntu-latest
steps:
- template: ./templates/release-github.yml
-3
View File
@@ -1,9 +1,6 @@
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: merge
displayName: 'merge'
-2
View File
@@ -29,7 +29,5 @@ stages:
jobs:
- job: release
displayName: 'source'
pool:
vmImage: 'ubuntu-latest'
steps:
- template: ./templates/release-private-tag.yml
+3
View File
@@ -28,6 +28,9 @@
[submodule "mbedtls"]
path = externals/mbedtls
url = https://github.com/yuzu-emu/mbedtls
[submodule "libzip"]
path = externals/libzip/libzip
url = https://github.com/nih-at/libzip.git
[submodule "xbyak"]
path = externals/xbyak
url = https://github.com/herumi/xbyak.git
+59
View File
@@ -0,0 +1,59 @@
language: cpp
matrix:
include:
- os: linux
env: NAME="clang-format"
sudo: required
dist: trusty
services: docker
install: "./.travis/clang-format/deps.sh"
script: "./.travis/clang-format/build.sh"
- os: linux
env: NAME="linux build"
sudo: required
dist: trusty
services: docker
addons:
apt:
packages:
- p7zip-full
install: "./.travis/linux/deps.sh"
script: "./.travis/linux/build.sh"
after_success: "./.travis/linux/upload.sh"
cache: ccache
- os: osx
env: NAME="macos build"
sudo: false
osx_image: xcode10.2
install: "./.travis/macos/deps.sh"
script: "./.travis/macos/build.sh"
after_success: "./.travis/macos/upload.sh"
cache: ccache
- os: linux
env: NAME="MinGW build"
sudo: required
dist: trusty
services: docker
addons:
apt:
packages:
- p7zip-full
install: "./.travis/linux-mingw/deps.sh"
script: "./.travis/linux-mingw/build.sh"
after_success: "./.travis/linux-mingw/upload.sh"
cache: ccache
deploy:
provider: releases
api_key:
secure: ElsIAlbvVXBNKsP31nVPysh+mf0GQA4DiL/y5iJeQxKQYR6iRoNo+RfzOBmdswdo0bE/PGeBAlfzCkp15gjhWf6Je0N6dRpczmcmLq6SSQFn1Mpq00xMJB2AgQIlaHs6KFgoUA173EBKbPwgU/NubTFpJFm/Wa+NcSWAHQXKL9KT2M3qKpxNkPl3mKEVsbch4REP+T/46vsa+ikw0VE0kIs6V93LqUQZpI2F0Dhihx8Cxr5iedkE1QsNK+QSX9iItMHbfek9OH980gP7L3lkZltyAA1Pk0c37OAgz2PwczwNKwCT8jg9PMzdcKmWouvLyAkZFuA806ElzwHY3oEd91Zm6+Bk5n24yBKZ9027AZzw38NK2Z2m9Akb8+ar8PdsKU6N5pDutX9qSLayr0oMgJ0s7/xnGBGdL3gfkPCFc50xO/2DxlsOR+zAhPNM9Y76hhGy6A7/40+9uzrJvd4nAuDvIXRzi2Yl2L7mKBE4suMKbFLtk2LlgM0qY5JMVTQ8NliaEtqopfPur2KWFVJUpWDNLtNX8xGqhfwg7cLjIiGmnxSaJBTDuZI6dpEjkWkU0n1xYhGqEqit8DbehYzazozMJ+Vsr8hku7jGlUtlw+U6HG1e19O2y4aGeSwYPROcCNz+BLwmVM8oZE3Roy3qoaa2yiFf+sy6rUHznrhsfEM=
file_glob: true
file: "artifacts/*"
skip_cleanup: true
on:
tags: true
notifications:
webhooks:
urls:
- https://api.yuzu-emu.org/code/travis/notify
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash -ex
docker run --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-clang-format /bin/bash -ex /yuzu/.travis/clang-format/docker.sh
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh -ex
docker pull citraemu/build-environments:linux-clang-format
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash -ex
# Run clang-format
cd /yuzu
./.travis/clang-format/script.sh
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash -ex
if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .travis* dist/*.desktop \
dist/*.svg dist/*.xml; then
echo Trailing whitespace found, aborting
exit 1
fi
# Default clang-format points to default 3.5 version one
CLANG_FORMAT=clang-format-10.0
$CLANG_FORMAT --version
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
# Get list of every file modified in this pull request
files_to_lint="$(git diff --name-only --diff-filter=ACMRTUXB $TRAVIS_COMMIT_RANGE | grep '^src/[^.]*[.]\(cpp\|h\)$' || true)"
else
# Check everything for branch pushes
files_to_lint="$(find src/ -name '*.cpp' -or -name '*.h')"
fi
# Turn off tracing for this because it's too verbose
set +x
for f in $files_to_lint; do
d=$(diff -u "$f" <($CLANG_FORMAT "$f") || true)
if ! [ -z "$d" ]; then
echo "!!! $f not compliant to coding style, here is the fix:"
echo "$d"
fail=1
fi
done
set -x
if [ "$fail" = 1 ]; then
exit 1
fi
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash -ex
# Copy documentation
cp license.txt "$REV_NAME"
cp README.md "$REV_NAME"
tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$REV_NAME"
# Find out what release we are building
if [ -z $TRAVIS_TAG ]; then
RELEASE_NAME=head
else
RELEASE_NAME=$(echo $TRAVIS_TAG | cut -d- -f1)
if [ "$NAME" = "MinGW build" ]; then
RELEASE_NAME="${RELEASE_NAME}-mingw"
fi
fi
mv "$REV_NAME" $RELEASE_NAME
7z a "$REV_NAME.7z" $RELEASE_NAME
# move the compiled archive into the artifacts directory to be uploaded by travis releases
mv "$ARCHIVE_NAME" artifacts/
mv "$REV_NAME.7z" artifacts/
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash -ex
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
GITREV="`git show -s --format='%h'`"
mkdir -p artifacts
+18
View File
@@ -0,0 +1,18 @@
# List of environment variables to be shared with Docker containers
CI
TRAVIS
CONTINUOUS_INTEGRATION
TRAVIS_BRANCH
TRAVIS_BUILD_ID
TRAVIS_BUILD_NUMBER
TRAVIS_COMMIT
TRAVIS_COMMIT_RANGE
TRAVIS_EVENT_TYPE
TRAVIS_JOB_ID
TRAVIS_JOB_NUMBER
TRAVIS_REPO_SLUG
TRAVIS_TAG
# yuzu specific flags
ENABLE_COMPATIBILITY_REPORTING
USE_DISCORD_PRESENCE
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash -ex
mkdir "$HOME/.ccache" || true
docker run --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/root/.ccache yuzuemu/build-environments:linux-mingw /bin/bash -ex /yuzu/.travis/linux-mingw/docker.sh
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh -ex
docker pull yuzuemu/build-environments:linux-mingw
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash -ex
cd /yuzu
# override Travis CI unreasonable ccache size
echo 'max_size = 3.0G' > "$HOME/.ccache/ccache.conf"
mkdir build && cd build
cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release
ninja
# Clean up the dirty hacks
rm /bin/uname && mv /bin/uname1 /bin/uname
rm /bin/cmd
ccache -s
echo "Tests skipped"
#ctest -VV -C Release
echo 'Prepare binaries...'
cd ..
mkdir package
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/'
find build/ -name "yuzu*.exe" -exec cp {} 'package' \;
# copy Qt plugins
mkdir package/platforms
cp "${QT_PLATFORM_DLL_PATH}/qwindows.dll" package/platforms/
cp -rv "${QT_PLATFORM_DLL_PATH}/../mediaservice/" package/
cp -rv "${QT_PLATFORM_DLL_PATH}/../imageformats/" package/
rm -f package/mediaservice/*d.dll
for i in package/*.exe; do
# we need to process pdb here, however, cv2pdb
# does not work here, so we just simply strip all the debug symbols
x86_64-w64-mingw32-strip "${i}"
done
pip3 install pefile
python3 .travis/linux-mingw/scan_dll.py package/*.exe "package/"
python3 .travis/linux-mingw/scan_dll.py package/imageformats/*.dll "package/"
+106
View File
@@ -0,0 +1,106 @@
import pefile
import sys
import re
import os
import queue
import shutil
# constant definitions
KNOWN_SYS_DLLS = ['WINMM.DLL', 'MSVCRT.DLL', 'VERSION.DLL', 'MPR.DLL',
'DWMAPI.DLL', 'UXTHEME.DLL', 'DNSAPI.DLL', 'IPHLPAPI.DLL']
# below is for Ubuntu 18.04 with specified PPA enabled, if you are using
# other distro or different repositories, change the following accordingly
DLL_PATH = [
'/usr/x86_64-w64-mingw32/bin/',
'/usr/x86_64-w64-mingw32/lib/',
'/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/'
]
missing = []
def parse_imports(file_name):
results = []
pe = pefile.PE(file_name, fast_load=True)
pe.parse_data_directories()
for entry in pe.DIRECTORY_ENTRY_IMPORT:
current = entry.dll.decode()
current_u = current.upper() # b/c Windows is often case insensitive
# here we filter out system dlls
# dll w/ names like *32.dll are likely to be system dlls
if current_u.upper() not in KNOWN_SYS_DLLS and not re.match(string=current_u, pattern=r'.*32\.DLL'):
results.append(current)
return results
def parse_imports_recursive(file_name, path_list=[]):
q = queue.Queue() # create a FIFO queue
# file_name can be a string or a list for the convience
if isinstance(file_name, str):
q.put(file_name)
elif isinstance(file_name, list):
for i in file_name:
q.put(i)
full_list = []
while q.qsize():
current = q.get_nowait()
print('> %s' % current)
deps = parse_imports(current)
# if this dll does not have any import, ignore it
if not deps:
continue
for dep in deps:
# the dependency already included in the list, skip
if dep in full_list:
continue
# find the requested dll in the provided paths
full_path = find_dll(dep)
if not full_path:
missing.append(dep)
continue
full_list.append(dep)
q.put(full_path)
path_list.append(full_path)
return full_list
def find_dll(name):
for path in DLL_PATH:
for root, _, files in os.walk(path):
for f in files:
if name.lower() == f.lower():
return os.path.join(root, f)
def deploy(name, dst, dry_run=False):
dlls_path = []
parse_imports_recursive(name, dlls_path)
for dll_entry in dlls_path:
if not dry_run:
shutil.copy(dll_entry, dst)
else:
print('[Dry-Run] Copy %s to %s' % (dll_entry, dst))
print('Deploy completed.')
return dlls_path
def main():
if len(sys.argv) < 3:
print('Usage: %s [files to examine ...] [target deploy directory]')
return 1
to_deploy = sys.argv[1:-1]
tgt_dir = sys.argv[-1]
if not os.path.isdir(tgt_dir):
print('%s is not a directory.' % tgt_dir)
return 1
print('Scanning dependencies...')
deploy(to_deploy, tgt_dir)
if missing:
print('Following DLLs are not found: %s' % ('\n'.join(missing)))
return 0
if __name__ == '__main__':
main()
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash -ex
. .travis/common/pre-upload.sh
REV_NAME="yuzu-windows-mingw-${GITDATE}-${GITREV}"
ARCHIVE_NAME="${REV_NAME}.tar.gz"
COMPRESSION_FLAGS="-czvf"
mkdir "$REV_NAME"
# get around the permission issues
cp -r package/* "$REV_NAME"
. .travis/common/post-upload.sh
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash -ex
mkdir -p "$HOME/.ccache"
docker run -e ENABLE_COMPATIBILITY_REPORTING --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/home/yuzu/.ccache yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.travis/linux/docker.sh
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh -ex
docker pull yuzuemu/build-environments:linux-fresh
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash -ex
cd /yuzu
mkdir build && cd build
cmake .. -G Ninja -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON
ninja
ccache -s
ctest -VV -C Release
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash -ex
. .travis/common/pre-upload.sh
REV_NAME="yuzu-linux-${GITDATE}-${GITREV}"
ARCHIVE_NAME="${REV_NAME}.tar.xz"
COMPRESSION_FLAGS="-cJvf"
mkdir "$REV_NAME"
cp build/bin/yuzu-cmd "$REV_NAME"
cp build/bin/yuzu "$REV_NAME"
. .travis/common/post-upload.sh
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash -ex
set -o pipefail
export MACOSX_DEPLOYMENT_TARGET=10.14
export Qt5_DIR=$(brew --prefix)/opt/qt5
export PATH="/usr/local/opt/ccache/libexec:$PATH"
# TODO: Build using ninja instead of make
mkdir build && cd build
cmake --version
cmake .. -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DUSE_DISCORD_PRESENCE=ON
make -j4
ccache -s
ctest -VV -C Release
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh -ex
brew update
brew install p7zip qt5 sdl2 ccache
brew outdated cmake || brew upgrade cmake
pip3 install macpack
+28
View File
@@ -0,0 +1,28 @@
#!/bin/bash -ex
. .travis/common/pre-upload.sh
REV_NAME="yuzu-osx-${GITDATE}-${GITREV}"
ARCHIVE_NAME="${REV_NAME}.tar.gz"
COMPRESSION_FLAGS="-czvf"
mkdir "$REV_NAME"
cp build/bin/yuzu-cmd "$REV_NAME"
cp -r build/bin/yuzu.app "$REV_NAME"
# move libs into folder for deployment
macpack "${REV_NAME}/yuzu.app/Contents/MacOS/yuzu" -d "../Frameworks"
# move qt frameworks into app bundle for deployment
$(brew --prefix)/opt/qt5/bin/macdeployqt "${REV_NAME}/yuzu.app" -executable="${REV_NAME}/yuzu.app/Contents/MacOS/yuzu"
# move libs into folder for deployment
macpack "${REV_NAME}/yuzu-cmd" -d "libs"
# Make the launching script executable
chmod +x ${REV_NAME}/yuzu.app/Contents/MacOS/yuzu
# Verify loader instructions
find "$REV_NAME" -exec otool -L {} \;
. .travis/common/post-upload.sh
+33 -88
View File
@@ -29,10 +29,16 @@ option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}")
option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
option(YUZU_ENABLE_BOXCAT "Enable the Boxcat service, a yuzu high-level implementation of BCAT" ON)
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
if (NOT ENABLE_WEB_SERVICE)
set(YUZU_ENABLE_BOXCAT OFF)
endif()
# Default to a Release build
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
@@ -129,7 +135,7 @@ endif()
# boost asio's concept usage doesn't play nicely with some compilers yet.
add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS)
if (MSVC)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:/std:c++latest>)
add_compile_options(/std:c++latest)
# cubeb and boost still make use of deprecated result_of.
add_definitions(-D_HAS_DEPRECATED_RESULT_OF)
@@ -237,7 +243,7 @@ yuzu_find_packages()
# Qt5 requires that we find components, so it doesn't fit our pretty little find package function
if(ENABLE_QT)
set(QT_VERSION 5.15)
set(QT_VERSION 5.12)
# We want to load the generated conan qt config so that we get the QT_ROOT var so that we can use the official
# Qt5Config inside the root folder instead of the conan generated one.
if(EXISTS ${CMAKE_BINARY_DIR}/qtConfig.cmake)
@@ -339,8 +345,8 @@ if(ENABLE_QT)
set(QT_PREFIX_HINT)
if(YUZU_USE_BUNDLED_QT)
if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64)
set(QT_BUILD qt-5.15.2-msvc2019_64)
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
set(QT_BUILD qt-5.12.8-msvc2017_64)
elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND NOT MINGW AND ARCHITECTURE_x86_64)
set(QT_BUILD qt5_5_15_2)
else()
@@ -369,8 +375,8 @@ endif()
if (ENABLE_SDL2)
if (YUZU_USE_BUNDLED_SDL2)
# Detect toolchain and platform
if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64)
set(SDL2_VER "SDL2-2.0.16")
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
set(SDL2_VER "SDL2-2.0.15-prerelease")
else()
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
endif()
@@ -390,7 +396,7 @@ if (ENABLE_SDL2)
elseif (YUZU_USE_EXTERNAL_SDL2)
message(STATUS "Using SDL2 from externals.")
else()
find_package(SDL2 2.0.16 REQUIRED)
find_package(SDL2 2.0.15 REQUIRED)
# Some installations don't set SDL2_LIBRARIES
if("${SDL2_LIBRARIES}" STREQUAL "")
@@ -416,6 +422,11 @@ if (CONAN_REQUIRED_LIBS)
endif()
include(${CMAKE_BINARY_DIR}/conan.cmake)
set(CONAN_LIB_OPTIONS
libzip:with_openssl=False
libzip:enable_windows_crypto=False
)
conan_check(VERSION 1.24.0 REQUIRED)
# Manually add iconv to fix a dep conflict between qt and sdl2
@@ -462,7 +473,7 @@ if (CONAN_REQUIRED_LIBS)
if(ENABLE_QT)
list(APPEND CMAKE_MODULE_PATH "${CONAN_QT_ROOT_RELEASE}")
list(APPEND CMAKE_PREFIX_PATH "${CONAN_QT_ROOT_RELEASE}")
find_package(Qt5 5.15 REQUIRED COMPONENTS Widgets)
find_package(Qt5 5.12 REQUIRED COMPONENTS Widgets)
if (YUZU_USE_QT_WEB_ENGINE)
find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets)
endif()
@@ -507,10 +518,6 @@ set(FFmpeg_COMPONENTS
avutil
swscale)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
Include(FindPkgConfig REQUIRED)
pkg_check_modules(LIBVA libva)
endif()
if (NOT YUZU_USE_BUNDLED_FFMPEG)
# Use system installed FFmpeg
find_package(FFmpeg QUIET COMPONENTS ${FFmpeg_COMPONENTS})
@@ -533,9 +540,6 @@ endif()
if (YUZU_USE_BUNDLED_FFMPEG)
if (NOT WIN32)
# TODO(lat9nq): Move this to externals/ffmpeg/CMakeLists.txt (and move externals/ffmpeg to
# externals/ffmpeg/ffmpeg)
# Build FFmpeg from externals
message(STATUS "Using FFmpeg from externals")
@@ -575,23 +579,20 @@ if (YUZU_USE_BUNDLED_FFMPEG)
CACHE PATH "Paths to FFmpeg libraries" FORCE)
endforeach()
Include(FindPkgConfig REQUIRED)
pkg_check_modules(LIBVA libva)
pkg_check_modules(CUDA cuda)
pkg_check_modules(FFNVCODEC ffnvcodec)
pkg_check_modules(VDPAU vdpau)
set(FFmpeg_HWACCEL_LIBRARIES)
set(FFmpeg_HWACCEL_FLAGS)
set(FFmpeg_HWACCEL_INCLUDE_DIRS)
set(FFmpeg_HWACCEL_LDFLAGS)
set(FFmpeg_INCLUDE_DIR
"${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR}"
CACHE PATH "Path to FFmpeg headers" FORCE)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
Include(FindPkgConfig REQUIRED)
pkg_check_modules(LIBVA libva)
endif()
if(LIBVA_FOUND)
pkg_check_modules(LIBDRM libdrm REQUIRED)
find_package(X11 REQUIRED)
pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
set(FFmpeg_LIBVA_LIBRARIES
${LIBDRM_LIBRARIES}
${X11_LIBRARIES}
${LIBVA-DRM_LIBRARIES}
@@ -601,56 +602,11 @@ if (YUZU_USE_BUNDLED_FFMPEG)
--enable-hwaccel=h264_vaapi
--enable-hwaccel=vp9_vaapi
--enable-libdrm)
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${LIBDRM_INCLUDE_DIRS}
${X11_INCLUDE_DIRS}
${LIBVA-DRM_INCLUDE_DIRS}
${LIBVA-X11_INCLUDE_DIRS}
${LIBVA_INCLUDE_DIRS}
)
message(STATUS "VA-API found")
else()
set(FFmpeg_HWACCEL_FLAGS --disable-vaapi)
endif()
if (FFNVCODEC_FOUND AND CUDA_FOUND)
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-cuvid
--enable-ffnvcodec
--enable-nvdec
--enable-hwaccel=h264_nvdec
--enable-hwaccel=vp9_nvdec
--extra-cflags=-I${CUDA_INCLUDE_DIRS}
)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${FFNVCODEC_LIBRARIES}
${CUDA_LIBRARIES}
)
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${FFNVCODEC_INCLUDE_DIRS}
${CUDA_INCLUDE_DIRS}
)
list(APPEND FFmpeg_HWACCEL_LDFLAGS
${FFNVCODEC_LDFLAGS}
${CUDA_LDFLAGS}
)
message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
endif()
if (VDPAU_FOUND)
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-vdpau
--enable-hwaccel=h264_vdpau
--enable-hwaccel=vp9_vdpau
)
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS})
message(STATUS "vdpau libraries version ${VDPAU_VERSION} found")
else()
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
endif()
# `configure` parameters builds only exactly what yuzu needs from FFmpeg
# `--disable-vdpau` is needed to avoid linking issues
add_custom_command(
@@ -668,6 +624,7 @@ if (YUZU_USE_BUNDLED_FFMPEG)
--disable-network
--disable-postproc
--disable-swresample
--disable-vdpau
--enable-decoder=h264
--enable-decoder=vp9
--cc="${CMAKE_C_COMPILER}"
@@ -696,26 +653,15 @@ if (YUZU_USE_BUNDLED_FFMPEG)
${FFmpeg_BUILD_DIR}
)
set(FFmpeg_INCLUDE_DIR
"${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR};${FFmpeg_HWACCEL_INCLUDE_DIRS}"
CACHE PATH "Path to FFmpeg headers" FORCE)
set(FFmpeg_LDFLAGS
"${FFmpeg_HWACCEL_LDFLAGS}"
CACHE STRING "FFmpeg linker flags" FORCE)
# ALL makes this custom target build every time
# but it won't actually build if the DEPENDS parameter is up to date
add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE})
add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_BUILD_LIBRARIES} ffmpeg-configure)
link_libraries(${FFmpeg_LIBVA_LIBRARIES})
set(FFmpeg_LIBRARIES ${FFmpeg_BUILD_LIBRARIES} ${FFmpeg_HWACCEL_LIBRARIES}
set(FFmpeg_LIBRARIES ${FFmpeg_LIBVA_LIBRARIES} ${FFmpeg_BUILD_LIBRARIES}
CACHE PATH "Paths to FFmpeg libraries" FORCE)
unset(FFmpeg_BUILD_LIBRARIES)
unset(FFmpeg_HWACCEL_FLAGS)
unset(FFmpeg_HWACCEL_INCLUDE_DIRS)
unset(FFmpeg_HWACCEL_LDFLAGS)
unset(FFmpeg_HWACCEL_LIBRARIES)
unset(FFmpeg_LIBVA_LIBRARIES)
if (FFmpeg_FOUND)
message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}")
@@ -724,13 +670,12 @@ if (YUZU_USE_BUNDLED_FFMPEG)
endif()
else() # WIN32
# Use yuzu FFmpeg binaries
set(FFmpeg_EXT_NAME "ffmpeg-4.4")
set(FFmpeg_EXT_NAME "ffmpeg-4.3.1")
set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
set(FFmpeg_FOUND YES)
set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE)
set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE)
set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE)
set(FFmpeg_DLL_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE)
set(FFmpeg_LIBRARIES
${FFmpeg_LIBRARY_DIR}/swscale.lib
@@ -756,7 +701,7 @@ if (APPLE)
elseif (WIN32)
# WSAPoll and SHGetKnownFolderPath (AppData/Roaming) didn't exist before WinNT 6.x (Vista)
add_definitions(-D_WIN32_WINNT=0x0600 -DWINVER=0x0600)
set(PLATFORM_LIBRARIES winmm ws2_32 iphlpapi)
set(PLATFORM_LIBRARIES winmm ws2_32)
if (MINGW)
# PSAPI is the Process Status API
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version)
@@ -769,7 +714,7 @@ endif()
# against all the src files. This should be used before making a pull request.
# =======================================================================
set(CLANG_FORMAT_POSTFIX "-12")
set(CLANG_FORMAT_POSTFIX "-10")
find_program(CLANG_FORMAT
NAMES clang-format${CLANG_FORMAT_POSTFIX}
clang-format
-1
View File
@@ -33,7 +33,6 @@ function(copy_yuzu_Qt5_deps target_dir)
Qt5Positioning$<$<CONFIG:Debug>:d>.*
Qt5PrintSupport$<$<CONFIG:Debug>:d>.*
Qt5Qml$<$<CONFIG:Debug>:d>.*
Qt5QmlModels$<$<CONFIG:Debug>:d>.*
Qt5Quick$<$<CONFIG:Debug>:d>.*
Qt5QuickWidgets$<$<CONFIG:Debug>:d>.*
Qt5WebChannel$<$<CONFIG:Debug>:d>.*
+8 -4
View File
@@ -7,9 +7,7 @@ include(DownloadExternals)
# xbyak
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
add_library(xbyak INTERFACE)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/xbyak/xbyak DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_include_directories(xbyak SYSTEM INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_include_directories(xbyak SYSTEM INTERFACE ./xbyak/xbyak)
target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
endif()
@@ -21,7 +19,6 @@ target_include_directories(catch-single-include INTERFACE catch/single_include)
if (ARCHITECTURE_x86_64)
set(DYNARMIC_TESTS OFF)
set(DYNARMIC_NO_BUNDLED_FMT ON)
set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE)
add_subdirectory(dynarmic)
endif()
@@ -93,6 +90,13 @@ endif()
# Sirit
add_subdirectory(sirit)
# libzip
find_package(libzip 1.5)
if (NOT libzip_FOUND)
message(STATUS "libzip 1.5 or newer not found, falling back to externals")
add_subdirectory(libzip EXCLUDE_FROM_ALL)
endif()
if (ENABLE_WEB_SERVICE)
find_package(OpenSSL 1.1)
if (OPENSSL_FOUND)
+1 -1
+72
View File
@@ -0,0 +1,72 @@
find_package(PkgConfig QUIET)
pkg_check_modules(PC_libzip QUIET libzip)
find_path(libzip_INCLUDE_DIR
NAMES zip.h
PATHS ${PC_libzip_INCLUDE_DIRS}
"$ENV{LIB_DIR}/include"
"$ENV{INCLUDE}"
/usr/local/include
/usr/include
)
find_path(libzip_INCLUDE_DIR_ZIPCONF
NAMES zipconf.h
HINTS ${PC_libzip_INCLUDE_DIRS}
"$ENV{LIB_DIR}/include"
"$ENV{LIB_DIR}/lib/libzip/include"
"$ENV{LIB}/lib/libzip/include"
/usr/local/lib/libzip/include
/usr/lib/libzip/include
/usr/local/include
/usr/include
"$ENV{INCLUDE}"
)
find_library(libzip_LIBRARY
NAMES zip
PATHS ${PC_libzip_LIBRARY_DIRS}
"$ENV{LIB_DIR}/lib" "$ENV{LIB}" /usr/local/lib /usr/lib
)
if (libzip_INCLUDE_DIR_ZIPCONF)
FILE(READ "${libzip_INCLUDE_DIR_ZIPCONF}/zipconf.h" _libzip_VERSION_CONTENTS)
if (_libzip_VERSION_CONTENTS)
STRING(REGEX REPLACE ".*#define LIBZIP_VERSION \"([0-9.]+)\".*" "\\1" libzip_VERSION "${_libzip_VERSION_CONTENTS}")
endif()
unset(_libzip_VERSION_CONTENTS)
endif()
set(libzip_VERSION ${libzip_VERSION} CACHE STRING "Version number of libzip")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(libzip
FOUND_VAR libzip_FOUND
REQUIRED_VARS
libzip_LIBRARY
libzip_INCLUDE_DIR
libzip_INCLUDE_DIR_ZIPCONF
libzip_VERSION
VERSION_VAR libzip_VERSION
)
if(libzip_FOUND)
set(libzip_LIBRARIES ${libzip_LIBRARY})
set(libzip_INCLUDE_DIRS ${libzip_INCLUDE_DIR})
set(libzip_DEFINITIONS ${PC_libzip_CFLAGS_OTHER})
endif()
if(libzip_FOUND AND NOT TARGET libzip::libzip)
add_library(libzip::libzip UNKNOWN IMPORTED)
set_target_properties(libzip::libzip PROPERTIES
IMPORTED_LOCATION "${libzip_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PC_libzip_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${libzip_INCLUDE_DIR}"
)
endif()
mark_as_advanced(
libzip_INCLUDE_DIR
libzip_INCLUDE_DIR_ZIPCONF
libzip_LIBRARY
libzip_VERSION
)
+564
View File
@@ -0,0 +1,564 @@
# TODO:
# create usable libtool .la file
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libzip")
PROJECT(libzip C)
OPTION(ENABLE_COMMONCRYPTO "Enable use of CommonCrypto" ON)
OPTION(ENABLE_GNUTLS "Enable use of GnuTLS" ON)
OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" ON)
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
OPTION(ENABLE_WINDOWS_CRYPTO "Enable use of Windows cryptography libraries" ON)
OPTION(ENABLE_BZIP2 "Enable use of BZip2" OFF)
OPTION(ENABLE_LZMA "Enable use of LZMA" OFF)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckIncludeFiles)
INCLUDE(CheckSymbolExists)
INCLUDE(CheckTypeSize)
INCLUDE(CheckCSourceRuns)
INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckStructHasMember)
INCLUDE(TestBigEndian)
INCLUDE(GNUInstallDirs)
IF(ENABLE_COMMONCRYPTO)
CHECK_INCLUDE_FILES(CommonCrypto/CommonCrypto.h COMMONCRYPTO_FOUND)
ELSE()
SET(COMMONCRYPTO_FOUND FALSE)
ENDIF()
IF(ENABLE_GNUTLS)
INCLUDE(FindNettle)
INCLUDE(FindGnuTLS)
ELSE()
SET(GNUTLS_FOUND FALSE)
ENDIF()
IF(ENABLE_MBEDTLS)
FIND_PATH(MBEDTLS_INCLUDE_DIR mbedtls/aes.h)
FIND_LIBRARY(MBEDTLS_LIBRARIES NAMES mbedcrypto)
ELSE()
SET(MBEDTLS_LIBRARIES FALSE)
ENDIF()
IF(ENABLE_OPENSSL)
INCLUDE(FindOpenSSL)
ELSE()
SET(OPENSSL_FOUND FALSE)
ENDIF()
IF(WIN32)
IF(ENABLE_WINDOWS_CRYPTO)
SET(WINDOWS_CRYPTO_FOUND TRUE)
ENDIF()
ELSE()
SET(WINDOWS_CRYPTO_FOUND FALSE)
ENDIF()
OPTION(BUILD_SHARED_LIBS "Build shared libraries" ON)
OPTION(SHARED_LIB_VERSIONNING "Add SO version in .so build" ON)
SET(PACKAGE "libzip")
SET(PACKAGE_NAME ${PACKAGE})
SET(PACKAGE_VERSION_MAJOR "1")
SET(PACKAGE_VERSION_MINOR "5")
SET(PACKAGE_VERSION_MICRO "2a")
#SET(VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}")
SET(VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_MICRO}")
SET(PACKAGE_VERSION ${VERSION})
SET(LIBZIP_VERSION ${PACKAGE_VERSION})
SET(LIBZIP_VERSION_MAJOR ${PACKAGE_VERSION_MAJOR})
SET(LIBZIP_VERSION_MINOR ${PACKAGE_VERSION_MINOR})
SET(LIBZIP_VERSION_MICRO ${PACKAGE_VERSION_MICRO})
SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
SET(ARCHIVE_NAME ${PACKAGE_NAME}-${PACKAGE_VERSION})
IF(NOT TARGET dist)
ADD_CUSTOM_TARGET(dist
COMMAND git config tar.tar.xz.command "xz -c"
COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.gz HEAD
COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.xz HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
ADD_CUSTOM_TARGET(distcheck
COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest 2>/dev/null || true
COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
COMMAND cmake -E tar xf ${ARCHIVE_NAME}.tar.gz
COMMAND chmod -R u-w ${ARCHIVE_NAME}
COMMAND mkdir ${ARCHIVE_NAME}-build
COMMAND mkdir ${ARCHIVE_NAME}-dest
COMMAND cd ${ARCHIVE_NAME}-build && cmake -DCMAKE_INSTALL_PREFIX=../${ARCHIVE_NAME}-dest ../${ARCHIVE_NAME}
COMMAND cd ${ARCHIVE_NAME}-build && make -j4
COMMAND cd ${ARCHIVE_NAME}-build && make test
COMMAND cd ${ARCHIVE_NAME}-build && make install
# COMMAND cd ${ARCHIVE_NAME}-build && make uninstall
# COMMAND if [ `find ${ARCHIVE_NAME}-dest ! -type d | wc -l` -ne 0 ]; then echo leftover files in ${ARCHIVE_NAME}-dest; false; fi
COMMAND cd ${ARCHIVE_NAME}-build && make clean
COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
COMMAND echo "${ARCHIVE_NAME}.tar.gz is ready for distribution."
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
ADD_DEPENDENCIES(distcheck dist)
ENDIF(NOT TARGET dist)
IF(BUILD_SHARED_LIBS)
SET(HAVE_SHARED TRUE)
ELSE()
SET(ZIP_STATIC TRUE)
ENDIF()
# Checks
CHECK_FUNCTION_EXISTS(_chmod HAVE__CHMOD)
CHECK_FUNCTION_EXISTS(_close HAVE__CLOSE)
CHECK_FUNCTION_EXISTS(_dup HAVE__DUP)
CHECK_FUNCTION_EXISTS(_fdopen HAVE__FDOPEN)
CHECK_FUNCTION_EXISTS(_fileno HAVE__FILENO)
CHECK_FUNCTION_EXISTS(_open HAVE__OPEN)
CHECK_FUNCTION_EXISTS(_setmode HAVE__SETMODE)
CHECK_FUNCTION_EXISTS(_snprintf HAVE__SNPRINTF)
CHECK_FUNCTION_EXISTS(_strdup HAVE__STRDUP)
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
CHECK_FUNCTION_EXISTS(_strtoi64 HAVE__STRTOI64)
CHECK_FUNCTION_EXISTS(_strtoui64 HAVE__STRTOUI64)
CHECK_FUNCTION_EXISTS(_unlink HAVE__UNLINK)
CHECK_FUNCTION_EXISTS(arc4random HAVE_ARC4RANDOM)
CHECK_FUNCTION_EXISTS(clonefile HAVE_CLONEFILE)
CHECK_FUNCTION_EXISTS(explicit_bzero HAVE_EXPLICIT_BZERO)
CHECK_FUNCTION_EXISTS(explicit_memset HAVE_EXPLICIT_MEMSET)
CHECK_FUNCTION_EXISTS(fileno HAVE_FILENO)
CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO)
CHECK_FUNCTION_EXISTS(ftello HAVE_FTELLO)
CHECK_FUNCTION_EXISTS(getprogname HAVE_GETPROGNAME)
CHECK_FUNCTION_EXISTS(localtime_r HAVE_LOCALTIME_R)
CHECK_FUNCTION_EXISTS(open HAVE_OPEN)
CHECK_FUNCTION_EXISTS(setmode HAVE_SETMODE)
CHECK_FUNCTION_EXISTS(snprintf HAVE_SNPRINTF)
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP)
CHECK_FUNCTION_EXISTS(stricmp HAVE_STRICMP)
CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL)
CHECK_FUNCTION_EXISTS(strtoull HAVE_STRTOULL)
CHECK_INCLUDE_FILES("sys/types.h;sys/stat.h;fts.h" HAVE_FTS_H)
CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H)
CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H)
CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H_LIBZIP)
CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H_LIBZIP)
CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H_LIBZIP)
# TODO: fix test
# this test does not find __progname even when it exists
#CHECK_SYMBOL_EXISTS(__progname stdlib.h HAVE___PROGNAME)
CHECK_TYPE_SIZE(__int8 __INT8_LIBZIP)
CHECK_TYPE_SIZE(int8_t INT8_T_LIBZIP)
CHECK_TYPE_SIZE(uint8_t UINT8_T_LIBZIP)
CHECK_TYPE_SIZE(__int16 __INT16_LIBZIP)
CHECK_TYPE_SIZE(int16_t INT16_T_LIBZIP)
CHECK_TYPE_SIZE(uint16_t UINT16_T_LIBZIP)
CHECK_TYPE_SIZE(__int32 __INT32_LIBZIP)
CHECK_TYPE_SIZE(int32_t INT32_T_LIBZIP)
CHECK_TYPE_SIZE(uint32_t UINT32_T_LIBZIP)
CHECK_TYPE_SIZE(__int64 __INT64_LIBZIP)
CHECK_TYPE_SIZE(int64_t INT64_T_LIBZIP)
CHECK_TYPE_SIZE(uint64_t UINT64_T_LIBZIP)
CHECK_TYPE_SIZE("short" SHORT_LIBZIP)
CHECK_TYPE_SIZE("int" INT_LIBZIP)
CHECK_TYPE_SIZE("long" LONG_LIBZIP)
CHECK_TYPE_SIZE("long long" LONG_LONG_LIBZIP)
CHECK_TYPE_SIZE("off_t" SIZEOF_OFF_T)
CHECK_TYPE_SIZE("size_t" SIZE_T_LIBZIP)
CHECK_TYPE_SIZE("ssize_t" SSIZE_T_LIBZIP)
CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
#include <linux/fs.h>
int main(int argc, char *argv[]) { unsigned long x = FICLONERANGE; }" HAVE_FICLONERANGE)
CHECK_C_SOURCE_COMPILES("
int foo(char * _Nullable bar);
int main(int argc, char *argv[]) { }" HAVE_NULLABLE)
TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
#FIND_PACKAGE(ZLIB 1.1.2 REQUIRED)
INCLUDE_DIRECTORIES(../zlib/zlib)
SET(CMAKE_REQUIRED_INCLUDES ../zlib/zlib)
IF(ENABLE_BZIP2)
FIND_PACKAGE(BZip2)
IF(BZIP2_FOUND)
SET (HAVE_LIBBZ2 1)
INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR})
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${BZIP2_LIBRARIES})
ELSE()
MESSAGE(WARNING "-- bzip2 library not found; bzip2 support disabled")
ENDIF(BZIP2_FOUND)
ENDIF(ENABLE_BZIP2)
IF(ENABLE_LZMA)
FIND_PACKAGE(LibLZMA)
IF(LIBLZMA_FOUND)
SET (HAVE_LIBLZMA 1)
INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIR})
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${LIBLZMA_LIBRARY})
ELSE()
MESSAGE(WARNING "-- lzma library not found; lzma support disabled")
ENDIF(LIBLZMA_FOUND)
ENDIF(ENABLE_LZMA)
IF (COMMONCRYPTO_FOUND)
SET (HAVE_CRYPTO 1)
SET (HAVE_COMMONCRYPTO 1)
ELSEIF (WINDOWS_CRYPTO_FOUND)
SET (HAVE_CRYPTO 1)
SET (HAVE_WINDOWS_CRYPTO 1)
ELSEIF (GNUTLS_FOUND AND NETTLE_FOUND)
SET (HAVE_CRYPTO 1)
SET (HAVE_GNUTLS 1)
INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_DIR} ${NETTLE_INCLUDE_DIR})
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${GNUTLS_LIBRARY} ${NETTLE_LIBRARY})
ELSEIF (OPENSSL_FOUND)
SET (HAVE_CRYPTO 1)
SET (HAVE_OPENSSL 1)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${OPENSSL_LIBRARIES})
ELSEIF (MBEDTLS_LIBRARIES)
SET (HAVE_CRYPTO 1)
SET (HAVE_MBEDTLS 1)
INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIR})
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${MBEDTLS_LIBRARIES})
ENDIF()
IF (NOT HAVE_CRYPTO)
MESSAGE(WARNING "-- neither Common Crypto, GnuTLS, mbed TLS, OpenSSL, nor Windows Cryptography found; AES support disabled")
ENDIF()
IF(MSVC)
ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS")
ADD_DEFINITIONS("-D_CRT_NONSTDC_NO_DEPRECATE")
ENDIF(MSVC)
if(WIN32)
if(HAVE_WINDOWS_CRYPTO)
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} bcrypt)
endif()
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
ADD_DEFINITIONS(-DMS_UWP)
else(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} advapi32)
endif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
endif(WIN32)
ADD_DEFINITIONS("-DHAVE_CONFIG_H")
# rpath handling: use rpath in installed binaries
IF(NOT CMAKE_SYSTEM_NAME MATCHES Linux)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
ENDIF()
# fixed size integral types
IF(HAVE_INTTYPES_H_LIBZIP)
SET(LIBZIP_TYPES_INCLUDE "#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>")
ELSEIF(HAVE_STDINT_H_LIBZIP)
SET(LIBZIP_TYPES_INCLUDE "#include <stdint.h>")
ELSEIF(HAVE_SYS_TYPES_H_LIBZIP)
SET(LIBZIP_TYPES_INCLUDE "#include <sys/types.h>")
ENDIF()
IF(HAVE_INT8_T_LIBZIP)
SET(ZIP_INT8_T int8_t)
ELSEIF(HAVE___INT8_LIBZIP)
SET(ZIP_INT8_T __int8)
ELSE()
SET(ZIP_INT8_T "signed char")
ENDIF()
IF(HAVE_UINT8_T_LIBZIP)
SET(ZIP_UINT8_T uint8_t)
ELSEIF(HAVE___INT8_LIBZIP)
SET(ZIP_UINT8_T "unsigned __int8")
ELSE()
SET(ZIP_UINT8_T "unsigned char")
ENDIF()
IF(HAVE_INT16_T_LIBZIP)
SET(ZIP_INT16_T int16_t)
ELSEIF(HAVE___INT16_LIBZIP)
SET(INT16_T_LIBZIP __int16)
ELSEIF(SHORT_LIBZIP EQUAL 2)
SET(INT16_T_LIBZIP short)
ENDIF()
IF(HAVE_UINT16_T_LIBZIP)
SET(ZIP_UINT16_T uint16_t)
ELSEIF(HAVE___INT16_LIBZIP)
SET(UINT16_T_LIBZIP "unsigned __int16")
ELSEIF(SHORT_LIBZIP EQUAL 2)
SET(UINT16_T_LIBZIP "unsigned short")
ENDIF()
IF(HAVE_INT32_T_LIBZIP)
SET(ZIP_INT32_T int32_t)
ELSEIF(HAVE___INT32_LIBZIP)
SET(ZIP_INT32_T __int32)
ELSEIF(INT_LIBZIP EQUAL 4)
SET(ZIP_INT32_T int)
ELSEIF(LONG_LIBZIP EQUAL 4)
SET(ZIP_INT32_T long)
ENDIF()
IF(HAVE_UINT32_T_LIBZIP)
SET(ZIP_UINT32_T uint32_t)
ELSEIF(HAVE___INT32_LIBZIP)
SET(ZIP_UINT32_T "unsigned __int32")
ELSEIF(INT_LIBZIP EQUAL 4)
SET(ZIP_UINT32_T "unsigned int")
ELSEIF(LONG_LIBZIP EQUAL 4)
SET(ZIP_UINT32_T "unsigned long")
ENDIF()
IF(HAVE_INT64_T_LIBZIP)
SET(ZIP_INT64_T int64_t)
ELSEIF(HAVE___INT64_LIBZIP)
SET(ZIP_INT64_T __int64)
ELSEIF(LONG_LIBZIP EQUAL 8)
SET(ZIP_INT64_T long)
ELSEIF(LONG_LONG_LIBZIP EQUAL 8)
SET(ZIP_INT64_T "long long")
ENDIF()
IF(HAVE_UINT64_T_LIBZIP)
SET(ZIP_UINT64_T uint64_t)
ELSEIF(HAVE___INT64_LIBZIP)
SET(ZIP_UINT64_T "unsigned __int64")
ELSEIF(LONG_LIBZIP EQUAL 8)
SET(ZIP_UINT64_T "unsigned long")
ELSEIF(LONG_LONG_LIBZIP EQUAL 8)
SET(ZIP_UINT64_T "unsigned long long")
ENDIF()
IF(HAVE_NULLABLE)
SET(ZIP_NULLABLE_DEFINES)
ELSE()
SET(ZIP_NULLABLE_DEFINES "#define _Nullable
#define _Nonnull")
ENDIF()
# write out config file
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libzip/cmake-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/libzip/config.h)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libzip/cmake-zipconf.h.in ${CMAKE_CURRENT_BINARY_DIR}/libzip/zipconf.h)
# installation
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libzip/zipconf.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
INSTALL(FILES libzip/lib/zip.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
SET(CMAKE_C_VISIBILITY_PRESET hidden)
ADD_LIBRARY(zip
libzip/lib/zip_add.c
libzip/lib/zip_add_dir.c
libzip/lib/zip_add_entry.c
libzip/lib/zip_algorithm_deflate.c
libzip/lib/zip_buffer.c
libzip/lib/zip_close.c
libzip/lib/zip_delete.c
libzip/lib/zip_dir_add.c
libzip/lib/zip_dirent.c
libzip/lib/zip_discard.c
libzip/lib/zip_entry.c
libzip/lib/zip_err_str.c
libzip/lib/zip_error.c
libzip/lib/zip_error_clear.c
libzip/lib/zip_error_get.c
libzip/lib/zip_error_get_sys_type.c
libzip/lib/zip_error_strerror.c
libzip/lib/zip_error_to_str.c
libzip/lib/zip_extra_field.c
libzip/lib/zip_extra_field_api.c
libzip/lib/zip_fclose.c
libzip/lib/zip_fdopen.c
libzip/lib/zip_file_add.c
libzip/lib/zip_file_error_clear.c
libzip/lib/zip_file_error_get.c
libzip/lib/zip_file_get_comment.c
libzip/lib/zip_file_get_external_attributes.c
libzip/lib/zip_file_get_offset.c
libzip/lib/zip_file_rename.c
libzip/lib/zip_file_replace.c
libzip/lib/zip_file_set_comment.c
libzip/lib/zip_file_set_encryption.c
libzip/lib/zip_file_set_external_attributes.c
libzip/lib/zip_file_set_mtime.c
libzip/lib/zip_file_strerror.c
libzip/lib/zip_filerange_crc.c
libzip/lib/zip_fopen.c
libzip/lib/zip_fopen_encrypted.c
libzip/lib/zip_fopen_index.c
libzip/lib/zip_fopen_index_encrypted.c
libzip/lib/zip_fread.c
libzip/lib/zip_fseek.c
libzip/lib/zip_ftell.c
libzip/lib/zip_get_archive_comment.c
libzip/lib/zip_get_archive_flag.c
libzip/lib/zip_get_encryption_implementation.c
libzip/lib/zip_get_file_comment.c
libzip/lib/zip_get_name.c
libzip/lib/zip_get_num_entries.c
libzip/lib/zip_get_num_files.c
libzip/lib/zip_hash.c
libzip/lib/zip_io_util.c
libzip/lib/zip_libzip_version.c
libzip/lib/zip_memdup.c
libzip/lib/zip_name_locate.c
libzip/lib/zip_new.c
libzip/lib/zip_open.c
libzip/lib/zip_progress.c
libzip/lib/zip_rename.c
libzip/lib/zip_replace.c
libzip/lib/zip_set_archive_comment.c
libzip/lib/zip_set_archive_flag.c
libzip/lib/zip_set_default_password.c
libzip/lib/zip_set_file_comment.c
libzip/lib/zip_set_file_compression.c
libzip/lib/zip_set_name.c
libzip/lib/zip_source_accept_empty.c
libzip/lib/zip_source_begin_write.c
libzip/lib/zip_source_begin_write_cloning.c
libzip/lib/zip_source_buffer.c
libzip/lib/zip_source_call.c
libzip/lib/zip_source_close.c
libzip/lib/zip_source_commit_write.c
libzip/lib/zip_source_compress.c
libzip/lib/zip_source_crc.c
libzip/lib/zip_source_error.c
libzip/lib/zip_source_filep.c
libzip/lib/zip_source_free.c
libzip/lib/zip_source_function.c
libzip/lib/zip_source_get_compression_flags.c
libzip/lib/zip_source_is_deleted.c
libzip/lib/zip_source_layered.c
libzip/lib/zip_source_open.c
libzip/lib/zip_source_pkware.c
libzip/lib/zip_source_read.c
libzip/lib/zip_source_remove.c
libzip/lib/zip_source_rollback_write.c
libzip/lib/zip_source_seek.c
libzip/lib/zip_source_seek_write.c
libzip/lib/zip_source_stat.c
libzip/lib/zip_source_supports.c
libzip/lib/zip_source_tell.c
libzip/lib/zip_source_tell_write.c
libzip/lib/zip_source_window.c
libzip/lib/zip_source_write.c
libzip/lib/zip_source_zip.c
libzip/lib/zip_source_zip_new.c
libzip/lib/zip_stat.c
libzip/lib/zip_stat_index.c
libzip/lib/zip_stat_init.c
libzip/lib/zip_strerror.c
libzip/lib/zip_string.c
libzip/lib/zip_unchange.c
libzip/lib/zip_unchange_all.c
libzip/lib/zip_unchange_archive.c
libzip/lib/zip_unchange_data.c
libzip/lib/zip_utf-8.c
)
IF(WIN32)
target_sources(zip PRIVATE
libzip/lib/zip_source_win32handle.c
libzip/lib/zip_source_win32utf8.c
libzip/lib/zip_source_win32w.c
)
IF(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
ELSE()
target_sources(zip PRIVATE libzip/lib/zip_source_win32a.c)
ENDIF()
ELSE()
target_sources(zip PRIVATE
libzip/lib/zip_mkstempm.c
libzip/lib/zip_source_file.c
libzip/lib/zip_random_unix.c
)
ENDIF()
IF(HAVE_LIBBZ2)
target_sources(zip PRIVATE libzip/lib/zip_algorithm_bzip2.c)
ENDIF()
IF(HAVE_LIBLZMA)
target_sources(zip PRIVATE libzip/lib/zip_algorithm_xz.c)
ENDIF()
IF(HAVE_COMMONCRYPTO)
target_sources(zip PRIVATE libzip/lib/zip_crypto_commoncrypto.c)
ELSEIF(HAVE_WINDOWS_CRYPTO)
target_sources(zip PRIVATE libzip/lib/zip_crypto_win.c)
ELSEIF(HAVE_GNUTLS)
target_sources(zip PRIVATE libzip/lib/zip_crypto_gnutls.c)
ELSEIF(HAVE_OPENSSL)
target_sources(zip PRIVATE libzip/lib/zip_crypto_openssl.c)
ELSEIF(HAVE_MBEDTLS)
target_sources(zip PRIVATE libzip/lib/zip_crypto_mbedtls.c)
ENDIF()
IF(HAVE_CRYPTO)
target_sources(zip PRIVATE
libzip/lib/zip_winzip_aes.c
libzip/lib/zip_source_winzip_aes_decode.c
libzip/lib/zip_source_winzip_aes_encode.c
)
ENDIF()
target_include_directories(zip
PUBLIC
libzip/lib
${CMAKE_CURRENT_BINARY_DIR}/libzip
)
# pkgconfig file
SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(exec_prefix \${prefix})
SET(bindir \${exec_prefix}/${CMAKE_INSTALL_BINDIR})
SET(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
SET(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
IF(CMAKE_SYSTEM_NAME MATCHES BSD)
SET(PKG_CONFIG_RPATH "-Wl,-R\${libdir}")
ENDIF(CMAKE_SYSTEM_NAME MATCHES BSD)
get_target_property(LIBS_PRIVATE zip LINK_LIBRARIES)
foreach(LIB ${LIBS_PRIVATE})
if(LIB MATCHES "^/")
get_filename_component(LIB ${LIB} NAME_WE)
string(REGEX REPLACE "^lib" "" LIB ${LIB})
endif()
set(LIBS "${LIBS} -l${LIB}")
endforeach()
CONFIGURE_FILE(libzip/libzip.pc.in libzip/libzip.pc @ONLY)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libzip.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
ADD_CUSTOM_TARGET(update_zip_err_str
COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/make_zip_err_str.sh ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip.h ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip_err_str.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip.h ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/make_zip_err_str.sh
)
IF(SHARED_LIB_VERSIONNING)
SET_TARGET_PROPERTIES(zip PROPERTIES VERSION 5.0 SOVERSION 5)
ENDIF()
TARGET_LINK_LIBRARIES(zip ${ZLIB_LIBRARIES} ${OPTIONAL_LIBRARY})
INSTALL(TARGETS zip
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
Vendored Submodule
+1
Submodule externals/libzip/libzip added at 89bd6d63bd
-3
View File
@@ -2,16 +2,13 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <cmath>
#include <numbers>
#include "audio_core/algorithm/interpolate.h"
#include "audio_core/command_generator.h"
#include "audio_core/effect_context.h"
#include "audio_core/mix_context.h"
#include "audio_core/voice_context.h"
#include "common/common_types.h"
#include "core/memory.h"
namespace AudioCore {
-2
View File
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include "audio_core/behavior_info.h"
#include "audio_core/common.h"
#include "audio_core/effect_context.h"
-2
View File
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include "audio_core/behavior_info.h"
#include "audio_core/voice_context.h"
#include "core/memory.h"
+1 -3
View File
@@ -53,8 +53,6 @@ add_library(common STATIC
div_ceil.h
dynamic_library.cpp
dynamic_library.h
error.cpp
error.h
fiber.cpp
fiber.h
fs/file.cpp
@@ -79,7 +77,6 @@ add_library(common STATIC
logging/filter.cpp
logging/filter.h
logging/log.h
logging/log_entry.h
logging/text_formatter.cpp
logging/text_formatter.h
logging/types.h
@@ -91,6 +88,7 @@ add_library(common STATIC
microprofile.cpp
microprofile.h
microprofileui.h
misc.cpp
nvidia_flags.cpp
nvidia_flags.h
page_table.cpp
+7 -14
View File
@@ -9,48 +9,41 @@
namespace Common {
template <typename T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
auto mod{static_cast<T>(value % size)};
value -= mod;
return static_cast<T>(mod == T{0} ? value : value + size);
}
template <typename T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2);
}
template <typename T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
return static_cast<T>(value - value % size);
}
template <typename T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool Is4KBAligned(T value) {
requires std::is_unsigned_v<T>[[nodiscard]] constexpr bool Is4KBAligned(T value) {
return (value & 0xFFF) == 0;
}
template <typename T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsWordAligned(T value) {
requires std::is_unsigned_v<T>[[nodiscard]] constexpr bool IsWordAligned(T value) {
return (value & 0b11) == 0;
}
template <typename T>
requires std::is_integral_v<T>
[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
requires std::is_integral_v<T>[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
using U = typename std::make_unsigned_t<T>;
const U mask = static_cast<U>(alignment - 1);
return (value & mask) == 0;
}
template <typename T, typename U>
requires std::is_integral_v<T>
[[nodiscard]] constexpr T DivideUp(T x, U y) {
requires std::is_integral_v<T>[[nodiscard]] constexpr T DivideUp(T x, U y) {
return (x + (y - 1)) / y;
}
+12 -17
View File
@@ -4,8 +4,9 @@
#pragma once
#include <algorithm>
#include <array>
#include <iterator>
#include <string>
#if !defined(ARCHITECTURE_x86_64)
#include <cstdlib> // for exit
@@ -48,6 +49,16 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
#endif // _MSC_VER ndef
// Generic function to get last error message.
// Call directly after the command or use the error num.
// This function might change the error code.
// Defined in misc.cpp.
[[nodiscard]] std::string GetLastErrorMsg();
// Like GetLastErrorMsg(), but passing an explicit error code.
// Defined in misc.cpp.
[[nodiscard]] std::string NativeErrorToString(int e);
#define DECLARE_ENUM_FLAG_OPERATORS(type) \
[[nodiscard]] constexpr type operator|(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
@@ -61,14 +72,6 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \
} \
[[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) << static_cast<T>(b)); \
} \
[[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(static_cast<T>(a) >> static_cast<T>(b)); \
} \
constexpr type& operator|=(type& a, type b) noexcept { \
a = a | b; \
return a; \
@@ -81,14 +84,6 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
a = a ^ b; \
return a; \
} \
constexpr type& operator<<=(type& a, type b) noexcept { \
a = a << b; \
return a; \
} \
constexpr type& operator>>=(type& a, type b) noexcept { \
a = a >> b; \
return a; \
} \
[[nodiscard]] constexpr type operator~(type key) noexcept { \
using T = std::underlying_type_t<type>; \
return static_cast<type>(~static_cast<T>(key)); \
+4 -4
View File
@@ -11,15 +11,15 @@ namespace Common {
/// Ceiled integer division.
template <typename N, typename D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeil(N number,
D divisor) {
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
}
/// Ceiled integer division with logarithmic divisor in base 2
template <typename N, typename D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeilLog2(
N value, D alignment_log2) {
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
}
-21
View File
@@ -1,21 +0,0 @@
// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <string>
namespace Common {
// Generic function to get last error message.
// Call directly after the command or use the error num.
// This function might change the error code.
// Defined in error.cpp.
[[nodiscard]] std::string GetLastErrorMsg();
// Like GetLastErrorMsg(), but passing an explicit error code.
// Defined in error.cpp.
[[nodiscard]] std::string NativeErrorToString(int e);
} // namespace Common
-1
View File
@@ -21,7 +21,6 @@
#define SCREENSHOTS_DIR "screenshots"
#define SDMC_DIR "sdmc"
#define SHADER_DIR "shader"
#define TAS_DIR "tas"
// yuzu-specific files
+12 -16
View File
@@ -82,35 +82,32 @@ public:
private:
PathManagerImpl() {
fs::path yuzu_path;
fs::path yuzu_path_cache;
fs::path yuzu_path_config;
#ifdef _WIN32
yuzu_path = GetExeDirectory() / PORTABLE_DIR;
auto yuzu_path = GetExeDirectory() / PORTABLE_DIR;
if (!IsDir(yuzu_path)) {
yuzu_path = GetAppDataRoamingDirectory() / YUZU_DIR;
}
yuzu_path_cache = yuzu_path / CACHE_DIR;
yuzu_path_config = yuzu_path / CONFIG_DIR;
GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path);
GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path / CACHE_DIR);
GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path / CONFIG_DIR);
#else
yuzu_path = GetCurrentDir() / PORTABLE_DIR;
auto yuzu_path = GetCurrentDir() / PORTABLE_DIR;
if (Exists(yuzu_path) && IsDir(yuzu_path)) {
yuzu_path_cache = yuzu_path / CACHE_DIR;
yuzu_path_config = yuzu_path / CONFIG_DIR;
GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path);
GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path / CACHE_DIR);
GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path / CONFIG_DIR);
} else {
yuzu_path = GetDataDirectory("XDG_DATA_HOME") / YUZU_DIR;
yuzu_path_cache = GetDataDirectory("XDG_CACHE_HOME") / YUZU_DIR;
yuzu_path_config = GetDataDirectory("XDG_CONFIG_HOME") / YUZU_DIR;
GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path);
GenerateYuzuPath(YuzuPath::CacheDir, GetDataDirectory("XDG_CACHE_HOME") / YUZU_DIR);
GenerateYuzuPath(YuzuPath::ConfigDir, GetDataDirectory("XDG_CONFIG_HOME") / YUZU_DIR);
}
#endif
GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path);
GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache);
GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config);
GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR);
GenerateYuzuPath(YuzuPath::KeysDir, yuzu_path / KEYS_DIR);
GenerateYuzuPath(YuzuPath::LoadDir, yuzu_path / LOAD_DIR);
@@ -119,7 +116,6 @@ private:
GenerateYuzuPath(YuzuPath::ScreenshotsDir, yuzu_path / SCREENSHOTS_DIR);
GenerateYuzuPath(YuzuPath::SDMCDir, yuzu_path / SDMC_DIR);
GenerateYuzuPath(YuzuPath::ShaderDir, yuzu_path / SHADER_DIR);
GenerateYuzuPath(YuzuPath::TASDir, yuzu_path / TAS_DIR);
}
~PathManagerImpl() = default;
-1
View File
@@ -23,7 +23,6 @@ enum class YuzuPath {
ScreenshotsDir, // Where yuzu screenshots are stored.
SDMCDir, // Where the emulated SDMC is stored.
ShaderDir, // Where shaders are stored.
TASDir, // Where TAS scripts are stored.
};
/**
+1 -1
View File
@@ -314,8 +314,8 @@ private:
}
void UntrackPlaceholder(boost::icl::separate_interval_set<size_t>::iterator it) {
placeholder_host_pointers.erase(it->lower());
placeholders.erase(it);
placeholder_host_pointers.erase(it->lower());
}
/// Return true when a given memory region is a "nieche" and the placeholders don't have to be
+9 -8
View File
@@ -235,19 +235,20 @@ public:
template <typename T>
concept HasLightCompareType = requires {
{ std::is_same<typename T::LightCompareType, void>::value } -> std::convertible_to<bool>;
{ std::is_same<typename T::LightCompareType, void>::value }
->std::convertible_to<bool>;
};
namespace impl {
template <typename T, typename Default>
consteval auto* GetLightCompareType() {
if constexpr (HasLightCompareType<T>) {
return static_cast<typename T::LightCompareType*>(nullptr);
} else {
return static_cast<Default*>(nullptr);
}
template <typename T, typename Default>
consteval auto* GetLightCompareType() {
if constexpr (HasLightCompareType<T>) {
return static_cast<typename T::LightCompareType*>(nullptr);
} else {
return static_cast<Default*>(nullptr);
}
}
} // namespace impl
+143 -220
View File
@@ -2,188 +2,42 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <atomic>
#include <chrono>
#include <climits>
#include <exception>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>
#include <fmt/format.h>
#ifdef _WIN32
#include <windows.h> // For OutputDebugStringW
#endif
#include "common/assert.h"
#include "common/fs/file.h"
#include "common/fs/fs.h"
#include "common/fs/fs_paths.h"
#include "common/fs/path_util.h"
#include "common/literals.h"
#include "common/thread.h"
#include "common/logging/backend.h"
#include "common/logging/log.h"
#include "common/logging/log_entry.h"
#include "common/logging/text_formatter.h"
#include "common/settings.h"
#ifdef _WIN32
#include "common/string_util.h"
#endif
#include "common/threadsafe_queue.h"
namespace Common::Log {
namespace {
/**
* Interface for logging backends.
*/
class Backend {
public:
virtual ~Backend() = default;
virtual void Write(const Entry& entry) = 0;
virtual void EnableForStacktrace() = 0;
virtual void Flush() = 0;
};
/**
* Backend that writes to stderr and with color
*/
class ColorConsoleBackend final : public Backend {
public:
explicit ColorConsoleBackend() = default;
~ColorConsoleBackend() override = default;
void Write(const Entry& entry) override {
if (enabled.load(std::memory_order_relaxed)) {
PrintColoredMessage(entry);
}
}
void Flush() override {
// stderr shouldn't be buffered
}
void EnableForStacktrace() override {
enabled = true;
}
void SetEnabled(bool enabled_) {
enabled = enabled_;
}
private:
std::atomic_bool enabled{false};
};
/**
* Backend that writes to a file passed into the constructor
*/
class FileBackend final : public Backend {
public:
explicit FileBackend(const std::filesystem::path& filename) {
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.
static_cast<void>(FS::RemoveFile(old_filename));
static_cast<void>(FS::RenameFile(filename, old_filename));
file = std::make_unique<FS::IOFile>(filename, FS::FileAccessMode::Write,
FS::FileType::TextFile);
}
~FileBackend() override = default;
void Write(const Entry& entry) override {
if (!enabled) {
return;
}
bytes_written += file->WriteString(FormatLogMessage(entry).append(1, '\n'));
using namespace Common::Literals;
// Prevent logs from exceeding a set maximum size in the event that log entries are spammed.
const auto write_limit = Settings::values.extended_logging ? 1_GiB : 100_MiB;
const bool write_limit_exceeded = bytes_written > write_limit;
if (entry.log_level >= Level::Error || write_limit_exceeded) {
if (write_limit_exceeded) {
// Stop writing after the write limit is exceeded.
// Don't close the file so we can print a stacktrace if necessary
enabled = false;
}
file->Flush();
}
}
void Flush() override {
file->Flush();
}
void EnableForStacktrace() override {
enabled = true;
bytes_written = 0;
}
private:
std::unique_ptr<FS::IOFile> file;
bool enabled = true;
std::size_t bytes_written = 0;
};
/**
* Backend that writes to Visual Studio's output window
*/
class DebuggerBackend final : public Backend {
public:
explicit DebuggerBackend() = default;
~DebuggerBackend() override = default;
void Write(const Entry& entry) override {
#ifdef _WIN32
::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
#endif
}
void Flush() override {}
void EnableForStacktrace() override {}
};
bool initialization_in_progress_suppress_logging = true;
/**
* Static state as a singleton.
*/
class Impl {
public:
static Impl& Instance() {
if (!instance) {
throw std::runtime_error("Using Logging instance before its initialization");
}
return *instance;
}
static void Initialize() {
if (instance) {
LOG_WARNING(Log, "Reinitializing logging backend");
return;
}
using namespace Common::FS;
const auto& log_dir = GetYuzuPath(YuzuPath::LogDir);
void(CreateDir(log_dir));
Filter filter;
filter.ParseFilterString(Settings::values.log_filter.GetValue());
instance = std::unique_ptr<Impl, decltype(&Deleter)>(new Impl(log_dir / LOG_FILE, filter),
Deleter);
initialization_in_progress_suppress_logging = false;
static Impl backend;
return backend;
}
Impl(const Impl&) = delete;
@@ -192,54 +46,74 @@ public:
Impl(Impl&&) = delete;
Impl& operator=(Impl&&) = delete;
void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, std::string message) {
message_queue.Push(
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message)));
}
void AddBackend(std::unique_ptr<Backend> backend) {
std::lock_guard lock{writing_mutex};
backends.push_back(std::move(backend));
}
void RemoveBackend(std::string_view backend_name) {
std::lock_guard lock{writing_mutex};
std::erase_if(backends, [&backend_name](const auto& backend) {
return backend_name == backend->GetName();
});
}
const Filter& GetGlobalFilter() const {
return filter;
}
void SetGlobalFilter(const Filter& f) {
filter = f;
}
void SetColorConsoleBackendEnabled(bool enabled) {
color_console_backend.SetEnabled(enabled);
}
void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, std::string message) {
if (!filter.CheckMessage(log_class, log_level))
return;
const Entry& entry =
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message));
message_queue.Push(entry);
Backend* GetBackend(std::string_view backend_name) {
const auto it =
std::find_if(backends.begin(), backends.end(),
[&backend_name](const auto& i) { return backend_name == i->GetName(); });
if (it == backends.end())
return nullptr;
return it->get();
}
private:
Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_)
: filter{filter_}, file_backend{file_backend_filename}, backend_thread{std::thread([this] {
Common::SetCurrentThreadName("yuzu:Log");
Entry entry;
const auto write_logs = [this, &entry]() {
ForEachBackend([&entry](Backend& backend) { backend.Write(entry); });
};
while (true) {
entry = message_queue.PopWait();
if (entry.final_entry) {
break;
}
write_logs();
}
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a
// case where a system is repeatedly spamming logs even on close.
int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100;
while (max_logs_to_write-- && message_queue.Pop(entry)) {
write_logs();
}
})} {}
Impl() {
backend_thread = std::thread([&] {
Entry entry;
auto write_logs = [&](Entry& e) {
std::lock_guard lock{writing_mutex};
for (const auto& backend : backends) {
backend->Write(e);
}
};
while (true) {
entry = message_queue.PopWait();
if (entry.final_entry) {
break;
}
write_logs(entry);
}
~Impl() {
StopBackendThread();
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a
// case where a system is repeatedly spamming logs even on close.
const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100;
int logs_written = 0;
while (logs_written++ < MAX_LOGS_TO_WRITE && message_queue.Pop(entry)) {
write_logs(entry);
}
});
}
void StopBackendThread() {
Entry stop_entry{};
stop_entry.final_entry = true;
message_queue.Push(stop_entry);
~Impl() {
Entry entry;
entry.final_entry = true;
message_queue.Push(entry);
backend_thread.join();
}
@@ -261,51 +135,100 @@ private:
};
}
void ForEachBackend(auto lambda) {
lambda(static_cast<Backend&>(debugger_backend));
lambda(static_cast<Backend&>(color_console_backend));
lambda(static_cast<Backend&>(file_backend));
}
static void Deleter(Impl* ptr) {
delete ptr;
}
static inline std::unique_ptr<Impl, decltype(&Deleter)> instance{nullptr, Deleter};
Filter filter;
DebuggerBackend debugger_backend{};
ColorConsoleBackend color_console_backend{};
FileBackend file_backend;
std::mutex writing_mutex;
std::thread backend_thread;
MPSCQueue<Entry> message_queue{};
std::vector<std::unique_ptr<Backend>> backends;
MPSCQueue<Entry> message_queue;
Filter filter;
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
};
} // namespace
void Initialize() {
Impl::Initialize();
ConsoleBackend::~ConsoleBackend() = default;
void ConsoleBackend::Write(const Entry& entry) {
PrintMessage(entry);
}
void DisableLoggingInTests() {
initialization_in_progress_suppress_logging = true;
ColorConsoleBackend::~ColorConsoleBackend() = default;
void ColorConsoleBackend::Write(const Entry& entry) {
PrintColoredMessage(entry);
}
FileBackend::FileBackend(const std::filesystem::path& filename) {
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.
FS::RemoveFile(old_filename);
void(FS::RenameFile(filename, old_filename));
file =
std::make_unique<FS::IOFile>(filename, FS::FileAccessMode::Write, FS::FileType::TextFile);
}
FileBackend::~FileBackend() = default;
void FileBackend::Write(const Entry& entry) {
if (!file->IsOpen()) {
return;
}
using namespace Common::Literals;
// Prevent logs from exceeding a set maximum size in the event that log entries are spammed.
constexpr std::size_t MAX_BYTES_WRITTEN = 100_MiB;
constexpr std::size_t MAX_BYTES_WRITTEN_EXTENDED = 1_GiB;
const bool write_limit_exceeded =
bytes_written > MAX_BYTES_WRITTEN_EXTENDED ||
(bytes_written > MAX_BYTES_WRITTEN && !Settings::values.extended_logging);
// Close the file after the write limit is exceeded.
if (write_limit_exceeded) {
file->Close();
return;
}
bytes_written += file->WriteString(FormatLogMessage(entry).append(1, '\n'));
if (entry.log_level >= Level::Error) {
file->Flush();
}
}
DebuggerBackend::~DebuggerBackend() = default;
void DebuggerBackend::Write(const Entry& entry) {
#ifdef _WIN32
::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
#endif
}
void SetGlobalFilter(const Filter& filter) {
Impl::Instance().SetGlobalFilter(filter);
}
void SetColorConsoleBackendEnabled(bool enabled) {
Impl::Instance().SetColorConsoleBackendEnabled(enabled);
void AddBackend(std::unique_ptr<Backend> backend) {
Impl::Instance().AddBackend(std::move(backend));
}
void RemoveBackend(std::string_view backend_name) {
Impl::Instance().RemoveBackend(backend_name);
}
Backend* GetBackend(std::string_view backend_name) {
return Impl::Instance().GetBackend(backend_name);
}
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, const char* format,
const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,
fmt::vformat(format, args));
}
auto& instance = Impl::Instance();
const auto& filter = instance.GetGlobalFilter();
if (!filter.CheckMessage(log_class, log_level))
return;
instance.PushEntry(log_class, log_level, filename, line_num, function,
fmt::vformat(format, args));
}
} // namespace Common::Log
+106 -7
View File
@@ -5,21 +5,120 @@
#pragma once
#include <filesystem>
#include <memory>
#include <string>
#include <string_view>
#include "common/logging/filter.h"
#include "common/logging/log.h"
namespace Common::FS {
class IOFile;
}
namespace Common::Log {
class Filter;
/// Initializes the logging system. This should be the first thing called in main.
void Initialize();
/**
* Interface for logging backends. As loggers can be created and removed at runtime, this can be
* used by a frontend for adding a custom logging backend as needed
*/
class Backend {
public:
virtual ~Backend() = default;
void DisableLoggingInTests();
virtual void SetFilter(const Filter& new_filter) {
filter = new_filter;
}
virtual const char* GetName() const = 0;
virtual void Write(const Entry& entry) = 0;
private:
Filter filter;
};
/**
* The global filter will prevent any messages from even being processed if they are filtered.
* Backend that writes to stderr without any color commands
*/
class ConsoleBackend : public Backend {
public:
~ConsoleBackend() override;
static const char* Name() {
return "console";
}
const char* GetName() const override {
return Name();
}
void Write(const Entry& entry) override;
};
/**
* Backend that writes to stderr and with color
*/
class ColorConsoleBackend : public Backend {
public:
~ColorConsoleBackend() override;
static const char* Name() {
return "color_console";
}
const char* GetName() const override {
return Name();
}
void Write(const Entry& entry) override;
};
/**
* Backend that writes to a file passed into the constructor
*/
class FileBackend : public Backend {
public:
explicit FileBackend(const std::filesystem::path& filename);
~FileBackend() override;
static const char* Name() {
return "file";
}
const char* GetName() const override {
return Name();
}
void Write(const Entry& entry) override;
private:
std::unique_ptr<FS::IOFile> file;
std::size_t bytes_written = 0;
};
/**
* Backend that writes to Visual Studio's output window
*/
class DebuggerBackend : public Backend {
public:
~DebuggerBackend() override;
static const char* Name() {
return "debugger";
}
const char* GetName() const override {
return Name();
}
void Write(const Entry& entry) override;
};
void AddBackend(std::unique_ptr<Backend> backend);
void RemoveBackend(std::string_view backend_name);
Backend* GetBackend(std::string_view backend_name);
/**
* The global filter will prevent any messages from even being processed if they are filtered. Each
* backend can have a filter, but if the level is lower than the global filter, the backend will
* never get the message
*/
void SetGlobalFilter(const Filter& filter);
void SetColorConsoleBackendEnabled(bool enabled);
} // namespace Common::Log
} // namespace Common::Log
-1
View File
@@ -111,7 +111,6 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Service, NCM) \
SUB(Service, NFC) \
SUB(Service, NFP) \
SUB(Service, NGCT) \
SUB(Service, NIFM) \
SUB(Service, NIM) \
SUB(Service, NPNS) \
+1 -5
View File
@@ -4,11 +4,7 @@
#pragma once
#include <algorithm>
#include <string_view>
#include <fmt/core.h>
#include <fmt/format.h>
#include "common/logging/types.h"
namespace Common::Log {
-28
View File
@@ -1,28 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <chrono>
#include "common/logging/types.h"
namespace Common::Log {
/**
* A log entry. Log entries are store in a structured format to permit more varied output
* formatting on different frontends, as well as facilitating filtering and aggregation.
*/
struct Entry {
std::chrono::microseconds timestamp;
Class log_class{};
Level log_level{};
const char* filename = nullptr;
unsigned int line_num = 0;
std::string function;
std::string message;
bool final_entry = false;
};
} // namespace Common::Log
-1
View File
@@ -13,7 +13,6 @@
#include "common/common_funcs.h"
#include "common/logging/filter.h"
#include "common/logging/log.h"
#include "common/logging/log_entry.h"
#include "common/logging/text_formatter.h"
#include "common/string_util.h"
+17 -1
View File
@@ -4,6 +4,8 @@
#pragma once
#include <chrono>
#include "common/common_types.h"
namespace Common::Log {
@@ -79,7 +81,6 @@ enum class Class : u8 {
Service_NCM, ///< The NCM service
Service_NFC, ///< The NFC (Near-field communication) service
Service_NFP, ///< The NFP service
Service_NGCT, ///< The NGCT (No Good Content for Terra) service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NIM, ///< The NIM service
Service_NPNS, ///< The NPNS service
@@ -129,4 +130,19 @@ enum class Class : u8 {
Count ///< Total number of logging classes
};
/**
* A log entry. Log entries are store in a structured format to permit more varied output
* formatting on different frontends, as well as facilitating filtering and aggregation.
*/
struct Entry {
std::chrono::microseconds timestamp;
Class log_class{};
Level log_level{};
const char* filename = nullptr;
unsigned int line_num = 0;
std::string function;
std::string message;
bool final_entry = false;
};
} // namespace Common::Log
-140
View File
@@ -1,140 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2+ or any later version
// Refer to the license.txt file included.
#pragma once
#include <deque>
#include <memory>
#include <type_traits>
#include "common/common_types.h"
namespace Common {
template <class Traits>
class LeastRecentlyUsedCache {
using ObjectType = typename Traits::ObjectType;
using TickType = typename Traits::TickType;
struct Item {
ObjectType obj;
TickType tick;
Item* next{};
Item* prev{};
};
public:
LeastRecentlyUsedCache() : first_item{}, last_item{} {}
~LeastRecentlyUsedCache() = default;
size_t Insert(ObjectType obj, TickType tick) {
const auto new_id = Build();
auto& item = item_pool[new_id];
item.obj = obj;
item.tick = tick;
Attach(item);
return new_id;
}
void Touch(size_t id, TickType tick) {
auto& item = item_pool[id];
if (item.tick >= tick) {
return;
}
item.tick = tick;
if (&item == last_item) {
return;
}
Detach(item);
Attach(item);
}
void Free(size_t id) {
auto& item = item_pool[id];
Detach(item);
item.prev = nullptr;
item.next = nullptr;
free_items.push_back(id);
}
template <typename Func>
void ForEachItemBelow(TickType tick, Func&& func) {
static constexpr bool RETURNS_BOOL =
std::is_same_v<std::invoke_result<Func, ObjectType>, bool>;
Item* iterator = first_item;
while (iterator) {
if (static_cast<s64>(tick) - static_cast<s64>(iterator->tick) < 0) {
return;
}
Item* next = iterator->next;
if constexpr (RETURNS_BOOL) {
if (func(iterator->obj)) {
return;
}
} else {
func(iterator->obj);
}
iterator = next;
}
}
private:
size_t Build() {
if (free_items.empty()) {
const size_t item_id = item_pool.size();
auto& item = item_pool.emplace_back();
item.next = nullptr;
item.prev = nullptr;
return item_id;
}
const size_t item_id = free_items.front();
free_items.pop_front();
auto& item = item_pool[item_id];
item.next = nullptr;
item.prev = nullptr;
return item_id;
}
void Attach(Item& item) {
if (!first_item) {
first_item = &item;
}
if (!last_item) {
last_item = &item;
} else {
item.prev = last_item;
last_item->next = &item;
item.next = nullptr;
last_item = &item;
}
}
void Detach(Item& item) {
if (item.prev) {
item.prev->next = item.next;
}
if (item.next) {
item.next->prev = item.prev;
}
if (&item == first_item) {
first_item = item.next;
if (first_item) {
first_item->prev = nullptr;
}
}
if (&item == last_item) {
last_item = item.prev;
if (last_item) {
last_item->next = nullptr;
}
}
}
std::deque<Item> item_pool;
std::deque<size_t> free_items;
Item* first_item{};
Item* last_item{};
};
} // namespace Common
+1 -5
View File
@@ -10,9 +10,7 @@
#include <cstring>
#endif
#include "common/error.h"
namespace Common {
#include "common/common_funcs.h"
std::string NativeErrorToString(int e) {
#ifdef _WIN32
@@ -52,5 +50,3 @@ std::string GetLastErrorMsg() {
return NativeErrorToString(errno);
#endif
}
} // namespace Common
-1
View File
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include <array>
#include <stdexcept>
#include <utility>
#include <vector>
+8 -5
View File
@@ -54,13 +54,15 @@ void LogSettings() {
log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue());
log_setting("Renderer_UseAsynchronousGpuEmulation",
values.use_asynchronous_gpu_emulation.GetValue());
log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
log_setting("Renderer_UseNvdecEmulation", values.use_nvdec_emulation.GetValue());
log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
log_setting("Renderer_UseGarbageCollection", values.use_caches_gc.GetValue());
log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
log_setting("Audio_OutputEngine", values.sink_id.GetValue());
log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
log_setting("Audio_OutputDevice", values.audio_device_id.GetValue());
log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue());
log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir));
@@ -69,9 +71,8 @@ void LogSettings() {
log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir));
log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir));
log_setting("Debugging_ProgramArgs", values.program_args.GetValue());
log_setting("Input_EnableMotion", values.motion_enabled.GetValue());
log_setting("Input_EnableVibration", values.vibration_enabled.GetValue());
log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue());
log_setting("Services_BCATBackend", values.bcat_backend.GetValue());
log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local.GetValue());
}
bool IsConfiguringGlobal() {
@@ -112,6 +113,7 @@ void RestoreGlobalState(bool is_powered_on) {
}
// Audio
values.enable_audio_stretching.SetGlobal(true);
values.volume.SetGlobal(true);
// Core
@@ -135,12 +137,13 @@ void RestoreGlobalState(bool is_powered_on) {
values.use_disk_shader_cache.SetGlobal(true);
values.gpu_accuracy.SetGlobal(true);
values.use_asynchronous_gpu_emulation.SetGlobal(true);
values.nvdec_emulation.SetGlobal(true);
values.use_nvdec_emulation.SetGlobal(true);
values.accelerate_astc.SetGlobal(true);
values.use_vsync.SetGlobal(true);
values.shader_backend.SetGlobal(true);
values.use_asynchronous_shaders.SetGlobal(true);
values.use_fast_gpu_time.SetGlobal(true);
values.use_caches_gc.SetGlobal(true);
values.bg_red.SetGlobal(true);
values.bg_green.SetGlobal(true);
values.bg_blue.SetGlobal(true);
+37 -170
View File
@@ -4,7 +4,6 @@
#pragma once
#include <algorithm>
#include <array>
#include <atomic>
#include <chrono>
@@ -16,6 +15,7 @@
#include "common/common_types.h"
#include "common/settings_input.h"
#include "input_common/udp/client.h"
namespace Settings {
@@ -47,12 +47,6 @@ enum class FullscreenMode : u32 {
Exclusive = 1,
};
enum class NvdecEmulation : u32 {
Off = 0,
CPU = 1,
GPU = 2,
};
/** The BasicSetting class is a simple resource manager. It defines a label and default value
* alongside the actual value of the setting for simpler and less-error prone use with frontend
* configurations. Setting a default value and label is required, though subclasses may deviate from
@@ -80,14 +74,14 @@ public:
*/
explicit BasicSetting(const Type& default_val, const std::string& name)
: default_value{default_val}, global{default_val}, label{name} {}
virtual ~BasicSetting() = default;
~BasicSetting() = default;
/**
* Returns a reference to the setting's value.
*
* @returns A reference to the setting
*/
[[nodiscard]] virtual const Type& GetValue() const {
[[nodiscard]] const Type& GetValue() const {
return global;
}
@@ -96,7 +90,7 @@ public:
*
* @param value The desired value
*/
virtual void SetValue(const Type& value) {
void SetValue(const Type& value) {
Type temp{value};
std::swap(global, temp);
}
@@ -126,7 +120,7 @@ public:
*
* @returns A reference to the setting
*/
virtual const Type& operator=(const Type& value) {
const Type& operator=(const Type& value) {
Type temp{value};
std::swap(global, temp);
return global;
@@ -137,7 +131,7 @@ public:
*
* @returns A reference to the setting
*/
explicit virtual operator const Type&() const {
explicit operator const Type&() const {
return global;
}
@@ -147,51 +141,6 @@ protected:
const std::string label{}; ///< The setting's label
};
/**
* BasicRangedSetting class is intended for use with quantifiable settings that need a more
* restrictive range than implicitly defined by its type. Implements a minimum and maximum that is
* simply used to sanitize SetValue and the assignment overload.
*/
template <typename Type>
class BasicRangedSetting : virtual public BasicSetting<Type> {
public:
/**
* Sets a default value, minimum value, maximum value, and label.
*
* @param default_val Intial value of the setting, and default value of the setting
* @param min_val Sets the minimum allowed value of the setting
* @param max_val Sets the maximum allowed value of the setting
* @param name Label for the setting
*/
explicit BasicRangedSetting(const Type& default_val, const Type& min_val, const Type& max_val,
const std::string& name)
: BasicSetting<Type>{default_val, name}, minimum{min_val}, maximum{max_val} {}
virtual ~BasicRangedSetting() = default;
/**
* Like BasicSetting's SetValue, except value is clamped to the range of the setting.
*
* @param value The desired value
*/
void SetValue(const Type& value) override {
this->global = std::clamp(value, minimum, maximum);
}
/**
* Like BasicSetting's assignment overload, except value is clamped to the range of the setting.
*
* @param value The desired value
* @returns A reference to the setting's value
*/
const Type& operator=(const Type& value) override {
this->global = std::clamp(value, minimum, maximum);
return this->global;
}
const Type minimum; ///< Minimum allowed value of the setting
const Type maximum; ///< Maximum allowed value of the setting
};
/**
* The Setting class is a slightly more complex version of the BasicSetting class. This adds a
* custom setting to switch to when a guest application specifically requires it. The effect is that
@@ -203,7 +152,7 @@ public:
* Like the BasicSetting, this requires setting a default value and label to use.
*/
template <typename Type>
class Setting : virtual public BasicSetting<Type> {
class Setting final : public BasicSetting<Type> {
public:
/**
* Sets a default value, label, and setting value.
@@ -213,7 +162,7 @@ public:
*/
explicit Setting(const Type& default_val, const std::string& name)
: BasicSetting<Type>(default_val, name) {}
virtual ~Setting() = default;
~Setting() = default;
/**
* Tells this setting to represent either the global or custom setting when other member
@@ -242,13 +191,7 @@ public:
*
* @returns The required value of the setting
*/
[[nodiscard]] virtual const Type& GetValue() const override {
if (use_global) {
return this->global;
}
return custom;
}
[[nodiscard]] virtual const Type& GetValue(bool need_global) const {
[[nodiscard]] const Type& GetValue(bool need_global = false) const {
if (use_global || need_global) {
return this->global;
}
@@ -260,7 +203,7 @@ public:
*
* @param value The new value
*/
void SetValue(const Type& value) override {
void SetValue(const Type& value) {
Type temp{value};
if (use_global) {
std::swap(this->global, temp);
@@ -276,7 +219,7 @@ public:
*
* @returns A reference to the current setting value
*/
const Type& operator=(const Type& value) override {
const Type& operator=(const Type& value) {
Type temp{value};
if (use_global) {
std::swap(this->global, temp);
@@ -291,87 +234,18 @@ public:
*
* @returns A reference to the current setting value
*/
virtual explicit operator const Type&() const override {
explicit operator const Type&() const {
if (use_global) {
return this->global;
}
return custom;
}
protected:
private:
bool use_global{true}; ///< The setting's global state
Type custom{}; ///< The custom value of the setting
};
/**
* RangedSetting is a Setting that implements a maximum and minimum value for its setting. Intended
* for use with quantifiable settings.
*/
template <typename Type>
class RangedSetting final : public BasicRangedSetting<Type>, public Setting<Type> {
public:
/**
* Sets a default value, minimum value, maximum value, and label.
*
* @param default_val Intial value of the setting, and default value of the setting
* @param min_val Sets the minimum allowed value of the setting
* @param max_val Sets the maximum allowed value of the setting
* @param name Label for the setting
*/
explicit RangedSetting(const Type& default_val, const Type& min_val, const Type& max_val,
const std::string& name)
: BasicSetting<Type>{default_val, name},
BasicRangedSetting<Type>{default_val, min_val, max_val, name}, Setting<Type>{default_val,
name} {}
virtual ~RangedSetting() = default;
// The following are needed to avoid a MSVC bug
// (source: https://stackoverflow.com/questions/469508)
[[nodiscard]] const Type& GetValue() const override {
return Setting<Type>::GetValue();
}
[[nodiscard]] const Type& GetValue(bool need_global) const override {
return Setting<Type>::GetValue(need_global);
}
explicit operator const Type&() const override {
if (this->use_global) {
return this->global;
}
return this->custom;
}
/**
* Like BasicSetting's SetValue, except value is clamped to the range of the setting. Sets the
* appropriate value depending on the global state.
*
* @param value The desired value
*/
void SetValue(const Type& value) override {
const Type temp = std::clamp(value, this->minimum, this->maximum);
if (this->use_global) {
this->global = temp;
}
this->custom = temp;
}
/**
* Like BasicSetting's assignment overload, except value is clamped to the range of the setting.
* Uses the appropriate value depending on the global state.
*
* @param value The desired value
* @returns A reference to the setting's value
*/
const Type& operator=(const Type& value) override {
const Type temp = std::clamp(value, this->minimum, this->maximum);
if (this->use_global) {
this->global = temp;
return this->global;
}
this->custom = temp;
return this->custom;
}
};
/**
* The InputSetting class allows for getting a reference to either the global or custom members.
* This is required as we cannot easily modify the values of user-defined types within containers
@@ -414,14 +288,14 @@ struct Values {
BasicSetting<std::string> audio_device_id{"auto", "output_device"};
BasicSetting<std::string> sink_id{"auto", "output_engine"};
BasicSetting<bool> audio_muted{false, "audio_muted"};
RangedSetting<u8> volume{100, 0, 100, "volume"};
Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
Setting<u8> volume{100, "volume"};
// Core
Setting<bool> use_multi_core{true, "use_multi_core"};
// Cpu
RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
CPUAccuracy::Unsafe, "cpu_accuracy"};
Setting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, "cpu_accuracy"};
// TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021
BasicSetting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"};
BasicSetting<bool> cpu_debug_mode{false, "cpu_debug_mode"};
@@ -443,8 +317,7 @@ struct Values {
Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"};
// Renderer
RangedSetting<RendererBackend> renderer_backend{
RendererBackend::OpenGL, RendererBackend::OpenGL, RendererBackend::Vulkan, "backend"};
Setting<RendererBackend> renderer_backend{RendererBackend::OpenGL, "backend"};
BasicSetting<bool> renderer_debug{false, "debug"};
BasicSetting<bool> renderer_shader_feedback{false, "shader_feedback"};
BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
@@ -455,30 +328,29 @@ struct Values {
Setting<u16> resolution_factor{1, "resolution_factor"};
// *nix platforms may have issues with the borderless windowed fullscreen mode.
// Default to exclusive fullscreen on these platforms for now.
RangedSetting<FullscreenMode> fullscreen_mode{
Setting<FullscreenMode> fullscreen_mode{
#ifdef _WIN32
FullscreenMode::Borderless,
#else
FullscreenMode::Exclusive,
#endif
FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"};
RangedSetting<int> aspect_ratio{0, 0, 3, "aspect_ratio"};
RangedSetting<int> max_anisotropy{0, 0, 4, "max_anisotropy"};
"fullscreen_mode"};
Setting<int> aspect_ratio{0, "aspect_ratio"};
Setting<int> max_anisotropy{0, "max_anisotropy"};
Setting<bool> use_speed_limit{true, "use_speed_limit"};
RangedSetting<u16> speed_limit{100, 0, 9999, "speed_limit"};
Setting<u16> speed_limit{100, "speed_limit"};
Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
RangedSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal,
GPUAccuracy::Extreme, "gpu_accuracy"};
Setting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, "gpu_accuracy"};
Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
Setting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"};
Setting<bool> accelerate_astc{true, "accelerate_astc"};
Setting<bool> use_vsync{true, "use_vsync"};
BasicRangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"};
BasicSetting<u16> fps_cap{1000, "fps_cap"};
BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"};
RangedSetting<ShaderBackend> shader_backend{ShaderBackend::GLASM, ShaderBackend::GLSL,
ShaderBackend::SPIRV, "shader_backend"};
Setting<ShaderBackend> shader_backend{ShaderBackend::GLASM, "shader_backend"};
Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
Setting<bool> use_caches_gc{false, "use_caches_gc"};
Setting<u8> bg_red{0, "bg_red"};
Setting<u8> bg_green{0, "bg_green"};
@@ -492,33 +364,27 @@ struct Values {
std::chrono::seconds custom_rtc_differential;
BasicSetting<s32> current_user{0, "current_user"};
RangedSetting<s32> language_index{1, 0, 17, "language_index"};
RangedSetting<s32> region_index{1, 0, 6, "region_index"};
RangedSetting<s32> time_zone_index{0, 0, 45, "time_zone_index"};
RangedSetting<s32> sound_index{1, 0, 2, "sound_index"};
Setting<s32> language_index{1, "language_index"};
Setting<s32> region_index{1, "region_index"};
Setting<s32> time_zone_index{0, "time_zone_index"};
Setting<s32> sound_index{1, "sound_index"};
// Controls
InputSetting<std::array<PlayerInput, 10>> players;
Setting<bool> use_docked_mode{true, "use_docked_mode"};
BasicSetting<bool> enable_raw_input{false, "enable_raw_input"};
Setting<bool> vibration_enabled{true, "vibration_enabled"};
Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
Setting<bool> motion_enabled{true, "motion_enabled"};
BasicSetting<std::string> motion_device{"engine:motion_emu,update_period:100,sensitivity:0.01",
"motion_device"};
BasicSetting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"};
BasicSetting<bool> pause_tas_on_load{true, "pause_tas_on_load"};
BasicSetting<bool> tas_enable{false, "tas_enable"};
BasicSetting<bool> tas_loop{false, "tas_loop"};
BasicSetting<bool> tas_swap_controllers{true, "tas_swap_controllers"};
BasicSetting<std::string> udp_input_servers{InputCommon::CemuhookUDP::DEFAULT_SRV,
"udp_input_servers"};
BasicSetting<bool> mouse_panning{false, "mouse_panning"};
BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
BasicSetting<u8> mouse_panning_sensitivity{10, "mouse_panning_sensitivity"};
BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
std::string mouse_device;
MouseButtonsRaw mouse_buttons;
@@ -567,8 +433,9 @@ struct Values {
BasicSetting<std::string> log_filter{"*:Info", "log_filter"};
BasicSetting<bool> use_dev_keys{false, "use_dev_keys"};
// Network
BasicSetting<std::string> network_interface{std::string(), "network_interface"};
// Services
BasicSetting<std::string> bcat_backend{"none", "bcat_backend"};
BasicSetting<bool> bcat_boxcat_local{false, "bcat_boxcat_local"};
// WebService
BasicSetting<bool> enable_telemetry{true, "enable_telemetry"};
+3 -3
View File
@@ -2,9 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <string>
#include "common/error.h"
#include "common/common_funcs.h"
#include "common/logging/log.h"
#include "common/thread.h"
#ifdef __APPLE__
@@ -23,6 +21,8 @@
#include <unistd.h>
#endif
#include <string>
#ifdef __FreeBSD__
#define cpu_set_t cpuset_t
#endif
+11 -26
View File
@@ -14,7 +14,7 @@
#include <utility>
namespace Common {
template <typename T, bool with_stop_token = false>
template <typename T>
class SPSCQueue {
public:
SPSCQueue() {
@@ -46,13 +46,15 @@ public:
ElementPtr* new_ptr = new ElementPtr();
write_ptr->next.store(new_ptr, std::memory_order_release);
write_ptr = new_ptr;
++size;
// cv_mutex must be held or else there will be a missed wakeup if the other thread is in the
// line before cv.wait
const size_t previous_size{size++};
// Acquire the mutex and then immediately release it as a fence.
// TODO(bunnei): This can be replaced with C++20 waitable atomics when properly supported.
// See discussion on https://github.com/yuzu-emu/yuzu/pull/3173 for details.
std::lock_guard lock{cv_mutex};
if (previous_size == 0) {
std::lock_guard lock{cv_mutex};
}
cv.notify_one();
}
@@ -84,7 +86,7 @@ public:
void Wait() {
if (Empty()) {
std::unique_lock lock{cv_mutex};
cv.wait(lock, [this] { return !Empty(); });
cv.wait(lock, [this]() { return !Empty(); });
}
}
@@ -95,19 +97,6 @@ public:
return t;
}
T PopWait(std::stop_token stop_token) {
if (Empty()) {
std::unique_lock lock{cv_mutex};
cv.wait(lock, stop_token, [this] { return !Empty(); });
}
if (stop_token.stop_requested()) {
return T{};
}
T t;
Pop(t);
return t;
}
// not thread-safe
void Clear() {
size.store(0);
@@ -136,13 +125,13 @@ private:
ElementPtr* read_ptr;
std::atomic_size_t size{0};
std::mutex cv_mutex;
std::conditional_t<with_stop_token, std::condition_variable_any, std::condition_variable> cv;
std::condition_variable cv;
};
// a simple thread-safe,
// single reader, multiple writer queue
template <typename T, bool with_stop_token = false>
template <typename T>
class MPSCQueue {
public:
[[nodiscard]] std::size_t Size() const {
@@ -179,17 +168,13 @@ public:
return spsc_queue.PopWait();
}
T PopWait(std::stop_token stop_token) {
return spsc_queue.PopWait(stop_token);
}
// not thread-safe
void Clear() {
spsc_queue.Clear();
}
private:
SPSCQueue<T, with_stop_token> spsc_queue;
SPSCQueue<T> spsc_queue;
std::mutex write_lock;
};
} // namespace Common
-7
View File
@@ -58,13 +58,6 @@ struct UUID {
uuid = INVALID_UUID;
}
[[nodiscard]] constexpr bool IsInvalid() const {
return uuid == INVALID_UUID;
}
[[nodiscard]] constexpr bool IsValid() const {
return !IsInvalid();
}
// TODO(ogniK): Properly generate a Nintendo ID
[[nodiscard]] constexpr u64 GetNintendoID() const {
return uuid[0];
+2 -2
View File
@@ -667,8 +667,8 @@ template <typename T>
// linear interpolation via float: 0.0=begin, 1.0=end
template <typename X>
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{})
Lerp(const X& begin, const X& end, const float t) {
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
const float t) {
return begin * (1.f - t) + end * t;
}
+1 -1
View File
@@ -6,7 +6,7 @@
#include <bitset>
#include <initializer_list>
#include <xbyak/xbyak.h>
#include <xbyak.h>
#include "common/assert.h"
namespace Common::X64 {
+1 -1
View File
@@ -5,7 +5,7 @@
#pragma once
#include <type_traits>
#include <xbyak/xbyak.h>
#include <xbyak.h>
#include "common/x64/xbyak_abi.h"
namespace Common::X64 {
+15 -8
View File
@@ -106,6 +106,8 @@ add_library(core STATIC
file_sys/vfs_concat.h
file_sys/vfs_layered.cpp
file_sys/vfs_layered.h
file_sys/vfs_libzip.cpp
file_sys/vfs_libzip.h
file_sys/vfs_offset.cpp
file_sys/vfs_offset.h
file_sys/vfs_real.cpp
@@ -216,7 +218,6 @@ add_library(core STATIC
hle/kernel/k_session.h
hle/kernel/k_shared_memory.cpp
hle/kernel/k_shared_memory.h
hle/kernel/k_shared_memory_info.h
hle/kernel/k_slab_heap.h
hle/kernel/k_spin_lock.cpp
hle/kernel/k_spin_lock.h
@@ -262,8 +263,6 @@ add_library(core STATIC
hle/service/acc/acc_u0.h
hle/service/acc/acc_u1.cpp
hle/service/acc/acc_u1.h
hle/service/acc/async_context.cpp
hle/service/acc/async_context.h
hle/service/acc/errors.h
hle/service/acc/profile_manager.cpp
hle/service/acc/profile_manager.h
@@ -453,8 +452,6 @@ add_library(core STATIC
hle/service/nfp/nfp.h
hle/service/nfp/nfp_user.cpp
hle/service/nfp/nfp_user.h
hle/service/ngct/ngct.cpp
hle/service/ngct/ngct.h
hle/service/nifm/nifm.cpp
hle/service/nifm/nifm.h
hle/service/nim/nim.cpp
@@ -639,8 +636,6 @@ add_library(core STATIC
memory.h
network/network.cpp
network/network.h
network/network_interface.cpp
network/network_interface.h
network/sockets.h
perf_stats.cpp
perf_stats.h
@@ -652,6 +647,13 @@ add_library(core STATIC
tools/freezer.h
)
if (YUZU_ENABLE_BOXCAT)
target_sources(core PRIVATE
hle/service/bcat/backend/boxcat.cpp
hle/service/bcat/backend/boxcat.h
)
endif()
if (MSVC)
target_compile_options(core PRIVATE
/we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
@@ -682,7 +684,12 @@ endif()
create_target_directory_groups(core)
target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus zip)
if (YUZU_ENABLE_BOXCAT)
target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT)
target_link_libraries(core PRIVATE httplib nlohmann_json::nlohmann_json)
endif()
if (ENABLE_WEB_SERVICE)
target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE)
+10 -41
View File
@@ -4,7 +4,6 @@
#include <array>
#include <atomic>
#include <exception>
#include <memory>
#include <utility>
@@ -83,14 +82,10 @@ FileSys::StorageId GetStorageIdForFrontendSlot(
}
}
void KProcessDeleter(Kernel::KProcess* process) {
process->Destroy();
}
using KProcessPtr = std::unique_ptr<Kernel::KProcess, decltype(&KProcessDeleter)>;
} // Anonymous namespace
/*static*/ System System::s_instance;
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
const std::string& path) {
// To account for split 00+01+etc files.
@@ -239,8 +234,8 @@ struct System::Impl {
}
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
main_process = KProcessPtr{Kernel::KProcess::Create(system.Kernel()), KProcessDeleter};
ASSERT(Kernel::KProcess::Initialize(main_process.get(), system, "main",
auto main_process = Kernel::KProcess::Create(system.Kernel());
ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
Kernel::KProcess::ProcessType::Userland)
.IsSuccess());
main_process->Open();
@@ -253,7 +248,7 @@ struct System::Impl {
static_cast<u32>(load_result));
}
AddGlueRegistrationForProcess(*app_loader, *main_process);
kernel.MakeCurrentProcess(main_process.get());
kernel.MakeCurrentProcess(main_process);
kernel.InitializeCores();
// Initialize cheat engine
@@ -305,6 +300,10 @@ struct System::Impl {
is_powered_on = false;
exit_lock = false;
if (gpu_core) {
gpu_core->ShutDown();
}
services.reset();
service_manager.reset();
cheat_engine.reset();
@@ -313,13 +312,11 @@ struct System::Impl {
time_manager.Shutdown();
core_timing.Shutdown();
app_loader.reset();
perf_stats.reset();
gpu_core.reset();
perf_stats.reset();
kernel.Shutdown();
memory.Reset();
applet_manager.ClearAll();
// TODO: The main process should be freed based on KAutoObject ref counting.
main_process.reset();
LOG_DEBUG(Core, "Shutdown OK");
}
@@ -378,7 +375,6 @@ struct System::Impl {
std::unique_ptr<Tegra::GPU> gpu_core;
std::unique_ptr<Hardware::InterruptManager> interrupt_manager;
std::unique_ptr<Core::DeviceMemory> device_memory;
KProcessPtr main_process{nullptr, KProcessDeleter};
Core::Memory::Memory memory;
CpuManager cpu_manager;
std::atomic_bool is_powered_on{};
@@ -421,7 +417,6 @@ struct System::Impl {
bool is_async_gpu{};
ExecuteProgramCallback execute_program_callback;
ExitCallback exit_callback;
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{};
@@ -430,20 +425,6 @@ struct System::Impl {
System::System() : impl{std::make_unique<Impl>(*this)} {}
System::~System() = default;
System& System::GetInstance() {
if (!s_instance) {
throw std::runtime_error("Using System instance before its initialization");
}
return *s_instance;
}
void System::InitializeGlobalInstance() {
if (s_instance) {
throw std::runtime_error("Reinitializing Global System instance.");
}
s_instance = std::unique_ptr<System>(new System);
}
CpuManager& System::GetCpuManager() {
return impl->cpu_manager;
}
@@ -799,18 +780,6 @@ void System::ExecuteProgram(std::size_t program_index) {
}
}
void System::RegisterExitCallback(ExitCallback&& callback) {
impl->exit_callback = std::move(callback);
}
void System::Exit() {
if (impl->exit_callback) {
impl->exit_callback();
} else {
LOG_CRITICAL(Core, "exit_callback must be initialized by the frontend");
}
}
void System::ApplySettings() {
if (IsPoweredOn()) {
Renderer().RefreshBaseSettings();
+4 -16
View File
@@ -120,9 +120,9 @@ public:
* Gets the instance of the System singleton class.
* @returns Reference to the instance of the System singleton class.
*/
[[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance();
static void InitializeGlobalInstance();
[[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance() {
return s_instance;
}
/// Enumeration representing the return values of the System Initialize and Load process.
enum class ResultStatus : u32 {
@@ -387,18 +387,6 @@ public:
*/
void ExecuteProgram(std::size_t program_index);
/// Type used for the frontend to designate a callback for System to exit the application.
using ExitCallback = std::function<void()>;
/**
* Registers a callback from the frontend for System to exit the application.
* @param callback Callback from the frontend to exit the application.
*/
void RegisterExitCallback(ExitCallback&& callback);
/// Instructs the frontend to exit the application.
void Exit();
/// Applies any changes to settings to this core instance.
void ApplySettings();
@@ -408,7 +396,7 @@ private:
struct Impl;
std::unique_ptr<Impl> impl;
inline static std::unique_ptr<System> s_instance{};
static System s_instance;
};
} // namespace Core
+15 -10
View File
@@ -21,25 +21,34 @@ namespace Core {
CpuManager::CpuManager(System& system_) : system{system_} {}
CpuManager::~CpuManager() = default;
void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager,
std::size_t core) {
cpu_manager.RunThread(stop_token, core);
void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) {
cpu_manager.RunThread(core);
}
void CpuManager::Initialize() {
running_mode = true;
if (is_multicore) {
for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {
core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core);
core_data[core].host_thread =
std::make_unique<std::thread>(ThreadStart, std::ref(*this), core);
}
} else {
core_data[0].host_thread = std::jthread(ThreadStart, std::ref(*this), 0);
core_data[0].host_thread = std::make_unique<std::thread>(ThreadStart, std::ref(*this), 0);
}
}
void CpuManager::Shutdown() {
running_mode = false;
Pause(false);
if (is_multicore) {
for (auto& data : core_data) {
data.host_thread->join();
data.host_thread.reset();
}
} else {
core_data[0].host_thread->join();
core_data[0].host_thread.reset();
}
}
std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() {
@@ -308,7 +317,7 @@ void CpuManager::Pause(bool paused) {
}
}
void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) {
void CpuManager::RunThread(std::size_t core) {
/// Initialization
system.RegisterCoreThread(core);
std::string name;
@@ -352,10 +361,6 @@ void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) {
return;
}
if (stop_token.stop_requested()) {
break;
}
auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
data.is_running = true;
Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext());
+3 -3
View File
@@ -78,9 +78,9 @@ private:
void SingleCoreRunSuspendThread();
void SingleCorePause(bool paused);
static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core);
static void ThreadStart(CpuManager& cpu_manager, std::size_t core);
void RunThread(std::stop_token stop_token, std::size_t core);
void RunThread(std::size_t core);
struct CoreData {
std::shared_ptr<Common::Fiber> host_context;
@@ -89,7 +89,7 @@ private:
std::atomic<bool> is_running;
std::atomic<bool> is_paused;
std::atomic<bool> initialized;
std::jthread host_thread;
std::unique_ptr<std::thread> host_thread;
};
std::atomic<bool> running_mode{};
-1
View File
@@ -5,7 +5,6 @@
#pragma once
#include <array>
#include <string>
#include <vector>
#include "common/common_funcs.h"
+1 -1
View File
@@ -77,7 +77,7 @@ void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address
aci_header.title_id = title_id;
aci_file_access.permissions = filesystem_permissions;
npdm_header.system_resource_size = system_resource_size;
aci_kernel_capabilities = std::move(capabilities);
aci_kernel_capabilities = std ::move(capabilities);
}
bool ProgramMetadata::Is64BitProgram() const {
-4
View File
@@ -273,10 +273,6 @@ VirtualFile VfsDirectory::GetFile(std::string_view name) const {
return iter == files.end() ? nullptr : *iter;
}
FileTimeStampRaw VfsDirectory::GetFileTimeStamp([[maybe_unused]] std::string_view path) const {
return {};
}
VirtualDir VfsDirectory::GetSubdirectory(std::string_view name) const {
const auto& subs = GetSubdirectories();
const auto iter = std::find_if(subs.begin(), subs.end(),
-3
View File
@@ -199,9 +199,6 @@ public:
// file with name.
virtual VirtualFile GetFile(std::string_view name) const;
// Returns a struct containing the file's timestamp.
virtual FileTimeStampRaw GetFileTimeStamp(std::string_view path) const;
// Returns a vector containing all of the subdirectories in this directory.
virtual std::vector<VirtualDir> GetSubdirectories() const = 0;
// Returns the directory with name matching name. Returns nullptr if directory dosen't have a
+88
View File
@@ -0,0 +1,88 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <string>
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
#include <zip.h>
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "common/fs/path_util.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_libzip.h"
#include "core/file_sys/vfs_vector.h"
namespace FileSys {
VirtualDir ExtractZIP(VirtualFile file) {
zip_error_t error{};
const auto data = file->ReadAllBytes();
std::unique_ptr<zip_source_t, decltype(&zip_source_close)> src{
zip_source_buffer_create(data.data(), data.size(), 0, &error), zip_source_close};
if (src == nullptr)
return nullptr;
std::unique_ptr<zip_t, decltype(&zip_close)> zip{zip_open_from_source(src.get(), 0, &error),
zip_close};
if (zip == nullptr)
return nullptr;
std::shared_ptr<VectorVfsDirectory> out = std::make_shared<VectorVfsDirectory>();
const auto num_entries = static_cast<std::size_t>(zip_get_num_entries(zip.get(), 0));
zip_stat_t stat{};
zip_stat_init(&stat);
for (std::size_t i = 0; i < num_entries; ++i) {
const auto stat_res = zip_stat_index(zip.get(), i, 0, &stat);
if (stat_res == -1)
return nullptr;
const std::string name(stat.name);
if (name.empty())
continue;
if (name.back() != '/') {
std::unique_ptr<zip_file_t, decltype(&zip_fclose)> file2{
zip_fopen_index(zip.get(), i, 0), zip_fclose};
std::vector<u8> buf(stat.size);
if (zip_fread(file2.get(), buf.data(), buf.size()) != s64(buf.size()))
return nullptr;
const auto parts = Common::FS::SplitPathComponents(stat.name);
const auto new_file = std::make_shared<VectorVfsFile>(buf, parts.back());
std::shared_ptr<VectorVfsDirectory> dtrv = out;
for (std::size_t j = 0; j < parts.size() - 1; ++j) {
if (dtrv == nullptr)
return nullptr;
const auto subdir = dtrv->GetSubdirectory(parts[j]);
if (subdir == nullptr) {
const auto temp = std::make_shared<VectorVfsDirectory>(
std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, parts[j]);
dtrv->AddDirectory(temp);
dtrv = temp;
} else {
dtrv = std::dynamic_pointer_cast<VectorVfsDirectory>(subdir);
}
}
if (dtrv == nullptr)
return nullptr;
dtrv->AddFile(new_file);
}
}
return out;
}
} // namespace FileSys
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/file_sys/vfs_types.h"
namespace FileSys {
VirtualDir ExtractZIP(VirtualFile zip);
} // namespace FileSys
-29
View File
@@ -13,13 +13,6 @@
#include "common/logging/log.h"
#include "core/file_sys/vfs_real.h"
// For FileTimeStampRaw
#include <sys/stat.h>
#ifdef _MSC_VER
#define stat _stat64
#endif
namespace FileSys {
namespace FS = Common::FS;
@@ -399,28 +392,6 @@ std::vector<VirtualFile> RealVfsDirectory::GetFiles() const {
return IterateEntries<RealVfsFile, VfsFile>();
}
FileTimeStampRaw RealVfsDirectory::GetFileTimeStamp(std::string_view path_) const {
const auto full_path = FS::SanitizePath(path + '/' + std::string(path_));
const auto fs_path = std::filesystem::path{FS::ToU8String(full_path)};
struct stat file_status;
#ifdef _WIN32
const auto stat_result = _wstat64(fs_path.c_str(), &file_status);
#else
const auto stat_result = stat(fs_path.c_str(), &file_status);
#endif
if (stat_result != 0) {
return {};
}
return {
.created{static_cast<u64>(file_status.st_ctime)},
.accessed{static_cast<u64>(file_status.st_atime)},
.modified{static_cast<u64>(file_status.st_mtime)},
};
}
std::vector<VirtualDir> RealVfsDirectory::GetSubdirectories() const {
return IterateEntries<RealVfsDirectory, VfsDirectory>();
}
-1
View File
@@ -86,7 +86,6 @@ public:
VirtualDir CreateDirectoryRelative(std::string_view relative_path) override;
bool DeleteSubdirectoryRecursive(std::string_view name) override;
std::vector<VirtualFile> GetFiles() const override;
FileTimeStampRaw GetFileTimeStamp(std::string_view path) const override;
std::vector<VirtualDir> GetSubdirectories() const override;
bool IsWritable() const override;
bool IsReadable() const override;
-9
View File
@@ -6,8 +6,6 @@
#include <memory>
#include "common/common_types.h"
namespace FileSys {
class VfsDirectory;
@@ -20,11 +18,4 @@ using VirtualDir = std::shared_ptr<VfsDirectory>;
using VirtualFile = std::shared_ptr<VfsFile>;
using VirtualFilesystem = std::shared_ptr<VfsFilesystem>;
struct FileTimeStampRaw {
u64 created{};
u64 accessed{};
u64 modified{};
u64 padding{};
};
} // namespace FileSys
+1 -2
View File
@@ -13,8 +13,7 @@ ProfileSelectApplet::~ProfileSelectApplet() = default;
void DefaultProfileSelectApplet::SelectProfile(
std::function<void(std::optional<Common::UUID>)> callback) const {
Service::Account::ProfileManager manager;
callback(manager.GetUser(Settings::values.current_user.GetValue())
.value_or(Common::UUID{Common::INVALID_UUID}));
callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{}));
LOG_INFO(Service_ACC, "called, selecting current user instead of prompting...");
}
+5 -12
View File
@@ -28,20 +28,13 @@ constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 12.1.0-1.0";
// Atmosphere version constants.
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 1;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 0;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 0;
constexpr u32 AtmosphereTargetFirmwareWithRevision(u8 major, u8 minor, u8 micro, u8 rev) {
return u32{major} << 24 | u32{minor} << 16 | u32{micro} << 8 | u32{rev};
}
constexpr u32 AtmosphereTargetFirmware(u8 major, u8 minor, u8 micro) {
return AtmosphereTargetFirmwareWithRevision(major, minor, micro, 0);
}
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 0;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 19;
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 5;
constexpr u32 GetTargetFirmware() {
return AtmosphereTargetFirmware(HOS_VERSION_MAJOR, HOS_VERSION_MINOR, HOS_VERSION_MICRO);
return u32{HOS_VERSION_MAJOR} << 24 | u32{HOS_VERSION_MINOR} << 16 |
u32{HOS_VERSION_MICRO} << 8 | 0U;
}
} // namespace HLE::ApiVersion
+3
View File
@@ -4,14 +4,17 @@
#pragma once
#include <array>
#include <cstring>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
#include "common/assert.h"
#include "common/common_types.h"
#include "core/hle/ipc.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_session.h"
-1
View File
@@ -15,7 +15,6 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h"
+1 -1
View File
@@ -17,6 +17,7 @@
#include "common/concepts.h"
#include "common/swap.h"
#include "core/hle/ipc.h"
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/svc_common.h"
union ResultCode;
@@ -37,7 +38,6 @@ namespace Kernel {
class Domain;
class HLERequestContext;
class KAutoObject;
class KernelCore;
class KHandleTable;
class KProcess;
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include "core/hle/kernel/k_auto_object_container.h"
namespace Kernel {
+1 -1
View File
@@ -7,7 +7,7 @@
namespace Kernel {
KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {}
KHandleTable::~KHandleTable() = default;
KHandleTable ::~KHandleTable() = default;
ResultCode KHandleTable::Finalize() {
// Get the table and clear our record of it.
+17 -10
View File
@@ -22,10 +22,12 @@ class KThread;
template <typename T>
concept KPriorityQueueAffinityMask = !std::is_reference_v<T> && requires(T & t) {
{ t.GetAffinityMask() } -> Common::ConvertibleTo<u64>;
{ t.GetAffinityMask() }
->Common::ConvertibleTo<u64>;
{t.SetAffinityMask(0)};
{ t.GetAffinity(0) } -> std::same_as<bool>;
{ t.GetAffinity(0) }
->std::same_as<bool>;
{t.SetAffinity(0, false)};
{t.SetAll()};
};
@@ -36,20 +38,25 @@ concept KPriorityQueueMember = !std::is_reference_v<T> && requires(T & t) {
{(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<T*>;
{ (typename T::QueueEntry()).GetPrev() } -> std::same_as<T*>;
{ t.GetPriorityQueueEntry(0) } -> std::same_as<typename T::QueueEntry&>;
{ (typename T::QueueEntry()).GetNext() }
->std::same_as<T*>;
{ (typename T::QueueEntry()).GetPrev() }
->std::same_as<T*>;
{ t.GetPriorityQueueEntry(0) }
->std::same_as<typename T::QueueEntry&>;
{t.GetAffinityMask()};
{ std::remove_cvref_t<decltype(t.GetAffinityMask())>() } -> KPriorityQueueAffinityMask;
{ std::remove_cvref_t<decltype(t.GetAffinityMask())>() }
->KPriorityQueueAffinityMask;
{ t.GetActiveCore() } -> Common::ConvertibleTo<s32>;
{ t.GetPriority() } -> Common::ConvertibleTo<s32>;
{ t.GetActiveCore() }
->Common::ConvertibleTo<s32>;
{ t.GetPriority() }
->Common::ConvertibleTo<s32>;
};
template <typename Member, size_t NumCores_, int LowestPriority, int HighestPriority>
requires KPriorityQueueMember<Member>
class KPriorityQueue {
requires KPriorityQueueMember<Member> class KPriorityQueue {
public:
using AffinityMaskType = std::remove_cv_t<
std::remove_reference_t<decltype(std::declval<Member>().GetAffinityMask())>>;
+3 -51
View File
@@ -23,7 +23,6 @@
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_shared_memory_info.h"
#include "core/hle/kernel/k_slab_heap.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
@@ -255,26 +254,10 @@ ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAdd
// Lock ourselves, to prevent concurrent access.
KScopedLightLock lk(state_lock);
// Try to find an existing info for the memory.
KSharedMemoryInfo* shemen_info = nullptr;
const auto iter = std::find_if(
shared_memory_list.begin(), shared_memory_list.end(),
[shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
if (iter != shared_memory_list.end()) {
shemen_info = *iter;
}
// TODO(bunnei): Manage KSharedMemoryInfo list here.
if (shemen_info == nullptr) {
shemen_info = KSharedMemoryInfo::Allocate(kernel);
R_UNLESS(shemen_info != nullptr, ResultOutOfMemory);
shemen_info->Initialize(shmem);
shared_memory_list.push_back(shemen_info);
}
// Open a reference to the shared memory and its info.
// Open a reference to the shared memory.
shmem->Open();
shemen_info->Open();
return ResultSuccess;
}
@@ -284,20 +267,7 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a
// Lock ourselves, to prevent concurrent access.
KScopedLightLock lk(state_lock);
KSharedMemoryInfo* shemen_info = nullptr;
const auto iter = std::find_if(
shared_memory_list.begin(), shared_memory_list.end(),
[shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
if (iter != shared_memory_list.end()) {
shemen_info = *iter;
}
ASSERT(shemen_info != nullptr);
if (shemen_info->Close()) {
shared_memory_list.erase(iter);
KSharedMemoryInfo::Free(kernel, shemen_info);
}
// TODO(bunnei): Manage KSharedMemoryInfo list here.
// Close a reference to the shared memory.
shmem->Close();
@@ -442,24 +412,6 @@ void KProcess::Finalize() {
// Finalize the handle table and close any open handles.
handle_table.Finalize();
// Free all shared memory infos.
{
auto it = shared_memory_list.begin();
while (it != shared_memory_list.end()) {
KSharedMemoryInfo* info = *it;
KSharedMemory* shmem = info->GetSharedMemory();
while (!info->Close()) {
shmem->Close();
}
shmem->Close();
it = shared_memory_list.erase(it);
KSharedMemoryInfo::Free(kernel, info);
}
}
// Perform inherited finalization.
KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize();
}
-4
View File
@@ -34,7 +34,6 @@ class KernelCore;
class KPageTable;
class KResourceLimit;
class KThread;
class KSharedMemoryInfo;
class TLSPage;
struct CodeSet;
@@ -449,9 +448,6 @@ private:
/// List of threads that are running with this process as their owner.
std::list<const KThread*> thread_list;
/// List of shared memory that are running with this process as their owner.
std::list<KSharedMemoryInfo*> shared_memory_list;
/// Address of the top of the main thread's stack
VAddr main_thread_stack_top{};
+1 -1
View File
@@ -197,7 +197,7 @@ private:
class [[nodiscard]] KScopedSchedulerLock : KScopedLock<GlobalSchedulerContext::LockType> {
public:
explicit KScopedSchedulerLock(KernelCore& kernel);
explicit KScopedSchedulerLock(KernelCore & kernel);
~KScopedSchedulerLock();
};
+8 -7
View File
@@ -13,18 +13,19 @@ namespace Kernel {
template <typename T>
concept KLockable = !std::is_reference_v<T> && requires(T & t) {
{ t.Lock() } -> std::same_as<void>;
{ t.Unlock() } -> std::same_as<void>;
{ t.Lock() }
->std::same_as<void>;
{ t.Unlock() }
->std::same_as<void>;
};
template <typename T>
requires KLockable<T>
class [[nodiscard]] KScopedLock {
requires KLockable<T> class [[nodiscard]] KScopedLock {
public:
explicit KScopedLock(T* l) : lock_ptr(l) {
explicit KScopedLock(T * l) : lock_ptr(l) {
this->lock_ptr->Lock();
}
explicit KScopedLock(T& l) : KScopedLock(std::addressof(l)) {}
explicit KScopedLock(T & l) : KScopedLock(std::addressof(l)) {}
~KScopedLock() {
this->lock_ptr->Unlock();
@@ -33,7 +34,7 @@ public:
KScopedLock(const KScopedLock&) = delete;
KScopedLock& operator=(const KScopedLock&) = delete;
KScopedLock(KScopedLock&&) = delete;
KScopedLock(KScopedLock &&) = delete;
KScopedLock& operator=(KScopedLock&&) = delete;
private:
@@ -17,7 +17,7 @@ namespace Kernel {
class [[nodiscard]] KScopedSchedulerLockAndSleep {
public:
explicit KScopedSchedulerLockAndSleep(KernelCore& kernel_, KThread* t, s64 timeout)
explicit KScopedSchedulerLockAndSleep(KernelCore & kernel_, KThread * t, s64 timeout)
: kernel(kernel_), thread(t), timeout_tick(timeout) {
// Lock the scheduler.
kernel.GlobalSchedulerContext().scheduler_lock.Lock();
@@ -1,46 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <string>
#include <boost/intrusive/list.hpp>
#include "common/assert.h"
#include "core/hle/kernel/slab_helpers.h"
namespace Kernel {
class KSharedMemory;
class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>,
public boost::intrusive::list_base_hook<> {
public:
explicit KSharedMemoryInfo() = default;
constexpr void Initialize(KSharedMemory* shmem) {
shared_memory = shmem;
}
constexpr KSharedMemory* GetSharedMemory() const {
return shared_memory;
}
constexpr void Open() {
++reference_count;
}
constexpr bool Close() {
return (--reference_count) == 0;
}
private:
KSharedMemory* shared_memory{};
size_t reference_count{};
};
} // namespace Kernel
+10 -13
View File
@@ -267,23 +267,20 @@ struct KernelCore::Impl {
}
}
static inline thread_local u32 host_thread_id = UINT32_MAX;
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
u32 GetHostThreadId(std::size_t core_id) {
if (host_thread_id == UINT32_MAX) {
// The first four slots are reserved for CPU core threads
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
host_thread_id = static_cast<u32>(core_id);
/// Creates a new host thread ID, should only be called by GetHostThreadId
u32 AllocateHostThreadId(std::optional<std::size_t> core_id) {
if (core_id) {
// The first for slots are reserved for CPU core threads
ASSERT(*core_id < Core::Hardware::NUM_CPU_CORES);
return static_cast<u32>(*core_id);
} else {
return next_host_thread_id++;
}
return host_thread_id;
}
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
u32 GetHostThreadId() {
if (host_thread_id == UINT32_MAX) {
host_thread_id = next_host_thread_id++;
}
u32 GetHostThreadId(std::optional<std::size_t> core_id = std::nullopt) {
const thread_local auto host_thread_id{AllocateHostThreadId(core_id)};
return host_thread_id;
}
-5
View File
@@ -5,7 +5,6 @@
#pragma once
#include <array>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
@@ -49,7 +48,6 @@ class KScheduler;
class KServerSession;
class KSession;
class KSharedMemory;
class KSharedMemoryInfo;
class KThread;
class KTransferMemory;
class KWritableEvent;
@@ -310,8 +308,6 @@ public:
return slab_heap_container->session;
} else if constexpr (std::is_same_v<T, KSharedMemory>) {
return slab_heap_container->shared_memory;
} else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) {
return slab_heap_container->shared_memory_info;
} else if constexpr (std::is_same_v<T, KThread>) {
return slab_heap_container->thread;
} else if constexpr (std::is_same_v<T, KTransferMemory>) {
@@ -365,7 +361,6 @@ private:
KSlabHeap<KResourceLimit> resource_limit;
KSlabHeap<KSession> session;
KSlabHeap<KSharedMemory> shared_memory;
KSlabHeap<KSharedMemoryInfo> shared_memory_info;
KSlabHeap<KThread> thread;
KSlabHeap<KTransferMemory> transfer_memory;
KSlabHeap<KWritableEvent> writeable_event;
+7 -9
View File
@@ -320,19 +320,17 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
auto& kernel = system.Kernel();
KScopedAutoObject session =
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
auto thread = kernel.CurrentScheduler()->GetCurrentThread();
{
KScopedSchedulerLock lock(kernel);
thread->SetState(ThreadState::Waiting);
thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
{
KScopedAutoObject session =
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
session->SendSyncRequest(thread, system.Memory(), system.CoreTiming());
}
session->SendSyncRequest(thread, system.Memory(), system.CoreTiming());
}
KSynchronizationObject* dummy{};
@@ -1080,8 +1078,8 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand
for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) {
if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetCurrentThread()) {
current = true;
break;
}
break;
}
// If the thread is current, retry until it isn't.
+21 -48
View File
@@ -23,7 +23,6 @@
#include "core/hle/service/acc/acc_su.h"
#include "core/hle/service/acc/acc_u0.h"
#include "core/hle/service/acc/acc_u1.h"
#include "core/hle/service/acc/async_context.h"
#include "core/hle/service/acc/errors.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/glue/arp.h"
@@ -455,6 +454,22 @@ public:
: IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} {}
};
class IAsyncContext final : public ServiceFramework<IAsyncContext> {
public:
explicit IAsyncContext(Core::System& system_) : ServiceFramework{system_, "IAsyncContext"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetSystemEvent"},
{1, nullptr, "Cancel"},
{2, nullptr, "HasDone"},
{3, nullptr, "GetResult"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ISessionObject final : public ServiceFramework<ISessionObject> {
public:
explicit ISessionObject(Core::System& system_, Common::UUID)
@@ -489,44 +504,16 @@ public:
}
};
class EnsureTokenIdCacheAsyncInterface final : public IAsyncContext {
public:
explicit EnsureTokenIdCacheAsyncInterface(Core::System& system_) : IAsyncContext{system_} {
MarkComplete();
}
~EnsureTokenIdCacheAsyncInterface() = default;
void LoadIdTokenCache(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
protected:
bool IsComplete() const override {
return true;
}
void Cancel() override {}
ResultCode GetResult() const override {
return ResultSuccess;
}
};
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
public:
explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_)
: ServiceFramework{system_, "IManagerForApplication"},
ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)},
user_id{user_id_} {
: ServiceFramework{system_, "IManagerForApplication"}, user_id{user_id_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
{1, &IManagerForApplication::GetAccountId, "GetAccountId"},
{2, &IManagerForApplication::EnsureIdTokenCacheAsync, "EnsureIdTokenCacheAsync"},
{3, &IManagerForApplication::LoadIdTokenCache, "LoadIdTokenCache"},
{2, nullptr, "EnsureIdTokenCacheAsync"},
{3, nullptr, "LoadIdTokenCache"},
{130, &IManagerForApplication::GetNintendoAccountUserResourceCacheForApplication, "GetNintendoAccountUserResourceCacheForApplication"},
{150, nullptr, "CreateAuthorizationRequest"},
{160, &IManagerForApplication::StoreOpenContext, "StoreOpenContext"},
@@ -553,20 +540,6 @@ private:
rb.PushRaw<u64>(user_id.GetNintendoID());
}
void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface(ensure_token_id);
}
void LoadIdTokenCache(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
ensure_token_id->LoadIdTokenCache(ctx);
}
void GetNintendoAccountUserResourceCacheForApplication(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
@@ -589,7 +562,6 @@ private:
rb.Push(ResultSuccess);
}
std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{};
Common::UUID user_id{Common::INVALID_UUID};
};
@@ -929,7 +901,8 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
}
const auto user_list = profile_manager->GetAllUsers();
if (std::ranges::all_of(user_list, [](const auto& user) { return user.IsInvalid(); })) {
if (std::all_of(user_list.begin(), user_list.end(),
[](const auto& user) { return user.uuid == Common::INVALID_UUID; })) {
rb.Push(ResultUnknown); // TODO(ogniK): Find the correct error code
rb.PushRaw<u128>(Common::INVALID_UUID);
return;
@@ -1,71 +0,0 @@
// Copyright 2021 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/acc/async_context.h"
namespace Service::Account {
IAsyncContext::IAsyncContext(Core::System& system_)
: ServiceFramework{system_, "IAsyncContext"}, service_context{system_, "IAsyncContext"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IAsyncContext::GetSystemEvent, "GetSystemEvent"},
{1, &IAsyncContext::Cancel, "Cancel"},
{2, &IAsyncContext::HasDone, "HasDone"},
{3, &IAsyncContext::GetResult, "GetResult"},
};
// clang-format on
RegisterHandlers(functions);
completion_event = service_context.CreateEvent("IAsyncContext:CompletionEvent");
}
IAsyncContext::~IAsyncContext() {
service_context.CloseEvent(completion_event);
}
void IAsyncContext::GetSystemEvent(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(completion_event->GetReadableEvent());
}
void IAsyncContext::Cancel(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called");
Cancel();
MarkComplete();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IAsyncContext::HasDone(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called");
is_complete.store(IsComplete());
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(is_complete.load());
}
void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(GetResult());
}
void IAsyncContext::MarkComplete() {
is_complete.store(true);
completion_event->GetWritableEvent().Signal();
}
} // namespace Service::Account

Some files were not shown because too many files have changed in this diff Show More