Compare commits
182 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60b184377e | ||
|
|
7341257fc4 | ||
|
|
d011f89f15 | ||
|
|
de1ef273b3 | ||
|
|
c2522f3e43 | ||
|
|
d8b83aa8f5 | ||
|
|
65010607b7 | ||
|
|
3c378a31b5 | ||
|
|
74d5c0ed2f | ||
|
|
6f0360690b | ||
|
|
4b9504028d | ||
|
|
55c0dd1cb3 | ||
|
|
7a27b7f3a3 | ||
|
|
b73f678ee8 | ||
|
|
024c84d2db | ||
|
|
0e2ded049d | ||
|
|
670a7f51e8 | ||
|
|
b1a1bd12ca | ||
|
|
bba54e1880 | ||
|
|
1585981eec | ||
|
|
1beaebe666 | ||
|
|
3c8cd62b0d | ||
|
|
33441fa728 | ||
|
|
988e42a3f5 | ||
|
|
5dec81fcbd | ||
|
|
16c0373adc | ||
|
|
c4e7ec7a99 | ||
|
|
9de860a419 | ||
|
|
47b97b9577 | ||
|
|
551c61bf27 | ||
|
|
ab9ddab0a2 | ||
|
|
9c065c013e | ||
|
|
ecc8ccc9d3 | ||
|
|
6ec6cb50dd | ||
|
|
8b329ddcc9 | ||
|
|
d4e1633fb7 | ||
|
|
e8baf07136 | ||
|
|
290bc20e79 | ||
|
|
c96a8867f0 | ||
|
|
0e2a7ca91b | ||
|
|
ef1f596595 | ||
|
|
c5c60e04dd | ||
|
|
7e376af8fc | ||
|
|
4e57f9d5cf | ||
|
|
a9ee6e346b | ||
|
|
dd449ce462 | ||
|
|
bc30a591ba | ||
|
|
50c27d5ae1 | ||
|
|
1121960f0e | ||
|
|
028f6fdbf6 | ||
|
|
3c39a87146 | ||
|
|
9e5af4ad30 | ||
|
|
41682e0888 | ||
|
|
88141bb2d4 | ||
|
|
eb2c50c5e6 | ||
|
|
ea09930196 | ||
|
|
227278098a | ||
|
|
929acd4d1e | ||
|
|
2dbf5290f2 | ||
|
|
f813cd3ff7 | ||
|
|
9b8e962368 | ||
|
|
500e9c5969 | ||
|
|
0d735a905d | ||
|
|
fc04108c77 | ||
|
|
29fce1a187 | ||
|
|
4620580245 | ||
|
|
1ecaa86a52 | ||
|
|
a2e61e6542 | ||
|
|
26aee55aef | ||
|
|
dfa582169b | ||
|
|
93c083aef1 | ||
|
|
0ec07e8763 | ||
|
|
3cfa7a89e0 | ||
|
|
2aff0b4733 | ||
|
|
a925ae79ff | ||
|
|
9222b3c960 | ||
|
|
ba02ff230a | ||
|
|
3309a6cdf1 | ||
|
|
8db4feb5b4 | ||
|
|
7459215933 | ||
|
|
c49f51eaf1 | ||
|
|
3d1e741645 | ||
|
|
aabf5b2059 | ||
|
|
30bd77c6e7 | ||
|
|
5ddcc1b2f5 | ||
|
|
f4ca8e0d3e | ||
|
|
02910953d3 | ||
|
|
0128901102 | ||
|
|
3b668e1210 | ||
|
|
e6b4311178 | ||
|
|
5f2a9a4c86 | ||
|
|
1bcdf5e61c | ||
|
|
a290aac5b3 | ||
|
|
fd005585f6 | ||
|
|
224cf3075c | ||
|
|
b4d0724a63 | ||
|
|
3f4cabfd4d | ||
|
|
d5a69ecb68 | ||
|
|
3a13552db8 | ||
|
|
8850d85341 | ||
|
|
96ee1b42bc | ||
|
|
4b16e93f1a | ||
|
|
f88d2f5739 | ||
|
|
ecf1f2e054 | ||
|
|
0a0b676286 | ||
|
|
07552d4615 | ||
|
|
e6f4251988 | ||
|
|
7909860d16 | ||
|
|
96cd5dce85 | ||
|
|
bf3f030a0d | ||
|
|
c7b5a87c90 | ||
|
|
da2b8295e1 | ||
|
|
6572660fde | ||
|
|
78e5f162e2 | ||
|
|
55e423c8b6 | ||
|
|
738140fdd8 | ||
|
|
10804d6d0e | ||
|
|
38ec6e14d9 | ||
|
|
3e9cafbee5 | ||
|
|
b7a69501cd | ||
|
|
973c40b63e | ||
|
|
9acd336422 | ||
|
|
8bddc750e2 | ||
|
|
1417849a2b | ||
|
|
1fbc341aba | ||
|
|
b6538c3e7c | ||
|
|
6c53edd4d3 | ||
|
|
8e64fb3225 | ||
|
|
c3c3e07263 | ||
|
|
5cb531b6cf | ||
|
|
b4dbf1b9c7 | ||
|
|
871aadbe36 | ||
|
|
9df67b2095 | ||
|
|
37c690576f | ||
|
|
72b73d22ab | ||
|
|
961427037c | ||
|
|
2261cf24af | ||
|
|
fdbeb90bd0 | ||
|
|
5e19691e41 | ||
|
|
0f6064e5c9 | ||
|
|
1276e425d2 | ||
|
|
a17813c4f4 | ||
|
|
fb51a655b8 | ||
|
|
d6a24b4a5b | ||
|
|
fe931ac976 | ||
|
|
b87422a86f | ||
|
|
90e5694230 | ||
|
|
bb1ed66d99 | ||
|
|
4dca2298f9 | ||
|
|
1517cba8ca | ||
|
|
a65e9ad552 | ||
|
|
e8e04a4b80 | ||
|
|
6c7d8073be | ||
|
|
8da16cf9fb | ||
|
|
378aed07e9 | ||
|
|
ddd82ef42b | ||
|
|
e895a4e2d7 | ||
|
|
2a96bea6a7 | ||
|
|
c788f9c0bd | ||
|
|
255197e643 | ||
|
|
ffc5ec6fa8 | ||
|
|
d523734266 | ||
|
|
c1ffaa8b29 | ||
|
|
dffcff9fec | ||
|
|
527a1574c3 | ||
|
|
d8a961cd6c | ||
|
|
03a6f3b0f4 | ||
|
|
cc84b48ce5 | ||
|
|
4fb921ff6b | ||
|
|
72deb773fd | ||
|
|
3e35101895 | ||
|
|
8c37cd1af6 | ||
|
|
f665c92114 | ||
|
|
8af62c9997 | ||
|
|
5c9feaebb6 | ||
|
|
b8aef40c56 | ||
|
|
18a88d19dc | ||
|
|
3fedcc2f6e | ||
|
|
bcd0444bb9 | ||
|
|
dd43d725c6 | ||
|
|
6f47bd9641 | ||
|
|
e7664b7a4f |
@@ -1,4 +1,7 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
chmod a+x ./.ci/scripts/format/docker.sh
|
||||
# the UID for the container yuzu user is 1027
|
||||
sudo chown -R 1027 ./
|
||||
docker run -v $(pwd):/yuzu yuzuemu/build-environments:linux-clang-format /bin/bash -ex /yuzu/.ci/scripts/format/docker.sh
|
||||
sudo chown -R $UID ./
|
||||
|
||||
2
.ci/scripts/linux/docker.sh
Normal file → Executable file
2
.ci/scripts/linux/docker.sh
Normal file → Executable file
@@ -5,7 +5,7 @@ cd /yuzu
|
||||
ccache -s
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -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 -DENABLE_VULKAN=No
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -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
|
||||
|
||||
|
||||
@@ -2,4 +2,7 @@
|
||||
|
||||
mkdir -p "ccache" || true
|
||||
chmod a+x ./.ci/scripts/linux/docker.sh
|
||||
# the UID for the container yuzu user is 1027
|
||||
sudo chown -R 1027 ./
|
||||
docker run -e ENABLE_COMPATIBILITY_REPORTING -e CCACHE_DIR=/yuzu/ccache -v $(pwd):/yuzu yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.ci/scripts/linux/docker.sh $1
|
||||
sudo chown -R $UID ./
|
||||
|
||||
22
.ci/scripts/windows/docker.sh
Normal file → Executable file
22
.ci/scripts/windows/docker.sh
Normal file → Executable file
@@ -4,22 +4,10 @@ cd /yuzu
|
||||
|
||||
ccache -s
|
||||
|
||||
# Dirty hack to trick unicorn makefile into believing we are in a MINGW system
|
||||
mv /bin/uname /bin/uname1 && echo -e '#!/bin/sh\necho MINGW64' >> /bin/uname
|
||||
chmod +x /bin/uname
|
||||
|
||||
# Dirty hack to trick unicorn makefile into believing we have cmd
|
||||
echo '' >> /bin/cmd
|
||||
chmod +x /bin/cmd
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DYUZU_USE_BUNDLED_UNICORN=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_VULKAN=No
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DYUZU_USE_BUNDLED_UNICORN=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"
|
||||
@@ -29,7 +17,13 @@ echo 'Prepare binaries...'
|
||||
cd ..
|
||||
mkdir package
|
||||
|
||||
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/'
|
||||
if [ -d "/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/" ]; then
|
||||
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/'
|
||||
else
|
||||
#fallback to qt
|
||||
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/'
|
||||
fi
|
||||
|
||||
find build/ -name "yuzu*.exe" -exec cp {} 'package' \;
|
||||
|
||||
# copy Qt plugins
|
||||
|
||||
@@ -2,4 +2,7 @@
|
||||
|
||||
mkdir -p "ccache" || true
|
||||
chmod a+x ./.ci/scripts/windows/docker.sh
|
||||
# the UID for the container yuzu user is 1027
|
||||
sudo chown -R 1027 ./
|
||||
docker run -e CCACHE_DIR=/yuzu/ccache -v $(pwd):/yuzu yuzuemu/build-environments:linux-mingw /bin/bash -ex /yuzu/.ci/scripts/windows/docker.sh $1
|
||||
sudo chown -R $UID ./
|
||||
|
||||
@@ -4,7 +4,9 @@ parameters:
|
||||
version: ''
|
||||
|
||||
steps:
|
||||
- script: mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 --config Release -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_BUNDLED_UNICORN=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cd ..
|
||||
- script: python -m pip install --upgrade pip conan
|
||||
displayName: 'Install conan'
|
||||
- script: mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 --config Release -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_UNICORN=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cd ..
|
||||
displayName: 'Configure CMake'
|
||||
- task: MSBuild@1
|
||||
displayName: 'Build'
|
||||
|
||||
@@ -5,18 +5,7 @@ variables:
|
||||
DisplayVersion: $[counter(variables['DisplayPrefix'], 1)]
|
||||
|
||||
stages:
|
||||
- stage: format
|
||||
displayName: 'format'
|
||||
jobs:
|
||||
- job: format
|
||||
displayName: 'clang'
|
||||
continueOnError: true
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- template: ./templates/format-check.yml
|
||||
- stage: build
|
||||
dependsOn: format
|
||||
displayName: 'build'
|
||||
jobs:
|
||||
- job: build
|
||||
|
||||
30
.gitmodules
vendored
30
.gitmodules
vendored
@@ -1,54 +1,30 @@
|
||||
[submodule "inih"]
|
||||
path = externals/inih/inih
|
||||
url = https://github.com/svn2github/inih
|
||||
[submodule "boost"]
|
||||
path = externals/boost
|
||||
url = https://github.com/yuzu-emu/ext-boost.git
|
||||
[submodule "catch"]
|
||||
path = externals/catch
|
||||
url = https://github.com/philsquared/Catch.git
|
||||
[submodule "cubeb"]
|
||||
path = externals/cubeb
|
||||
url = https://github.com/kinetiknz/cubeb.git
|
||||
[submodule "dynarmic"]
|
||||
path = externals/dynarmic
|
||||
url = https://github.com/MerryMage/dynarmic.git
|
||||
[submodule "fmt"]
|
||||
path = externals/fmt
|
||||
url = https://github.com/fmtlib/fmt.git
|
||||
[submodule "lz4"]
|
||||
path = externals/lz4
|
||||
url = https://github.com/lz4/lz4.git
|
||||
[submodule "unicorn"]
|
||||
path = externals/unicorn
|
||||
url = https://github.com/yuzu-emu/unicorn
|
||||
[submodule "mbedtls"]
|
||||
path = externals/mbedtls
|
||||
url = https://github.com/DarkLordZach/mbedtls
|
||||
[submodule "opus"]
|
||||
path = externals/opus/opus
|
||||
url = https://github.com/xiph/opus.git
|
||||
[submodule "soundtouch"]
|
||||
path = externals/soundtouch
|
||||
url = https://github.com/citra-emu/ext-soundtouch.git
|
||||
[submodule "libressl"]
|
||||
path = externals/libressl
|
||||
url = https://github.com/citra-emu/ext-libressl-portable.git
|
||||
[submodule "discord-rpc"]
|
||||
path = externals/discord-rpc
|
||||
url = https://github.com/discordapp/discord-rpc.git
|
||||
[submodule "Vulkan-Headers"]
|
||||
path = externals/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
[submodule "externals/zstd"]
|
||||
path = externals/zstd
|
||||
url = https://github.com/facebook/zstd
|
||||
[submodule "sirit"]
|
||||
path = externals/sirit
|
||||
url = https://github.com/ReinUsesLisp/sirit
|
||||
[submodule "mbedtls"]
|
||||
path = externals/mbedtls
|
||||
url = https://github.com/DarkLordZach/mbedtls
|
||||
[submodule "libzip"]
|
||||
path = externals/libzip/libzip
|
||||
url = https://github.com/nih-at/libzip.git
|
||||
[submodule "zlib"]
|
||||
path = externals/zlib/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
|
||||
312
CMakeLists.txt
312
CMakeLists.txt
@@ -1,7 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/find-modules")
|
||||
include(DownloadExternals)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
@@ -10,10 +11,9 @@ project(yuzu)
|
||||
# Set bundled sdl2/qt as dependent options.
|
||||
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
|
||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
|
||||
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_QT;MSVC" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" OFF "ENABLE_QT;MSVC" OFF)
|
||||
|
||||
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
||||
|
||||
@@ -29,6 +29,13 @@ option(ENABLE_VULKAN "Enables Vulkan backend" ON)
|
||||
|
||||
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
||||
|
||||
# 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)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
message(STATUS "Defaulting to a Release build")
|
||||
endif()
|
||||
|
||||
if(EXISTS ${PROJECT_SOURCE_DIR}/hooks/pre-commit AND NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
|
||||
message(STATUS "Copying pre-commit hook")
|
||||
file(COPY hooks/pre-commit
|
||||
@@ -53,7 +60,6 @@ endfunction()
|
||||
if(EXISTS ${PROJECT_SOURCE_DIR}/.gitmodules)
|
||||
check_submodules_present()
|
||||
endif()
|
||||
|
||||
configure_file(${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||
COPYONLY)
|
||||
@@ -115,63 +121,227 @@ message(STATUS "Target architecture: ${ARCHITECTURE}")
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# System imported libraries
|
||||
# ======================
|
||||
|
||||
find_package(Boost 1.66.0 QUIET)
|
||||
if (NOT Boost_FOUND)
|
||||
message(STATUS "Boost 1.66.0 or newer not found, falling back to externals")
|
||||
|
||||
set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost")
|
||||
set(Boost_NO_SYSTEM_PATHS OFF)
|
||||
find_package(Boost QUIET REQUIRED)
|
||||
endif()
|
||||
|
||||
# Output binaries to bin/
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
# System imported libraries
|
||||
# If not found, download any missing through Conan
|
||||
# =======================================================================
|
||||
set(CONAN_CMAKE_SILENT_OUTPUT TRUE)
|
||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
|
||||
if (YUZU_CONAN_INSTALLED)
|
||||
if (IS_MULTI_CONFIG)
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo_multi.cmake)
|
||||
else()
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||
endif()
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")
|
||||
conan_basic_setup()
|
||||
message(STATUS "Adding conan installed libraries to the search path")
|
||||
endif()
|
||||
|
||||
macro(yuzu_find_packages)
|
||||
set(options FORCE_REQUIRED)
|
||||
cmake_parse_arguments(FN "${options}" "" "" ${ARGN})
|
||||
|
||||
# Cmake has a *serious* lack of 2D array or associative array...
|
||||
# Capitalization matters here. We need the naming to match the generated paths from Conan
|
||||
set(REQUIRED_LIBS
|
||||
# Cmake Pkg Prefix Version Conan Pkg
|
||||
"Boost 1.71 boost/1.72.0"
|
||||
"Catch2 2.11 catch2/2.11.0"
|
||||
"fmt 6.2 fmt/6.2.0"
|
||||
"OpenSSL 1.1 openssl/1.1.1f"
|
||||
# can't use until https://github.com/bincrafters/community/issues/1173
|
||||
#"libzip 1.5 libzip/1.5.2@bincrafters/stable"
|
||||
"lz4 1.8 lz4/1.9.2"
|
||||
"nlohmann_json 3.7 nlohmann_json/3.7.3"
|
||||
# we need to be careful as the version check might be broken https://github.com/xiph/opus/issues/110
|
||||
"opus 1.3 opus/1.3.1"
|
||||
"ZLIB 1.2 zlib/1.2.11"
|
||||
"zstd 1.4 zstd/1.4.4"
|
||||
)
|
||||
|
||||
foreach(PACKAGE ${REQUIRED_LIBS})
|
||||
string(REGEX REPLACE "[ \t\r\n]+" ";" PACKAGE_SPLIT ${PACKAGE})
|
||||
list(GET PACKAGE_SPLIT 0 PACKAGE_PREFIX)
|
||||
list(GET PACKAGE_SPLIT 1 PACKAGE_VERSION)
|
||||
list(GET PACKAGE_SPLIT 2 PACKAGE_CONAN)
|
||||
# This function is called twice, once to check if the packages exist on the system already
|
||||
# and a second time to check if conan installed them properly. The second check passes in FORCE_REQUIRED
|
||||
if (NOT ${PACKAGE_PREFIX}_FOUND)
|
||||
if (FN_FORCE_REQUIRED)
|
||||
find_package(${PACKAGE_PREFIX} ${PACKAGE_VERSION} REQUIRED)
|
||||
else()
|
||||
find_package(${PACKAGE_PREFIX} ${PACKAGE_VERSION})
|
||||
endif()
|
||||
endif()
|
||||
if (NOT ${PACKAGE_PREFIX}_FOUND)
|
||||
list(APPEND CONAN_REQUIRED_LIBS ${PACKAGE_CONAN})
|
||||
else()
|
||||
# Set a legacy findPackage.cmake style PACKAGE_LIBRARIES variable for subprojects that rely on this
|
||||
set(${PACKAGE_PREFIX}_LIBRARIES "${PACKAGE_PREFIX}::${PACKAGE_PREFIX}")
|
||||
endif()
|
||||
endforeach()
|
||||
unset(FN_FORCE_REQUIRED)
|
||||
endmacro()
|
||||
|
||||
# Attempt to locate any packages that are required and report the missing ones in CONAN_REQUIRED_LIBS
|
||||
yuzu_find_packages()
|
||||
|
||||
# Qt5 requires that we find components, so it doesn't fit our pretty little find package function
|
||||
if(ENABLE_QT)
|
||||
# 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)
|
||||
include(${CMAKE_BINARY_DIR}/qtConfig.cmake)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CONAN_QT_ROOT_RELEASE}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CONAN_QT_ROOT_RELEASE}")
|
||||
endif()
|
||||
# Workaround for an issue where conan tries to build Qt from scratch instead of download prebuilt binaries
|
||||
set(QT_PREFIX_HINT)
|
||||
if(YUZU_USE_BUNDLED_QT)
|
||||
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
|
||||
set(QT_VER qt-5.12.0-msvc2017_64)
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable YUZU_USE_BUNDLED_QT and provide your own.")
|
||||
endif()
|
||||
|
||||
if (DEFINED QT_VER)
|
||||
download_bundled_external("qt/" ${QT_VER} QT_PREFIX)
|
||||
endif()
|
||||
|
||||
set(QT_PREFIX_HINT HINTS "${QT_PREFIX}")
|
||||
endif()
|
||||
find_package(Qt5 5.9 COMPONENTS Widgets OpenGL ${QT_PREFIX_HINT})
|
||||
if (NOT Qt5_FOUND)
|
||||
list(APPEND CONAN_REQUIRED_LIBS "qt/5.14.1@bincrafters/stable")
|
||||
endif()
|
||||
endif()
|
||||
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the yuzu_find_package
|
||||
if(ENABLE_SDL2)
|
||||
if(EXISTS ${CMAKE_BINARY_DIR}/sdl2Config.cmake)
|
||||
include(${CMAKE_BINARY_DIR}/sdl2Config.cmake)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CONAN_SDL2_ROOT_RELEASE}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CONAN_SDL2_ROOT_RELEASE}")
|
||||
endif()
|
||||
find_package(SDL2)
|
||||
if (NOT SDL2_FOUND)
|
||||
# otherwise add this to the list of libraries to install
|
||||
list(APPEND CONAN_REQUIRED_LIBS "sdl2/2.0.12@bincrafters/stable")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Install any missing dependencies with conan install
|
||||
if (CONAN_REQUIRED_LIBS)
|
||||
message(STATUS "Packages ${CONAN_REQUIRED_LIBS} not found!")
|
||||
# Use Conan to fetch the libraries that aren't found
|
||||
# Download conan.cmake automatically, you can also just copy the conan.cmake file
|
||||
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
|
||||
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
|
||||
file(DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.15/conan.cmake"
|
||||
"${CMAKE_BINARY_DIR}/conan.cmake")
|
||||
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)
|
||||
# Add the bincrafters remote
|
||||
conan_add_remote(NAME bincrafters
|
||||
URL https://api.bintray.com/conan/bincrafters/public-conan)
|
||||
|
||||
# Manually add iconv to fix a dep conflict between qt and sdl2
|
||||
# We don't need to add it through find_package or anything since the other two can find it just fine
|
||||
if ("${CONAN_REQUIRED_LIBS}" MATCHES "qt" AND "${CONAN_REQUIRED_LIBS}" MATCHES "sdl")
|
||||
list(APPEND CONAN_REQUIRED_LIBS "libiconv/1.16")
|
||||
endif()
|
||||
if (IS_MULTI_CONFIG)
|
||||
conan_cmake_run(REQUIRES ${CONAN_REQUIRED_LIBS}
|
||||
OPTIONS ${CONAN_LIB_OPTIONS}
|
||||
BUILD missing
|
||||
CONFIGURATION_TYPES "Release;Debug"
|
||||
GENERATORS cmake_multi cmake_find_package_multi)
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo_multi.cmake)
|
||||
else()
|
||||
conan_cmake_run(REQUIRES ${CONAN_REQUIRED_LIBS}
|
||||
OPTIONS ${CONAN_LIB_OPTIONS}
|
||||
BUILD missing
|
||||
GENERATORS cmake cmake_find_package_multi)
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||
endif()
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")
|
||||
conan_basic_setup()
|
||||
|
||||
set(YUZU_CONAN_INSTALLED TRUE CACHE BOOL "If true, the following builds will add conan to the lib search path" FORCE)
|
||||
|
||||
# Now that we've installed what we are missing, try to locate them again,
|
||||
# this time with required, so we bail if its not found.
|
||||
yuzu_find_packages(FORCE_REQUIRED)
|
||||
|
||||
# Due to issues with variable scopes in functions, we need to also find_package(qt5) outside of the function
|
||||
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.9 REQUIRED COMPONENTS Widgets OpenGL)
|
||||
if (YUZU_USE_QT_WEB_ENGINE)
|
||||
find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets)
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_SDL2)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CONAN_SDL2_ROOT_RELEASE}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CONAN_SDL2_ROOT_RELEASE}")
|
||||
find_package(SDL2 REQUIRED)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# Reexport some targets that are named differently when using the upstream CmakeConfig vs the generated Conan config
|
||||
# In order to ALIAS targets to a new name, they first need to be IMPORTED_GLOBAL
|
||||
# Dynarmic checks for target `boost` and so we want to make sure it can find it through our system instead of using their external
|
||||
if (TARGET Boost::Boost)
|
||||
set_target_properties(Boost::Boost PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
add_library(Boost::boost ALIAS Boost::Boost)
|
||||
add_library(boost ALIAS Boost::Boost)
|
||||
elseif (TARGET Boost::boost)
|
||||
set_target_properties(Boost::boost PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
add_library(boost ALIAS Boost::boost)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET OpenSSL::SSL)
|
||||
set_target_properties(OpenSSL::OpenSSL PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
add_library(OpenSSL::SSL ALIAS OpenSSL::OpenSSL)
|
||||
endif()
|
||||
if (NOT TARGET OpenSSL::Crypto)
|
||||
set_target_properties(OpenSSL::OpenSSL PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
add_library(OpenSSL::Crypto ALIAS OpenSSL::OpenSSL)
|
||||
endif()
|
||||
|
||||
if (TARGET sdl2::sdl2)
|
||||
# imported from the conan generated sdl2Config.cmake
|
||||
set_target_properties(sdl2::sdl2 PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
add_library(SDL2 ALIAS sdl2::sdl2)
|
||||
elseif(SDL2_FOUND)
|
||||
# found through the system package manager
|
||||
# Some installations don't set SDL2_LIBRARIES
|
||||
if("${SDL2_LIBRARIES}" STREQUAL "")
|
||||
message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
|
||||
set(SDL2_LIBRARIES "SDL2::SDL2")
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
|
||||
add_library(SDL2 INTERFACE)
|
||||
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
# Prefer the -pthread flag on Linux.
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if (ENABLE_SDL2)
|
||||
if (YUZU_USE_BUNDLED_SDL2)
|
||||
# Detect toolchain and platform
|
||||
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
|
||||
set(SDL2_VER "SDL2-2.0.8")
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
|
||||
endif()
|
||||
|
||||
if (DEFINED SDL2_VER)
|
||||
download_bundled_external("sdl2/" ${SDL2_VER} SDL2_PREFIX)
|
||||
endif()
|
||||
|
||||
set(SDL2_FOUND YES)
|
||||
set(SDL2_INCLUDE_DIR "${SDL2_PREFIX}/include" CACHE PATH "Path to SDL2 headers")
|
||||
set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library")
|
||||
set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll")
|
||||
|
||||
add_library(SDL2 INTERFACE)
|
||||
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
|
||||
target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
|
||||
else()
|
||||
find_package(SDL2 REQUIRED)
|
||||
|
||||
# Some installations don't set SDL2_LIBRARIES
|
||||
if("${SDL2_LIBRARIES}" STREQUAL "")
|
||||
message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
|
||||
set(SDL2_LIBRARIES "SDL2::SDL2")
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
|
||||
add_library(SDL2 INTERFACE)
|
||||
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
|
||||
endif()
|
||||
else()
|
||||
set(SDL2_FOUND NO)
|
||||
endif()
|
||||
|
||||
# If unicorn isn't found, msvc -> download bundled unicorn; everyone else -> build external
|
||||
if (YUZU_USE_BUNDLED_UNICORN)
|
||||
if (MSVC)
|
||||
@@ -212,8 +382,12 @@ if (YUZU_USE_BUNDLED_UNICORN)
|
||||
find_package(PythonInterp 2.7 REQUIRED)
|
||||
|
||||
if (MINGW)
|
||||
# Intentionally call the unicorn makefile directly instead of using make.sh so that we can override the
|
||||
# UNAME_S makefile variable to MINGW. This way we don't have to hack at the uname binary to build
|
||||
# Additionally, overriding DO_WINDOWS_EXPORT prevents unicorn from patching the static unicorn.a by using msvc and cmd,
|
||||
# which are both things we don't have in a mingw cross compiling environment.
|
||||
add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY}
|
||||
COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh cross-win64
|
||||
COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-gcc-ar RANLIB=x86_64-w64-mingw32-gcc-ranlib make UNAME_S=MINGW DO_WINDOWS_EXPORT=0
|
||||
WORKING_DIRECTORY ${UNICORN_PREFIX}
|
||||
)
|
||||
else()
|
||||
@@ -243,32 +417,6 @@ else()
|
||||
message(FATAL_ERROR "Could not find or build unicorn which is required.")
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT)
|
||||
if (YUZU_USE_BUNDLED_QT)
|
||||
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
|
||||
set(QT_VER qt-5.12.0-msvc2017_64)
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable YUZU_USE_BUNDLED_QT and provide your own.")
|
||||
endif()
|
||||
|
||||
if (DEFINED QT_VER)
|
||||
download_bundled_external("qt/" ${QT_VER} QT_PREFIX)
|
||||
endif()
|
||||
|
||||
set(QT_PREFIX_HINT HINTS "${QT_PREFIX}")
|
||||
else()
|
||||
# Passing an empty HINTS seems to cause default system paths to get ignored in CMake 2.8 so
|
||||
# make sure to not pass anything if we don't have one.
|
||||
set(QT_PREFIX_HINT)
|
||||
endif()
|
||||
|
||||
find_package(Qt5 REQUIRED COMPONENTS Widgets OpenGL ${QT_PREFIX_HINT})
|
||||
|
||||
if (YUZU_USE_QT_WEB_ENGINE)
|
||||
find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets ${QT_PREFIX_HINT})
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# Platform-specific library requirements
|
||||
# ======================================
|
||||
|
||||
@@ -299,7 +447,7 @@ find_program(CLANG_FORMAT
|
||||
PATHS ${PROJECT_BINARY_DIR}/externals)
|
||||
# if find_program doesn't find it, try to download from externals
|
||||
if (NOT CLANG_FORMAT)
|
||||
if (WIN32)
|
||||
if (WIN32 AND NOT CMAKE_CROSSCOMPILING)
|
||||
message(STATUS "Clang format not found! Downloading...")
|
||||
set(CLANG_FORMAT "${PROJECT_BINARY_DIR}/externals/clang-format${CLANG_FORMAT_POSTFIX}.exe")
|
||||
file(DOWNLOAD
|
||||
|
||||
@@ -10,8 +10,8 @@ set(SDL2_PATH ${MINGW_PREFIX})
|
||||
set(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-)
|
||||
|
||||
# Specify the cross compiler
|
||||
set(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}gcc-posix)
|
||||
set(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}g++-posix)
|
||||
set(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}gcc)
|
||||
set(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}g++)
|
||||
set(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres)
|
||||
|
||||
# Mingw tools
|
||||
|
||||
87
externals/CMakeLists.txt
vendored
87
externals/CMakeLists.txt
vendored
@@ -1,30 +1,13 @@
|
||||
# Definitions for all external bundled libraries
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/externals/find-modules")
|
||||
include(DownloadExternals)
|
||||
|
||||
# pkgconfig -- it is used to find shared libraries without cmake modules on linux systems
|
||||
find_package(PkgConfig)
|
||||
if (NOT PkgConfig_FOUND)
|
||||
function(pkg_check_modules)
|
||||
# STUB
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
# Catch
|
||||
add_library(catch-single-include INTERFACE)
|
||||
target_include_directories(catch-single-include INTERFACE catch/single_include)
|
||||
|
||||
# libfmt
|
||||
pkg_check_modules(FMT IMPORTED_TARGET GLOBAL fmt>=6.2.0)
|
||||
if (FMT_FOUND)
|
||||
add_library(fmt::fmt ALIAS PkgConfig::FMT)
|
||||
else()
|
||||
message(STATUS "fmt 6.2.0 or newer not found, falling back to externals")
|
||||
add_subdirectory(fmt)
|
||||
add_library(fmt::fmt ALIAS fmt)
|
||||
endif()
|
||||
|
||||
# Dynarmic
|
||||
if (ARCHITECTURE_x86_64)
|
||||
set(DYNARMIC_TESTS OFF)
|
||||
@@ -43,17 +26,6 @@ add_subdirectory(glad)
|
||||
# inih
|
||||
add_subdirectory(inih)
|
||||
|
||||
# lz4
|
||||
pkg_check_modules(LIBLZ4 IMPORTED_TARGET GLOBAL liblz4>=1.8.0)
|
||||
if (LIBLZ4_FOUND)
|
||||
add_library(lz4_static ALIAS PkgConfig::LIBLZ4)
|
||||
else()
|
||||
message(STATUS "liblz4 1.8.0 or newer not found, falling back to externals")
|
||||
set(LZ4_BUNDLED_MODE ON)
|
||||
add_subdirectory(lz4/contrib/cmake_unofficial EXCLUDE_FROM_ALL)
|
||||
target_include_directories(lz4_static INTERFACE ./lz4/lib)
|
||||
endif()
|
||||
|
||||
# mbedtls
|
||||
add_subdirectory(mbedtls EXCLUDE_FROM_ALL)
|
||||
target_include_directories(mbedtls PUBLIC ./mbedtls/include)
|
||||
@@ -66,29 +38,9 @@ target_include_directories(microprofile INTERFACE ./microprofile)
|
||||
add_library(unicorn-headers INTERFACE)
|
||||
target_include_directories(unicorn-headers INTERFACE ./unicorn/include)
|
||||
|
||||
# Zstandard
|
||||
pkg_check_modules(LIBZSTD IMPORTED_TARGET GLOBAL libzstd>=1.3.8)
|
||||
if (LIBZSTD_FOUND)
|
||||
add_library(libzstd_static ALIAS PkgConfig::LIBZSTD)
|
||||
else()
|
||||
message(STATUS "libzstd 1.3.8 or newer not found, falling back to externals")
|
||||
add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
|
||||
target_include_directories(libzstd_static INTERFACE ./zstd/lib)
|
||||
endif()
|
||||
|
||||
# SoundTouch
|
||||
add_subdirectory(soundtouch)
|
||||
|
||||
# Opus
|
||||
pkg_check_modules(OPUS IMPORTED_TARGET GLOBAL opus>=1.3.1)
|
||||
if (OPUS_FOUND)
|
||||
add_library(opus ALIAS PkgConfig::OPUS)
|
||||
else()
|
||||
message(STATUS "opus 1.3.1 or newer not found, falling back to externals")
|
||||
add_subdirectory(opus)
|
||||
target_include_directories(opus INTERFACE ./opus/include)
|
||||
endif()
|
||||
|
||||
# Cubeb
|
||||
if(ENABLE_CUBEB)
|
||||
set(BUILD_TESTS OFF CACHE BOOL "")
|
||||
@@ -106,37 +58,14 @@ if (ENABLE_VULKAN)
|
||||
add_subdirectory(sirit)
|
||||
endif()
|
||||
|
||||
# zlib
|
||||
find_package(ZLIB 1.2.11)
|
||||
if (NOT ZLIB_FOUND)
|
||||
message(STATUS "zlib 1.2.11 or newer not found, falling back to externals")
|
||||
add_subdirectory(zlib EXCLUDE_FROM_ALL)
|
||||
set(ZLIB_LIBRARIES z)
|
||||
endif()
|
||||
|
||||
# libzip
|
||||
pkg_check_modules(LIBZIP IMPORTED_TARGET GLOBAL libzip>=1.5.3)
|
||||
if (LIBZIP_FOUND)
|
||||
add_library(zip ALIAS PkgConfig::LIBZIP)
|
||||
else()
|
||||
message(STATUS "libzip 1.5.3 or newer not found, falling back to externals")
|
||||
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)
|
||||
# LibreSSL
|
||||
find_package(OpenSSL COMPONENTS Crypto SSL)
|
||||
if (NOT OpenSSL_FOUND)
|
||||
message(STATUS "OpenSSL not found, falling back to externals")
|
||||
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
||||
add_subdirectory(libressl EXCLUDE_FROM_ALL)
|
||||
target_include_directories(ssl INTERFACE ./libressl/include)
|
||||
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
|
||||
get_directory_property(OPENSSL_LIBRARIES
|
||||
DIRECTORY libressl
|
||||
DEFINITION OPENSSL_LIBS)
|
||||
endif()
|
||||
|
||||
# lurlparser
|
||||
add_subdirectory(lurlparser EXCLUDE_FROM_ALL)
|
||||
|
||||
@@ -144,9 +73,5 @@ if (ENABLE_WEB_SERVICE)
|
||||
add_library(httplib INTERFACE)
|
||||
target_include_directories(httplib INTERFACE ./httplib)
|
||||
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
|
||||
|
||||
# JSON
|
||||
add_library(json-headers INTERFACE)
|
||||
target_include_directories(json-headers INTERFACE ./json)
|
||||
target_link_libraries(httplib INTERFACE OpenSSL::SSL OpenSSL::Crypto)
|
||||
endif()
|
||||
|
||||
2
externals/Vulkan-Headers
vendored
2
externals/Vulkan-Headers
vendored
Submodule externals/Vulkan-Headers updated: 0e78ffd1dc...9250d5ae8f
1
externals/boost
vendored
1
externals/boost
vendored
Submodule externals/boost deleted from 5e8300b76a
1
externals/catch
vendored
1
externals/catch
vendored
Submodule externals/catch deleted from 15cf3caace
2
externals/cubeb
vendored
2
externals/cubeb
vendored
Submodule externals/cubeb updated: 6f2420de8f...616d773441
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
Submodule externals/dynarmic updated: a3cd05577c...e7166e8ba7
49
externals/find-modules/FindCatch2.cmake
vendored
Normal file
49
externals/find-modules/FindCatch2.cmake
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_Catch2 QUIET Catch2)
|
||||
|
||||
find_path(Catch2_INCLUDE_DIR
|
||||
NAMES catch.hpp
|
||||
PATHS ${PC_Catch2_INCLUDE_DIRS} ${CONAN_CATCH2_ROOT}
|
||||
PATH_SUFFIXES catch2
|
||||
)
|
||||
|
||||
if(Catch2_INCLUDE_DIR)
|
||||
file(STRINGS "${Catch2_INCLUDE_DIR}/catch.hpp" _Catch2_version_lines
|
||||
REGEX "#define[ \t]+CATCH_VERSION_(MAJOR|MINOR|PATCH)")
|
||||
string(REGEX REPLACE ".*CATCH_VERSION_MAJOR +\([0-9]+\).*" "\\1" _Catch2_version_major "${_Catch2_version_lines}")
|
||||
string(REGEX REPLACE ".*CATCH_VERSION_MINOR +\([0-9]+\).*" "\\1" _Catch2_version_minor "${_Catch2_version_lines}")
|
||||
string(REGEX REPLACE ".*CATCH_VERSION_PATCH +\([0-9]+\).*" "\\1" _Catch2_version_patch "${_Catch2_version_lines}")
|
||||
set(Catch2_VERSION "${_Catch2_version_major}.${_Catch2_version_minor}.${_Catch2_version_patch}")
|
||||
unset(_Catch2_version_major)
|
||||
unset(_Catch2_version_minor)
|
||||
unset(_Catch2_version_patch)
|
||||
unset(_Catch2_version_lines)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Catch2
|
||||
FOUND_VAR Catch2_FOUND
|
||||
REQUIRED_VARS
|
||||
Catch2_INCLUDE_DIR
|
||||
Catch2_VERSION
|
||||
VERSION_VAR Catch2_VERSION
|
||||
)
|
||||
|
||||
if(Catch2_FOUND)
|
||||
set(Catch2_INCLUDE_DIRS ${Catch2_INCLUDE_DIR})
|
||||
set(Catch2_DEFINITIONS ${PC_Catch2_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(Catch2_FOUND AND NOT TARGET Catch2::Catch2)
|
||||
add_library(Catch2::Catch2 UNKNOWN IMPORTED)
|
||||
set_target_properties(Catch2::Catch2 PROPERTIES
|
||||
IMPORTED_LOCATION "${Catch2_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_Catch2_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Catch2_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
Catch2_INCLUDE_DIR
|
||||
)
|
||||
72
externals/find-modules/FindLibzip.cmake
vendored
Normal file
72
externals/find-modules/FindLibzip.cmake
vendored
Normal 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
|
||||
)
|
||||
69
externals/find-modules/Findfmt.cmake
vendored
Normal file
69
externals/find-modules/Findfmt.cmake
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_fmt QUIET fmt)
|
||||
|
||||
find_path(fmt_INCLUDE_DIR
|
||||
NAMES format.h
|
||||
PATHS ${PC_fmt_INCLUDE_DIRS} ${CONAN_INCLUDE_DIRS_fmt}
|
||||
PATH_SUFFIXES fmt
|
||||
)
|
||||
|
||||
find_library(fmt_LIBRARY
|
||||
NAMES fmt
|
||||
PATHS ${PC_fmt_LIBRARY_DIRS} ${CONAN_LIB_DIRS_fmt}
|
||||
)
|
||||
|
||||
if(fmt_INCLUDE_DIR)
|
||||
set(_fmt_version_file "${fmt_INCLUDE_DIR}/core.h")
|
||||
if(NOT EXISTS "${_fmt_version_file}")
|
||||
set(_fmt_version_file "${fmt_INCLUDE_DIR}/format.h")
|
||||
endif()
|
||||
if(EXISTS "${_fmt_version_file}")
|
||||
# parse "#define FMT_VERSION 60200" to 6.2.0
|
||||
file(STRINGS "${_fmt_version_file}" fmt_VERSION_LINE
|
||||
REGEX "^#define[ \t]+FMT_VERSION[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+FMT_VERSION[ \t]+([0-9]+)$"
|
||||
"\\1" fmt_VERSION "${fmt_VERSION_LINE}")
|
||||
foreach(ver "fmt_VERSION_PATCH" "fmt_VERSION_MINOR" "fmt_VERSION_MAJOR")
|
||||
math(EXPR ${ver} "${fmt_VERSION} % 100")
|
||||
math(EXPR fmt_VERSION "(${fmt_VERSION} - ${${ver}}) / 100")
|
||||
endforeach()
|
||||
set(fmt_VERSION
|
||||
"${fmt_VERSION_MAJOR}.${fmt_VERSION_MINOR}.${fmt_VERSION_PATCH}")
|
||||
endif()
|
||||
unset(_fmt_version_file)
|
||||
unset(fmt_VERSION_LINE)
|
||||
unset(fmt_VERSION_MAJOR)
|
||||
unset(fmt_VERSION_MINOR)
|
||||
unset(fmt_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(fmt
|
||||
FOUND_VAR fmt_FOUND
|
||||
REQUIRED_VARS
|
||||
fmt_LIBRARY
|
||||
fmt_INCLUDE_DIR
|
||||
fmt_VERSION
|
||||
VERSION_VAR fmt_VERSION
|
||||
)
|
||||
|
||||
if(fmt_FOUND)
|
||||
set(fmt_LIBRARIES ${fmt_LIBRARY})
|
||||
set(fmt_INCLUDE_DIRS ${fmt_INCLUDE_DIR})
|
||||
set(fmt_DEFINITIONS ${PC_fmt_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(fmt_FOUND AND NOT TARGET fmt::fmt)
|
||||
add_library(fmt::fmt UNKNOWN IMPORTED)
|
||||
set_target_properties(fmt::fmt PROPERTIES
|
||||
IMPORTED_LOCATION "${fmt_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_fmt_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${fmt_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
fmt_INCLUDE_DIR
|
||||
fmt_LIBRARY
|
||||
)
|
||||
54
externals/find-modules/Findlz4.cmake
vendored
Normal file
54
externals/find-modules/Findlz4.cmake
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_lz4 QUIET lz4)
|
||||
|
||||
find_path(lz4_INCLUDE_DIR
|
||||
NAMES lz4.h
|
||||
PATHS ${PC_lz4_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(lz4_LIBRARY
|
||||
NAMES lz4
|
||||
PATHS ${PC_lz4_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(lz4_INCLUDE_DIR)
|
||||
file(STRINGS "${lz4_INCLUDE_DIR}/lz4.h" _lz4_version_lines
|
||||
REGEX "#define[ \t]+LZ4_VERSION_(MAJOR|MINOR|RELEASE)")
|
||||
string(REGEX REPLACE ".*LZ4_VERSION_MAJOR *\([0-9]*\).*" "\\1" _lz4_version_major "${_lz4_version_lines}")
|
||||
string(REGEX REPLACE ".*LZ4_VERSION_MINOR *\([0-9]*\).*" "\\1" _lz4_version_minor "${_lz4_version_lines}")
|
||||
string(REGEX REPLACE ".*LZ4_VERSION_RELEASE *\([0-9]*\).*" "\\1" _lz4_version_release "${_lz4_version_lines}")
|
||||
set(lz4_VERSION "${_lz4_version_major}.${_lz4_version_minor}.${_lz4_version_release}")
|
||||
unset(_lz4_version_major)
|
||||
unset(_lz4_version_minor)
|
||||
unset(_lz4_version_release)
|
||||
unset(_lz4_version_lines)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(lz4
|
||||
FOUND_VAR lz4_FOUND
|
||||
REQUIRED_VARS
|
||||
lz4_LIBRARY
|
||||
lz4_INCLUDE_DIR
|
||||
VERSION_VAR lz4_VERSION
|
||||
)
|
||||
|
||||
if(lz4_FOUND)
|
||||
set(lz4_LIBRARIES ${lz4_LIBRARY})
|
||||
set(lz4_INCLUDE_DIRS ${lz4_INCLUDE_DIR})
|
||||
set(lz4_DEFINITIONS ${PC_lz4_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(lz4_FOUND AND NOT TARGET lz4::lz4)
|
||||
add_library(lz4::lz4 UNKNOWN IMPORTED)
|
||||
set_target_properties(lz4::lz4 PROPERTIES
|
||||
IMPORTED_LOCATION "${lz4_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_lz4_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${lz4_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
lz4_INCLUDE_DIR
|
||||
lz4_LIBRARY
|
||||
)
|
||||
49
externals/find-modules/Findnlohmann_json.cmake
vendored
Normal file
49
externals/find-modules/Findnlohmann_json.cmake
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_nlohmann_json QUIET nlohmann_json)
|
||||
|
||||
find_path(nlohmann_json_INCLUDE_DIR
|
||||
NAMES json.hpp
|
||||
PATHS ${PC_nlohmann_json_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES nlohmann
|
||||
)
|
||||
|
||||
if(nlohmann_json_INCLUDE_DIR)
|
||||
file(STRINGS "${nlohmann_json_INCLUDE_DIR}/json.hpp" _nlohmann_json_version_lines
|
||||
REGEX "#define[ \t]+NLOHMANN_JSON_VERSION_(MAJOR|MINOR|PATCH)")
|
||||
string(REGEX REPLACE ".*NLOHMANN_JSON_VERSION_MAJOR +\([0-9]+\).*" "\\1" _nlohmann_json_version_major "${_nlohmann_json_version_lines}")
|
||||
string(REGEX REPLACE ".*NLOHMANN_JSON_VERSION_MINOR +\([0-9]+\).*" "\\1" _nlohmann_json_version_minor "${_nlohmann_json_version_lines}")
|
||||
string(REGEX REPLACE ".*NLOHMANN_JSON_VERSION_PATCH +\([0-9]+\).*" "\\1" _nlohmann_json_version_patch "${_nlohmann_json_version_lines}")
|
||||
set(nlohmann_json_VERSION "${_nlohmann_json_version_major}.${_nlohmann_json_version_minor}.${_nlohmann_json_version_patch}")
|
||||
unset(_nlohmann_json_version_major)
|
||||
unset(_nlohmann_json_version_minor)
|
||||
unset(_nlohmann_json_version_patch)
|
||||
unset(_nlohmann_json_version_lines)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(nlohmann_json
|
||||
FOUND_VAR nlohmann_json_FOUND
|
||||
REQUIRED_VARS
|
||||
nlohmann_json_INCLUDE_DIR
|
||||
nlohmann_json_VERSION
|
||||
VERSION_VAR nlohmann_json_VERSION
|
||||
)
|
||||
|
||||
if(nlohmann_json_FOUND)
|
||||
set(nlohmann_json_INCLUDE_DIRS ${nlohmann_json_INCLUDE_DIR})
|
||||
set(nlohmann_json_DEFINITIONS ${PC_nlohmann_json_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(nlohmann_json_FOUND AND NOT TARGET nlohmann_json::nlohmann_json)
|
||||
add_library(nlohmann_json::nlohmann_json UNKNOWN IMPORTED)
|
||||
set_target_properties(nlohmann_json::nlohmann_json PROPERTIES
|
||||
IMPORTED_LOCATION "${nlohmann_json_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_nlohmann_json_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${nlohmann_json_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
nlohmann_json_INCLUDE_DIR
|
||||
)
|
||||
42
externals/find-modules/Findopus.cmake
vendored
Normal file
42
externals/find-modules/Findopus.cmake
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_opus QUIET opus)
|
||||
|
||||
find_path(opus_INCLUDE_DIR
|
||||
NAMES opus.h
|
||||
PATHS ${PC_opus_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES opus
|
||||
)
|
||||
find_library(opus_LIBRARY
|
||||
NAMES opus
|
||||
PATHS ${PC_opus_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(opus
|
||||
FOUND_VAR opus_FOUND
|
||||
REQUIRED_VARS
|
||||
opus_LIBRARY
|
||||
opus_INCLUDE_DIR
|
||||
VERSION_VAR opus_VERSION
|
||||
)
|
||||
|
||||
if(opus_FOUND)
|
||||
set(Opus_LIBRARIES ${opus_LIBRARY})
|
||||
set(Opus_INCLUDE_DIRS ${opus_INCLUDE_DIR})
|
||||
set(Opus_DEFINITIONS ${PC_opus_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(opus_FOUND AND NOT TARGET Opus::Opus)
|
||||
add_library(Opus::Opus UNKNOWN IMPORTED)
|
||||
set_target_properties(Opus::Opus PROPERTIES
|
||||
IMPORTED_LOCATION "${opus_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_opus_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${opus_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
opus_INCLUDE_DIR
|
||||
opus_LIBRARY
|
||||
)
|
||||
55
externals/find-modules/Findzstd.cmake
vendored
Normal file
55
externals/find-modules/Findzstd.cmake
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_zstd QUIET libzstd)
|
||||
|
||||
find_path(zstd_INCLUDE_DIR
|
||||
NAMES zstd.h
|
||||
PATHS ${PC_zstd_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(zstd_LIBRARY
|
||||
NAMES zstd
|
||||
PATHS ${PC_zstd_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(zstd_INCLUDE_DIR)
|
||||
file(STRINGS "${zstd_INCLUDE_DIR}/zstd.h" _zstd_version_lines
|
||||
REGEX "#define[ \t]+ZSTD_VERSION_(MAJOR|MINOR|RELEASE)")
|
||||
string(REGEX REPLACE ".*ZSTD_VERSION_MAJOR *\([0-9]*\).*" "\\1" _zstd_version_major "${_zstd_version_lines}")
|
||||
string(REGEX REPLACE ".*ZSTD_VERSION_MINOR *\([0-9]*\).*" "\\1" _zstd_version_minor "${_zstd_version_lines}")
|
||||
string(REGEX REPLACE ".*ZSTD_VERSION_RELEASE *\([0-9]*\).*" "\\1" _zstd_version_release "${_zstd_version_lines}")
|
||||
set(zstd_VERSION "${_zstd_version_major}.${_zstd_version_minor}.${_zstd_version_release}")
|
||||
unset(_zstd_version_major)
|
||||
unset(_zstd_version_minor)
|
||||
unset(_zstd_version_release)
|
||||
unset(_zstd_version_lines)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(zstd
|
||||
FOUND_VAR zstd_FOUND
|
||||
REQUIRED_VARS
|
||||
zstd_LIBRARY
|
||||
zstd_INCLUDE_DIR
|
||||
zstd_VERSION
|
||||
VERSION_VAR zstd_VERSION
|
||||
)
|
||||
|
||||
if(zstd_FOUND)
|
||||
set(zstd_LIBRARIES ${zstd_LIBRARY})
|
||||
set(zstd_INCLUDE_DIRS ${zstd_INCLUDE_DIR})
|
||||
set(zstd_DEFINITIONS ${PC_zstd_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(zstd_FOUND AND NOT TARGET zstd::zstd)
|
||||
add_library(zstd::zstd UNKNOWN IMPORTED)
|
||||
set_target_properties(zstd::zstd PROPERTIES
|
||||
IMPORTED_LOCATION "${zstd_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_zstd_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${zstd_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
zstd_INCLUDE_DIR
|
||||
zstd_LIBRARY
|
||||
)
|
||||
1
externals/fmt
vendored
1
externals/fmt
vendored
Submodule externals/fmt deleted from 9bdd1596ce
9
externals/json/README.md
vendored
9
externals/json/README.md
vendored
@@ -1,9 +0,0 @@
|
||||
JSON for Modern C++
|
||||
===================
|
||||
|
||||
v3.1.2
|
||||
|
||||
This is a mirror providing the single required header file.
|
||||
|
||||
The original repository can be found at:
|
||||
https://github.com/nlohmann/json/commit/d2dd27dc3b8472dbaa7d66f83619b3ebcd9185fe
|
||||
17300
externals/json/json.hpp
vendored
17300
externals/json/json.hpp
vendored
File diff suppressed because it is too large
Load Diff
1
externals/libressl
vendored
1
externals/libressl
vendored
Submodule externals/libressl deleted from 7d01cb01cb
1
externals/lz4
vendored
1
externals/lz4
vendored
Submodule externals/lz4 deleted from 4db65c1d99
254
externals/opus/CMakeLists.txt
vendored
254
externals/opus/CMakeLists.txt
vendored
@@ -1,254 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(opus)
|
||||
|
||||
option(OPUS_STACK_PROTECTOR "Use stack protection" OFF)
|
||||
option(OPUS_USE_ALLOCA "Use alloca for stack arrays (on non-C99 compilers)" OFF)
|
||||
option(OPUS_CUSTOM_MODES "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames" OFF)
|
||||
option(OPUS_FIXED_POINT "Compile as fixed-point (for machines without a fast enough FPU)" OFF)
|
||||
option(OPUS_ENABLE_FLOAT_API "Compile with the floating point API (for machines with float library" ON)
|
||||
|
||||
include(opus/opus_functions.cmake)
|
||||
|
||||
if(OPUS_STACK_PROTECTOR)
|
||||
if(NOT MSVC) # GC on by default on MSVC
|
||||
check_and_set_flag(STACK_PROTECTION_STRONG -fstack-protector-strong)
|
||||
endif()
|
||||
else()
|
||||
if(MSVC)
|
||||
check_and_set_flag(BUFFER_SECURITY_CHECK /GS-)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(opus STATIC
|
||||
# CELT sources
|
||||
opus/celt/bands.c
|
||||
opus/celt/celt.c
|
||||
opus/celt/celt_decoder.c
|
||||
opus/celt/celt_encoder.c
|
||||
opus/celt/celt_lpc.c
|
||||
opus/celt/cwrs.c
|
||||
opus/celt/entcode.c
|
||||
opus/celt/entdec.c
|
||||
opus/celt/entenc.c
|
||||
opus/celt/kiss_fft.c
|
||||
opus/celt/laplace.c
|
||||
opus/celt/mathops.c
|
||||
opus/celt/mdct.c
|
||||
opus/celt/modes.c
|
||||
opus/celt/pitch.c
|
||||
opus/celt/quant_bands.c
|
||||
opus/celt/rate.c
|
||||
opus/celt/vq.c
|
||||
|
||||
# SILK sources
|
||||
opus/silk/A2NLSF.c
|
||||
opus/silk/CNG.c
|
||||
opus/silk/HP_variable_cutoff.c
|
||||
opus/silk/LPC_analysis_filter.c
|
||||
opus/silk/LPC_fit.c
|
||||
opus/silk/LPC_inv_pred_gain.c
|
||||
opus/silk/LP_variable_cutoff.c
|
||||
opus/silk/NLSF2A.c
|
||||
opus/silk/NLSF_VQ.c
|
||||
opus/silk/NLSF_VQ_weights_laroia.c
|
||||
opus/silk/NLSF_decode.c
|
||||
opus/silk/NLSF_del_dec_quant.c
|
||||
opus/silk/NLSF_encode.c
|
||||
opus/silk/NLSF_stabilize.c
|
||||
opus/silk/NLSF_unpack.c
|
||||
opus/silk/NSQ.c
|
||||
opus/silk/NSQ_del_dec.c
|
||||
opus/silk/PLC.c
|
||||
opus/silk/VAD.c
|
||||
opus/silk/VQ_WMat_EC.c
|
||||
opus/silk/ana_filt_bank_1.c
|
||||
opus/silk/biquad_alt.c
|
||||
opus/silk/bwexpander.c
|
||||
opus/silk/bwexpander_32.c
|
||||
opus/silk/check_control_input.c
|
||||
opus/silk/code_signs.c
|
||||
opus/silk/control_SNR.c
|
||||
opus/silk/control_audio_bandwidth.c
|
||||
opus/silk/control_codec.c
|
||||
opus/silk/dec_API.c
|
||||
opus/silk/decode_core.c
|
||||
opus/silk/decode_frame.c
|
||||
opus/silk/decode_indices.c
|
||||
opus/silk/decode_parameters.c
|
||||
opus/silk/decode_pitch.c
|
||||
opus/silk/decode_pulses.c
|
||||
opus/silk/decoder_set_fs.c
|
||||
opus/silk/enc_API.c
|
||||
opus/silk/encode_indices.c
|
||||
opus/silk/encode_pulses.c
|
||||
opus/silk/gain_quant.c
|
||||
opus/silk/init_decoder.c
|
||||
opus/silk/init_encoder.c
|
||||
opus/silk/inner_prod_aligned.c
|
||||
opus/silk/interpolate.c
|
||||
opus/silk/lin2log.c
|
||||
opus/silk/log2lin.c
|
||||
opus/silk/pitch_est_tables.c
|
||||
opus/silk/process_NLSFs.c
|
||||
opus/silk/quant_LTP_gains.c
|
||||
opus/silk/resampler.c
|
||||
opus/silk/resampler_down2.c
|
||||
opus/silk/resampler_down2_3.c
|
||||
opus/silk/resampler_private_AR2.c
|
||||
opus/silk/resampler_private_IIR_FIR.c
|
||||
opus/silk/resampler_private_down_FIR.c
|
||||
opus/silk/resampler_private_up2_HQ.c
|
||||
opus/silk/resampler_rom.c
|
||||
opus/silk/shell_coder.c
|
||||
opus/silk/sigm_Q15.c
|
||||
opus/silk/sort.c
|
||||
opus/silk/stereo_LR_to_MS.c
|
||||
opus/silk/stereo_MS_to_LR.c
|
||||
opus/silk/stereo_decode_pred.c
|
||||
opus/silk/stereo_encode_pred.c
|
||||
opus/silk/stereo_find_predictor.c
|
||||
opus/silk/stereo_quant_pred.c
|
||||
opus/silk/sum_sqr_shift.c
|
||||
opus/silk/table_LSF_cos.c
|
||||
opus/silk/tables_LTP.c
|
||||
opus/silk/tables_NLSF_CB_NB_MB.c
|
||||
opus/silk/tables_NLSF_CB_WB.c
|
||||
opus/silk/tables_gain.c
|
||||
opus/silk/tables_other.c
|
||||
opus/silk/tables_pitch_lag.c
|
||||
opus/silk/tables_pulses_per_block.c
|
||||
|
||||
# Opus sources
|
||||
opus/src/analysis.c
|
||||
opus/src/mapping_matrix.c
|
||||
opus/src/mlp.c
|
||||
opus/src/mlp_data.c
|
||||
opus/src/opus.c
|
||||
opus/src/opus_decoder.c
|
||||
opus/src/opus_encoder.c
|
||||
opus/src/opus_multistream.c
|
||||
opus/src/opus_multistream_decoder.c
|
||||
opus/src/opus_multistream_encoder.c
|
||||
opus/src/opus_projection_decoder.c
|
||||
opus/src/opus_projection_encoder.c
|
||||
opus/src/repacketizer.c
|
||||
)
|
||||
|
||||
if (DEBUG)
|
||||
target_sources(opus PRIVATE opus/silk/debug.c)
|
||||
endif()
|
||||
|
||||
if (OPUS_FIXED_POINT)
|
||||
target_sources(opus PRIVATE
|
||||
opus/silk/fixed/LTP_analysis_filter_FIX.c
|
||||
opus/silk/fixed/LTP_scale_ctrl_FIX.c
|
||||
opus/silk/fixed/apply_sine_window_FIX.c
|
||||
opus/silk/fixed/autocorr_FIX.c
|
||||
opus/silk/fixed/burg_modified_FIX.c
|
||||
opus/silk/fixed/corrMatrix_FIX.c
|
||||
opus/silk/fixed/encode_frame_FIX.c
|
||||
opus/silk/fixed/find_LPC_FIX.c
|
||||
opus/silk/fixed/find_LTP_FIX.c
|
||||
opus/silk/fixed/find_pitch_lags_FIX.c
|
||||
opus/silk/fixed/find_pred_coefs_FIX.c
|
||||
opus/silk/fixed/k2a_FIX.c
|
||||
opus/silk/fixed/k2a_Q16_FIX.c
|
||||
opus/silk/fixed/noise_shape_analysis_FIX.c
|
||||
opus/silk/fixed/pitch_analysis_core_FIX.c
|
||||
opus/silk/fixed/prefilter_FIX.c
|
||||
opus/silk/fixed/process_gains_FIX.c
|
||||
opus/silk/fixed/regularize_correlations_FIX.c
|
||||
opus/silk/fixed/residual_energy16_FIX.c
|
||||
opus/silk/fixed/residual_energy_FIX.c
|
||||
opus/silk/fixed/schur64_FIX.c
|
||||
opus/silk/fixed/schur_FIX.c
|
||||
opus/silk/fixed/solve_LS_FIX.c
|
||||
opus/silk/fixed/vector_ops_FIX.c
|
||||
opus/silk/fixed/warped_autocorrelation_FIX.c
|
||||
)
|
||||
else()
|
||||
target_sources(opus PRIVATE
|
||||
opus/silk/float/LPC_analysis_filter_FLP.c
|
||||
opus/silk/float/LPC_inv_pred_gain_FLP.c
|
||||
opus/silk/float/LTP_analysis_filter_FLP.c
|
||||
opus/silk/float/LTP_scale_ctrl_FLP.c
|
||||
opus/silk/float/apply_sine_window_FLP.c
|
||||
opus/silk/float/autocorrelation_FLP.c
|
||||
opus/silk/float/burg_modified_FLP.c
|
||||
opus/silk/float/bwexpander_FLP.c
|
||||
opus/silk/float/corrMatrix_FLP.c
|
||||
opus/silk/float/encode_frame_FLP.c
|
||||
opus/silk/float/energy_FLP.c
|
||||
opus/silk/float/find_LPC_FLP.c
|
||||
opus/silk/float/find_LTP_FLP.c
|
||||
opus/silk/float/find_pitch_lags_FLP.c
|
||||
opus/silk/float/find_pred_coefs_FLP.c
|
||||
opus/silk/float/inner_product_FLP.c
|
||||
opus/silk/float/k2a_FLP.c
|
||||
opus/silk/float/noise_shape_analysis_FLP.c
|
||||
opus/silk/float/pitch_analysis_core_FLP.c
|
||||
opus/silk/float/process_gains_FLP.c
|
||||
opus/silk/float/regularize_correlations_FLP.c
|
||||
opus/silk/float/residual_energy_FLP.c
|
||||
opus/silk/float/scale_copy_vector_FLP.c
|
||||
opus/silk/float/scale_vector_FLP.c
|
||||
opus/silk/float/schur_FLP.c
|
||||
opus/silk/float/sort_FLP.c
|
||||
opus/silk/float/warped_autocorrelation_FLP.c
|
||||
opus/silk/float/wrappers_FLP.c
|
||||
)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(opus PRIVATE OPUS_BUILD ENABLE_HARDENING)
|
||||
|
||||
if(NOT MSVC)
|
||||
if(MINGW)
|
||||
target_compile_definitions(opus PRIVATE _FORTIFY_SOURCE=0)
|
||||
else()
|
||||
target_compile_definitions(opus PRIVATE _FORTIFY_SOURCE=2)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# It is strongly recommended to uncomment one of these VAR_ARRAYS: Use C99
|
||||
# variable-length arrays for stack allocation USE_ALLOCA: Use alloca() for stack
|
||||
# allocation If none is defined, then the fallback is a non-threadsafe global
|
||||
# array
|
||||
if(OPUS_USE_ALLOCA OR MSVC)
|
||||
target_compile_definitions(opus PRIVATE USE_ALLOCA)
|
||||
else()
|
||||
target_compile_definitions(opus PRIVATE VAR_ARRAYS)
|
||||
endif()
|
||||
|
||||
if(OPUS_CUSTOM_MODES)
|
||||
target_compile_definitions(opus PRIVATE CUSTOM_MODES)
|
||||
endif()
|
||||
|
||||
if(NOT OPUS_ENABLE_FLOAT_API)
|
||||
target_compile_definitions(opus PRIVATE DISABLE_FLOAT_API)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(opus
|
||||
PUBLIC
|
||||
-DOPUS_VERSION="\\"1.3.1\\""
|
||||
|
||||
PRIVATE
|
||||
# Use C99 intrinsics to speed up float-to-int conversion
|
||||
HAVE_LRINTF
|
||||
)
|
||||
|
||||
if (FIXED_POINT)
|
||||
target_compile_definitions(opus PRIVATE -DFIXED_POINT=1 -DDISABLE_FLOAT_API)
|
||||
endif()
|
||||
|
||||
target_include_directories(opus
|
||||
PUBLIC
|
||||
opus/include
|
||||
|
||||
PRIVATE
|
||||
opus/celt
|
||||
opus/silk
|
||||
opus/silk/fixed
|
||||
opus/silk/float
|
||||
opus/src
|
||||
)
|
||||
1
externals/opus/opus
vendored
1
externals/opus/opus
vendored
Submodule externals/opus/opus deleted from ad8fe90db7
2
externals/sirit
vendored
2
externals/sirit
vendored
Submodule externals/sirit updated: a712959f1e...414fc4dbd2
81
externals/zlib/CMakeLists.txt
vendored
81
externals/zlib/CMakeLists.txt
vendored
@@ -1,81 +0,0 @@
|
||||
project(zlib C)
|
||||
|
||||
include(CheckTypeSize)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFile)
|
||||
|
||||
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_include_file(stdint.h HAVE_STDINT_H)
|
||||
check_include_file(stddef.h HAVE_STDDEF_H)
|
||||
|
||||
# Check to see if we have large file support
|
||||
set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
|
||||
# We add these other definitions here because CheckTypeSize.cmake
|
||||
# in CMake 2.4.x does not automatically do so and we want
|
||||
# compatibility with CMake 2.4.x.
|
||||
if(HAVE_SYS_TYPES_H)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
|
||||
endif()
|
||||
if(HAVE_STDINT_H)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
|
||||
endif()
|
||||
if(HAVE_STDDEF_H)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
|
||||
endif()
|
||||
check_type_size(off64_t OFF64_T)
|
||||
if(HAVE_OFF64_T)
|
||||
add_definitions(-D_LARGEFILE64_SOURCE=1)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
|
||||
|
||||
# Check for fseeko
|
||||
check_function_exists(fseeko HAVE_FSEEKO)
|
||||
if(NOT HAVE_FSEEKO)
|
||||
add_definitions(-DNO_FSEEKO)
|
||||
endif()
|
||||
|
||||
# Check for unistd.h
|
||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||
if(HAVE_UNISTD_H)
|
||||
add_definitions(-DHAVE_UNISTD_H)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
endif()
|
||||
|
||||
add_library(z STATIC
|
||||
zlib/adler32.c
|
||||
zlib/compress.c
|
||||
zlib/crc32.c
|
||||
zlib/crc32.h
|
||||
zlib/deflate.c
|
||||
zlib/deflate.h
|
||||
zlib/gzclose.c
|
||||
zlib/gzguts.h
|
||||
zlib/gzlib.c
|
||||
zlib/gzread.c
|
||||
zlib/gzwrite.c
|
||||
zlib/inffast.h
|
||||
zlib/inffixed.h
|
||||
zlib/inflate.c
|
||||
zlib/inflate.h
|
||||
zlib/infback.c
|
||||
zlib/inftrees.c
|
||||
zlib/inftrees.h
|
||||
zlib/inffast.c
|
||||
zlib/trees.c
|
||||
zlib/trees.h
|
||||
zlib/uncompr.c
|
||||
zlib/zconf.h
|
||||
zlib/zlib.h
|
||||
zlib/zutil.c
|
||||
zlib/zutil.h
|
||||
)
|
||||
add_library(ZLIB::ZLIB ALIAS z)
|
||||
|
||||
target_include_directories(z
|
||||
PUBLIC
|
||||
zlib/
|
||||
)
|
||||
1
externals/zlib/zlib
vendored
1
externals/zlib/zlib
vendored
Submodule externals/zlib/zlib deleted from cacf7f1d4e
1
externals/zstd
vendored
1
externals/zstd
vendored
Submodule externals/zstd deleted from 470344d33e
@@ -17,7 +17,7 @@ namespace AudioCore {
|
||||
|
||||
constexpr u32 STREAM_SAMPLE_RATE{48000};
|
||||
constexpr u32 STREAM_NUM_CHANNELS{2};
|
||||
|
||||
using VoiceChannelHolder = std::array<VoiceResourceInformation*, 6>;
|
||||
class AudioRenderer::VoiceState {
|
||||
public:
|
||||
bool IsPlaying() const {
|
||||
@@ -37,9 +37,10 @@ public:
|
||||
}
|
||||
|
||||
void SetWaveIndex(std::size_t index);
|
||||
std::vector<s16> DequeueSamples(std::size_t sample_count, Core::Memory::Memory& memory);
|
||||
std::vector<s16> DequeueSamples(std::size_t sample_count, Core::Memory::Memory& memory,
|
||||
const VoiceChannelHolder& voice_resources);
|
||||
void UpdateState();
|
||||
void RefreshBuffer(Core::Memory::Memory& memory);
|
||||
void RefreshBuffer(Core::Memory::Memory& memory, const VoiceChannelHolder& voice_resources);
|
||||
|
||||
private:
|
||||
bool is_in_use{};
|
||||
@@ -79,7 +80,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event,
|
||||
std::size_t instance_number)
|
||||
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count),
|
||||
effects(params.effect_count), memory{memory_} {
|
||||
voice_resources(params.voice_count), effects(params.effect_count), memory{memory_} {
|
||||
behavior_info.SetUserRevision(params.revision);
|
||||
audio_out = std::make_unique<AudioCore::AudioOut>();
|
||||
stream = audio_out->OpenStream(core_timing, STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS,
|
||||
@@ -127,6 +128,12 @@ ResultVal<std::vector<u8>> AudioRenderer::UpdateAudioRenderer(const std::vector<
|
||||
input_params.data() + sizeof(UpdateDataHeader) + config.behavior_size,
|
||||
memory_pool_count * sizeof(MemoryPoolInfo));
|
||||
|
||||
// Copy voice resources
|
||||
const std::size_t voice_resource_offset{sizeof(UpdateDataHeader) + config.behavior_size +
|
||||
config.memory_pools_size};
|
||||
std::memcpy(voice_resources.data(), input_params.data() + voice_resource_offset,
|
||||
sizeof(VoiceResourceInformation) * voice_resources.size());
|
||||
|
||||
// Copy VoiceInfo structs
|
||||
std::size_t voice_offset{sizeof(UpdateDataHeader) + config.behavior_size +
|
||||
config.memory_pools_size + config.voice_resource_size};
|
||||
@@ -220,14 +227,15 @@ void AudioRenderer::VoiceState::SetWaveIndex(std::size_t index) {
|
||||
is_refresh_pending = true;
|
||||
}
|
||||
|
||||
std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count,
|
||||
Core::Memory::Memory& memory) {
|
||||
std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(
|
||||
std::size_t sample_count, Core::Memory::Memory& memory,
|
||||
const VoiceChannelHolder& voice_resources) {
|
||||
if (!IsPlaying()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (is_refresh_pending) {
|
||||
RefreshBuffer(memory);
|
||||
RefreshBuffer(memory, voice_resources);
|
||||
}
|
||||
|
||||
const std::size_t max_size{samples.size() - offset};
|
||||
@@ -271,7 +279,8 @@ void AudioRenderer::VoiceState::UpdateState() {
|
||||
is_in_use = info.is_in_use;
|
||||
}
|
||||
|
||||
void AudioRenderer::VoiceState::RefreshBuffer(Core::Memory::Memory& memory) {
|
||||
void AudioRenderer::VoiceState::RefreshBuffer(Core::Memory::Memory& memory,
|
||||
const VoiceChannelHolder& voice_resources) {
|
||||
const auto wave_buffer_address = info.wave_buffer[wave_index].buffer_addr;
|
||||
const auto wave_buffer_size = info.wave_buffer[wave_index].buffer_sz;
|
||||
std::vector<s16> new_samples(wave_buffer_size / sizeof(s16));
|
||||
@@ -296,17 +305,77 @@ void AudioRenderer::VoiceState::RefreshBuffer(Core::Memory::Memory& memory) {
|
||||
}
|
||||
|
||||
switch (info.channel_count) {
|
||||
case 1:
|
||||
case 1: {
|
||||
// 1 channel is upsampled to 2 channel
|
||||
samples.resize(new_samples.size() * 2);
|
||||
|
||||
for (std::size_t index = 0; index < new_samples.size(); ++index) {
|
||||
samples[index * 2] = new_samples[index];
|
||||
samples[index * 2 + 1] = new_samples[index];
|
||||
auto sample = static_cast<float>(new_samples[index]);
|
||||
if (voice_resources[0]->in_use) {
|
||||
sample *= voice_resources[0]->mix_volumes[0];
|
||||
}
|
||||
|
||||
samples[index * 2] = static_cast<s16>(sample * info.volume);
|
||||
samples[index * 2 + 1] = static_cast<s16>(sample * info.volume);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// 2 channel is played as is
|
||||
samples = std::move(new_samples);
|
||||
const std::size_t sample_count = (samples.size() / 2);
|
||||
for (std::size_t index = 0; index < sample_count; ++index) {
|
||||
const std::size_t index_l = index * 2;
|
||||
const std::size_t index_r = index * 2 + 1;
|
||||
|
||||
auto sample_l = static_cast<float>(samples[index_l]);
|
||||
auto sample_r = static_cast<float>(samples[index_r]);
|
||||
|
||||
if (voice_resources[0]->in_use) {
|
||||
sample_l *= voice_resources[0]->mix_volumes[0];
|
||||
}
|
||||
|
||||
if (voice_resources[1]->in_use) {
|
||||
sample_r *= voice_resources[1]->mix_volumes[1];
|
||||
}
|
||||
|
||||
samples[index_l] = static_cast<s16>(sample_l * info.volume);
|
||||
samples[index_r] = static_cast<s16>(sample_r * info.volume);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
samples.resize((new_samples.size() / 6) * 2);
|
||||
const std::size_t sample_count = samples.size() / 2;
|
||||
|
||||
for (std::size_t index = 0; index < sample_count; ++index) {
|
||||
auto FL = static_cast<float>(new_samples[index * 6]);
|
||||
auto FR = static_cast<float>(new_samples[index * 6 + 1]);
|
||||
auto FC = static_cast<float>(new_samples[index * 6 + 2]);
|
||||
auto BL = static_cast<float>(new_samples[index * 6 + 4]);
|
||||
auto BR = static_cast<float>(new_samples[index * 6 + 5]);
|
||||
|
||||
if (voice_resources[0]->in_use) {
|
||||
FL *= voice_resources[0]->mix_volumes[0];
|
||||
}
|
||||
if (voice_resources[1]->in_use) {
|
||||
FR *= voice_resources[1]->mix_volumes[1];
|
||||
}
|
||||
if (voice_resources[2]->in_use) {
|
||||
FC *= voice_resources[2]->mix_volumes[2];
|
||||
}
|
||||
if (voice_resources[4]->in_use) {
|
||||
BL *= voice_resources[4]->mix_volumes[4];
|
||||
}
|
||||
if (voice_resources[5]->in_use) {
|
||||
BR *= voice_resources[5]->mix_volumes[5];
|
||||
}
|
||||
|
||||
samples[index * 2] =
|
||||
static_cast<s16>((0.3694f * FL + 0.2612f * FC + 0.3694f * BL) * info.volume);
|
||||
samples[index * 2 + 1] =
|
||||
static_cast<s16>((0.3694f * FR + 0.2612f * FC + 0.3694f * BR) * info.volume);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -352,11 +421,17 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
|
||||
if (!voice.IsPlaying()) {
|
||||
continue;
|
||||
}
|
||||
VoiceChannelHolder resources{};
|
||||
for (u32 channel = 0; channel < voice.GetInfo().channel_count; channel++) {
|
||||
const auto channel_resource_id = voice.GetInfo().voice_channel_resource_ids[channel];
|
||||
resources[channel] = &voice_resources[channel_resource_id];
|
||||
}
|
||||
|
||||
std::size_t offset{};
|
||||
s64 samples_remaining{BUFFER_SIZE};
|
||||
while (samples_remaining > 0) {
|
||||
const std::vector<s16> samples{voice.DequeueSamples(samples_remaining, memory)};
|
||||
const std::vector<s16> samples{
|
||||
voice.DequeueSamples(samples_remaining, memory, resources)};
|
||||
|
||||
if (samples.empty()) {
|
||||
break;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "audio_core/behavior_info.h"
|
||||
#include "audio_core/common.h"
|
||||
#include "audio_core/stream.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
@@ -116,6 +117,14 @@ struct WaveBuffer {
|
||||
};
|
||||
static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
|
||||
|
||||
struct VoiceResourceInformation {
|
||||
s32_le id{};
|
||||
std::array<float_le, MAX_MIX_BUFFERS> mix_volumes{};
|
||||
bool in_use{};
|
||||
INSERT_PADDING_BYTES(11);
|
||||
};
|
||||
static_assert(sizeof(VoiceResourceInformation) == 0x70, "VoiceResourceInformation has wrong size");
|
||||
|
||||
struct VoiceInfo {
|
||||
u32_le id;
|
||||
u32_le node_id;
|
||||
@@ -244,6 +253,7 @@ private:
|
||||
AudioRendererParameter worker_params;
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event;
|
||||
std::vector<VoiceState> voices;
|
||||
std::vector<VoiceResourceInformation> voice_resources;
|
||||
std::vector<EffectState> effects;
|
||||
std::unique_ptr<AudioOut> audio_out;
|
||||
StreamPtr stream;
|
||||
|
||||
@@ -14,6 +14,7 @@ constexpr ResultCode ERR_INVALID_PARAMETERS{ErrorModule::Audio, 41};
|
||||
}
|
||||
|
||||
constexpr u32_le CURRENT_PROCESS_REVISION = Common::MakeMagic('R', 'E', 'V', '8');
|
||||
constexpr std::size_t MAX_MIX_BUFFERS = 24;
|
||||
|
||||
static constexpr u32 VersionFromRevision(u32_le rev) {
|
||||
// "REV7" -> 7
|
||||
|
||||
@@ -148,6 +148,8 @@ add_library(common STATIC
|
||||
thread.h
|
||||
thread_queue_list.h
|
||||
threadsafe_queue.h
|
||||
time_zone.cpp
|
||||
time_zone.h
|
||||
timer.cpp
|
||||
timer.h
|
||||
uint128.cpp
|
||||
@@ -172,5 +174,5 @@ endif()
|
||||
|
||||
create_target_directory_groups(common)
|
||||
|
||||
target_link_libraries(common PUBLIC Boost::boost fmt microprofile)
|
||||
target_link_libraries(common PRIVATE lz4_static libzstd_static)
|
||||
target_link_libraries(common PUBLIC Boost::boost fmt::fmt microprofile)
|
||||
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd)
|
||||
|
||||
49
src/common/time_zone.cpp
Normal file
49
src/common/time_zone.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "common/time_zone.h"
|
||||
|
||||
namespace Common::TimeZone {
|
||||
|
||||
std::string GetDefaultTimeZone() {
|
||||
return "GMT";
|
||||
}
|
||||
|
||||
static std::string GetOsTimeZoneOffset() {
|
||||
const std::time_t t{std::time(nullptr)};
|
||||
const std::tm tm{*std::localtime(&t)};
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(&tm, "%z"); // Get the current timezone offset, e.g. "-400", as a string
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) {
|
||||
try {
|
||||
return std::stoi(timezone);
|
||||
} catch (const std::invalid_argument&) {
|
||||
LOG_CRITICAL(Common, "invalid_argument with {}!", timezone);
|
||||
return 0;
|
||||
} catch (const std::out_of_range&) {
|
||||
LOG_CRITICAL(Common, "out_of_range with {}!", timezone);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::chrono::seconds GetCurrentOffsetSeconds() {
|
||||
const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())};
|
||||
|
||||
int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds
|
||||
seconds += (offset % 100) * 60; // Convert minute component to seconds
|
||||
|
||||
return std::chrono::seconds{seconds};
|
||||
}
|
||||
|
||||
} // namespace Common::TimeZone
|
||||
18
src/common/time_zone.h
Normal file
18
src/common/time_zone.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace Common::TimeZone {
|
||||
|
||||
/// Gets the default timezone, i.e. "GMT"
|
||||
std::string GetDefaultTimeZone();
|
||||
|
||||
/// Gets the offset of the current timezone (from the default), in seconds
|
||||
std::chrono::seconds GetCurrentOffsetSeconds();
|
||||
|
||||
} // namespace Common::TimeZone
|
||||
@@ -40,6 +40,11 @@ struct UUID {
|
||||
uuid = INVALID_UUID;
|
||||
}
|
||||
|
||||
// TODO(ogniK): Properly generate a Nintendo ID
|
||||
constexpr u64 GetNintendoID() const {
|
||||
return uuid[0];
|
||||
}
|
||||
|
||||
std::string Format() const;
|
||||
std::string FormatSwitch() const;
|
||||
};
|
||||
|
||||
@@ -606,11 +606,11 @@ 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 json-headers mbedtls opus unicorn)
|
||||
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus unicorn)
|
||||
|
||||
if (YUZU_ENABLE_BOXCAT)
|
||||
target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT)
|
||||
target_link_libraries(core PRIVATE httplib json-headers zip)
|
||||
target_link_libraries(core PRIVATE httplib nlohmann_json::nlohmann_json zip)
|
||||
endif()
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
|
||||
@@ -185,10 +185,9 @@ void ARM_Dynarmic_64::Step() {
|
||||
|
||||
ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, ExclusiveMonitor& exclusive_monitor,
|
||||
std::size_t core_index)
|
||||
: ARM_Interface{system},
|
||||
cb(std::make_unique<DynarmicCallbacks64>(*this)), inner_unicorn{system},
|
||||
core_index{core_index}, exclusive_monitor{
|
||||
dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
|
||||
: ARM_Interface{system}, cb(std::make_unique<DynarmicCallbacks64>(*this)),
|
||||
inner_unicorn{system, ARM_Unicorn::Arch::AArch64}, core_index{core_index},
|
||||
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
|
||||
|
||||
ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;
|
||||
|
||||
|
||||
@@ -62,8 +62,9 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
|
||||
return false;
|
||||
}
|
||||
|
||||
ARM_Unicorn::ARM_Unicorn(System& system) : ARM_Interface{system} {
|
||||
CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
|
||||
ARM_Unicorn::ARM_Unicorn(System& system, Arch architecture) : ARM_Interface{system} {
|
||||
const auto arch = architecture == Arch::AArch32 ? UC_ARCH_ARM : UC_ARCH_ARM64;
|
||||
CHECKED(uc_open(arch, UC_MODE_ARM, &uc));
|
||||
|
||||
auto fpv = 3 << 20;
|
||||
CHECKED(uc_reg_write(uc, UC_ARM64_REG_CPACR_EL1, &fpv));
|
||||
|
||||
@@ -15,7 +15,12 @@ class System;
|
||||
|
||||
class ARM_Unicorn final : public ARM_Interface {
|
||||
public:
|
||||
explicit ARM_Unicorn(System& system);
|
||||
enum class Arch {
|
||||
AArch32, // 32-bit ARM
|
||||
AArch64, // 64-bit ARM
|
||||
};
|
||||
|
||||
explicit ARM_Unicorn(System& system, Arch architecture);
|
||||
~ARM_Unicorn() override;
|
||||
|
||||
void SetPC(u64 pc) override;
|
||||
|
||||
@@ -95,6 +95,10 @@ u32 NACP::GetSupportedLanguages() const {
|
||||
return raw.supported_languages;
|
||||
}
|
||||
|
||||
u64 NACP::GetDeviceSaveDataSize() const {
|
||||
return raw.device_save_data_size;
|
||||
}
|
||||
|
||||
std::vector<u8> NACP::GetRawBytes() const {
|
||||
std::vector<u8> out(sizeof(RawNACP));
|
||||
std::memcpy(out.data(), &raw, sizeof(RawNACP));
|
||||
|
||||
@@ -113,6 +113,7 @@ public:
|
||||
u32 GetSupportedLanguages() const;
|
||||
std::vector<u8> GetRawBytes() const;
|
||||
bool GetUserAccountSwitchLock() const;
|
||||
u64 GetDeviceSaveDataSize() const;
|
||||
|
||||
private:
|
||||
RawNACP raw{};
|
||||
|
||||
@@ -57,7 +57,8 @@ void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) {
|
||||
bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataDescriptor& desc) {
|
||||
return desc.type == SaveDataType::CacheStorage || desc.type == SaveDataType::TemporaryStorage ||
|
||||
(space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User
|
||||
desc.type == SaveDataType::SaveData && desc.title_id == 0 && desc.save_id == 0);
|
||||
(desc.type == SaveDataType::SaveData || desc.type == SaveDataType::DeviceSaveData) &&
|
||||
desc.title_id == 0 && desc.save_id == 0);
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
@@ -139,8 +140,10 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
|
||||
u128 user_id, u64 save_id) {
|
||||
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
|
||||
// be interpreted as the title id of the current process.
|
||||
if (type == SaveDataType::SaveData && title_id == 0) {
|
||||
title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
|
||||
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
|
||||
if (title_id == 0) {
|
||||
title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
|
||||
}
|
||||
}
|
||||
|
||||
std::string out = GetSaveDataSpaceIdPath(space);
|
||||
|
||||
@@ -46,7 +46,7 @@ private:
|
||||
EmuWindow::EmuWindow() {
|
||||
// TODO: Find a better place to set this.
|
||||
config.min_client_area_size =
|
||||
std::make_pair(Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height);
|
||||
std::make_pair(Layout::MinimumSize::Width, Layout::MinimumSize::Height);
|
||||
active_config = config;
|
||||
touch_state = std::make_shared<TouchState>();
|
||||
Input::RegisterFactory<Input::TouchDevice>("emu_window", touch_state);
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
|
||||
namespace Layout {
|
||||
|
||||
namespace MinimumSize {
|
||||
constexpr u32 Width = 640;
|
||||
constexpr u32 Height = 360;
|
||||
} // namespace MinimumSize
|
||||
|
||||
namespace ScreenUndocked {
|
||||
constexpr u32 Width = 1280;
|
||||
constexpr u32 Height = 720;
|
||||
|
||||
@@ -30,6 +30,7 @@ HandleTable::~HandleTable() = default;
|
||||
|
||||
ResultCode HandleTable::SetSize(s32 handle_table_size) {
|
||||
if (static_cast<u32>(handle_table_size) > MAX_COUNT) {
|
||||
LOG_ERROR(Kernel, "Handle table size {} is greater than {}", handle_table_size, MAX_COUNT);
|
||||
return ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -80,6 +81,7 @@ ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
||||
|
||||
ResultCode HandleTable::Close(Handle handle) {
|
||||
if (!IsValid(handle)) {
|
||||
LOG_ERROR(Kernel, "Handle is not valid! handle={:08X}", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
@@ -57,7 +56,6 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
|
||||
return true;
|
||||
});
|
||||
|
||||
auto& kernel = Core::System::GetInstance().Kernel();
|
||||
if (!writable_event) {
|
||||
// Create event if not provided
|
||||
const auto pair = WritableEvent::CreateEventPair(kernel, "HLE Pause Event: " + reason);
|
||||
@@ -79,9 +77,11 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
|
||||
return writable_event;
|
||||
}
|
||||
|
||||
HLERequestContext::HLERequestContext(std::shared_ptr<Kernel::ServerSession> server_session,
|
||||
HLERequestContext::HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory,
|
||||
std::shared_ptr<ServerSession> server_session,
|
||||
std::shared_ptr<Thread> thread)
|
||||
: server_session(std::move(server_session)), thread(std::move(thread)) {
|
||||
: server_session(std::move(server_session)),
|
||||
thread(std::move(thread)), kernel{kernel}, memory{memory} {
|
||||
cmd_buf[0] = 0;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,6 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTabl
|
||||
ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
|
||||
auto& owner_process = *thread.GetOwnerProcess();
|
||||
auto& handle_table = owner_process.GetHandleTable();
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
|
||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf;
|
||||
memory.ReadBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(),
|
||||
@@ -286,7 +285,6 @@ std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
|
||||
std::vector<u8> buffer;
|
||||
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
|
||||
BufferDescriptorA()[buffer_index].Size()};
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
|
||||
if (is_buffer_a) {
|
||||
ASSERT_MSG(BufferDescriptorA().size() > buffer_index,
|
||||
@@ -319,7 +317,6 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
|
||||
size = buffer_size; // TODO(bunnei): This needs to be HW tested
|
||||
}
|
||||
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
if (is_buffer_b) {
|
||||
ASSERT_MSG(BufferDescriptorB().size() > buffer_index,
|
||||
"BufferDescriptorB invalid buffer_index {}", buffer_index);
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
union ResultCode;
|
||||
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
namespace Service {
|
||||
class ServiceFrameworkBase;
|
||||
}
|
||||
@@ -28,6 +32,7 @@ namespace Kernel {
|
||||
class Domain;
|
||||
class HandleTable;
|
||||
class HLERequestContext;
|
||||
class KernelCore;
|
||||
class Process;
|
||||
class ServerSession;
|
||||
class Thread;
|
||||
@@ -98,7 +103,8 @@ protected:
|
||||
*/
|
||||
class HLERequestContext {
|
||||
public:
|
||||
explicit HLERequestContext(std::shared_ptr<ServerSession> session,
|
||||
explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory,
|
||||
std::shared_ptr<ServerSession> session,
|
||||
std::shared_ptr<Thread> thread);
|
||||
~HLERequestContext();
|
||||
|
||||
@@ -305,6 +311,9 @@ private:
|
||||
|
||||
std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;
|
||||
bool is_thread_waiting{};
|
||||
|
||||
KernelCore& kernel;
|
||||
Core::Memory::Memory& memory;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphère, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX.
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -49,18 +49,18 @@ constexpr bool IsAllowedIndexForAddress(std::size_t index) {
|
||||
return index < std::size(AddressSpaceInfos) && AddressSpaceInfos[index].GetAddress() != Invalid;
|
||||
}
|
||||
|
||||
constexpr std::size_t
|
||||
AddressSpaceIndices32Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
|
||||
constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)>
|
||||
AddressSpaceIndices32Bit{
|
||||
0, 1, 0, 2, 0, 3,
|
||||
};
|
||||
|
||||
constexpr std::size_t
|
||||
AddressSpaceIndices36Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
|
||||
constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)>
|
||||
AddressSpaceIndices36Bit{
|
||||
4, 5, 4, 6, 4, 7,
|
||||
};
|
||||
|
||||
constexpr std::size_t
|
||||
AddressSpaceIndices39Bit[static_cast<std::size_t>(AddressSpaceInfo::Type::Count)]{
|
||||
constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)>
|
||||
AddressSpaceIndices39Bit{
|
||||
9, 8, 8, 10, 12, 11,
|
||||
};
|
||||
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphère, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX.
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Kernel::Memory {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphère, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX.
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState p
|
||||
MemoryPermission prev_perm, MemoryAttribute prev_attribute,
|
||||
MemoryState state, MemoryPermission perm,
|
||||
MemoryAttribute attribute) {
|
||||
const std::size_t prev_count{memory_block_tree.size()};
|
||||
const VAddr end_addr{addr + num_pages * PageSize};
|
||||
iterator node{memory_block_tree.begin()};
|
||||
|
||||
@@ -109,7 +108,6 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState p
|
||||
|
||||
void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState state,
|
||||
MemoryPermission perm, MemoryAttribute attribute) {
|
||||
const std::size_t prev_count{memory_block_tree.size()};
|
||||
const VAddr end_addr{addr + num_pages * PageSize};
|
||||
iterator node{memory_block_tree.begin()};
|
||||
|
||||
@@ -145,7 +143,6 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState s
|
||||
|
||||
void MemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func,
|
||||
MemoryPermission perm) {
|
||||
const std::size_t prev_count{memory_block_tree.size()};
|
||||
const VAddr end_addr{addr + num_pages * PageSize};
|
||||
iterator node{memory_block_tree.begin()};
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/memory/memory_block.h"
|
||||
|
||||
@@ -104,9 +104,9 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
|
||||
// Ensure that we don't leave anything un-freed
|
||||
auto group_guard = detail::ScopeExit([&] {
|
||||
for (const auto& it : page_list.Nodes()) {
|
||||
const auto num_pages{std::min(
|
||||
const auto min_num_pages{std::min(
|
||||
it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)};
|
||||
chosen_manager.Free(it.GetAddress(), num_pages);
|
||||
chosen_manager.Free(it.GetAddress(), min_num_pages);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -165,9 +165,9 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages,
|
||||
|
||||
// Free all of the pages
|
||||
for (const auto& it : page_list.Nodes()) {
|
||||
const auto num_pages{std::min(
|
||||
const auto min_num_pages{std::min(
|
||||
it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)};
|
||||
chosen_manager.Free(it.GetAddress(), num_pages);
|
||||
chosen_manager.Free(it.GetAddress(), min_num_pages);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <array>
|
||||
#include <mutex>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/memory/page_heap.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphère, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX.
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/memory/page_heap.h"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphère, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX.
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <list>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/memory/memory_types.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "core/core.h"
|
||||
#include "core/device_memory.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/memory/address_space_info.h"
|
||||
|
||||
@@ -4,16 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/page_table.h"
|
||||
#include "core/file_sys/program_metadata.h"
|
||||
#include "core/hle/kernel/memory/memory_block.h"
|
||||
#include "core/hle/kernel/memory/memory_manager.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// This file references various implementation details from Atmosphère, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphère-NX.
|
||||
// This file references various implementation details from Atmosphere, an open-source firmware for
|
||||
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Kernel::Memory {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <random>
|
||||
|
||||
#include "core/hle/kernel/memory/system_control.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
@@ -67,6 +68,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
Handle requesting_thread_handle) {
|
||||
// The mutex address must be 4-byte aligned
|
||||
if ((address % sizeof(u32)) != 0) {
|
||||
LOG_ERROR(Kernel, "Address is not 4-byte aligned! address={:016X}", address);
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
@@ -88,6 +90,8 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
}
|
||||
|
||||
if (holding_thread == nullptr) {
|
||||
LOG_ERROR(Kernel, "Holding thread does not exist! thread_handle={:08X}",
|
||||
holding_thread_handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -109,6 +113,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
ResultCode Mutex::Release(VAddr address) {
|
||||
// The mutex address must be 4-byte aligned
|
||||
if ((address % sizeof(u32)) != 0) {
|
||||
LOG_ERROR(Kernel, "Address is not 4-byte aligned! address={:016X}", address);
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,9 @@ PhysicalCore::PhysicalCore(Core::System& system, std::size_t id,
|
||||
std::make_unique<Core::ARM_Dynarmic_64>(system, exclusive_monitor, core_index);
|
||||
|
||||
#else
|
||||
arm_interface = std::make_shared<Core::ARM_Unicorn>(system);
|
||||
using Core::ARM_Unicorn;
|
||||
arm_interface_32 = std::make_unique<ARM_Unicorn>(system, ARM_Unicorn::Arch::AArch32);
|
||||
arm_interface_64 = std::make_unique<ARM_Unicorn>(system, ARM_Unicorn::Arch::AArch64);
|
||||
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/bit_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/memory/page_table.h"
|
||||
@@ -119,22 +120,30 @@ ResultCode ProcessCapabilities::ParseCapabilities(const u32* capabilities,
|
||||
// The MapPhysical type uses two descriptor flags for its parameters.
|
||||
// If there's only one, then there's a problem.
|
||||
if (i >= num_capabilities) {
|
||||
LOG_ERROR(Kernel, "Invalid combination! i={}", i);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
const auto size_flags = capabilities[i];
|
||||
if (GetCapabilityType(size_flags) != CapabilityType::MapPhysical) {
|
||||
LOG_ERROR(Kernel, "Invalid capability type! size_flags={}", size_flags);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
const auto result = HandleMapPhysicalFlags(descriptor, size_flags, page_table);
|
||||
if (result.IsError()) {
|
||||
LOG_ERROR(Kernel, "Failed to map physical flags! descriptor={}, size_flags={}",
|
||||
descriptor, size_flags);
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
const auto result =
|
||||
ParseSingleFlagCapability(set_flags, set_svc_bits, descriptor, page_table);
|
||||
if (result.IsError()) {
|
||||
LOG_ERROR(
|
||||
Kernel,
|
||||
"Failed to parse capability flag! set_flags={}, set_svc_bits={}, descriptor={}",
|
||||
set_flags, set_svc_bits, descriptor);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -162,6 +171,9 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s
|
||||
const u32 flag_length = GetFlagBitOffset(type);
|
||||
const u32 set_flag = 1U << flag_length;
|
||||
if ((set_flag & set_flags & InitializeOnceMask) != 0) {
|
||||
LOG_ERROR(Kernel,
|
||||
"Attempted to initialize flags that may only be initialized once. set_flags={}",
|
||||
set_flags);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
set_flags |= set_flag;
|
||||
@@ -187,6 +199,7 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_ERROR(Kernel, "Invalid capability type! type={}", static_cast<u32>(type));
|
||||
return ERR_INVALID_CAPABILITY_DESCRIPTOR;
|
||||
}
|
||||
|
||||
@@ -208,23 +221,31 @@ void ProcessCapabilities::Clear() {
|
||||
|
||||
ResultCode ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) {
|
||||
if (priority_mask != 0 || core_mask != 0) {
|
||||
LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}",
|
||||
priority_mask, core_mask);
|
||||
return ERR_INVALID_CAPABILITY_DESCRIPTOR;
|
||||
}
|
||||
|
||||
const u32 core_num_min = (flags >> 16) & 0xFF;
|
||||
const u32 core_num_max = (flags >> 24) & 0xFF;
|
||||
if (core_num_min > core_num_max) {
|
||||
LOG_ERROR(Kernel, "Core min is greater than core max! core_num_min={}, core_num_max={}",
|
||||
core_num_min, core_num_max);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
const u32 priority_min = (flags >> 10) & 0x3F;
|
||||
const u32 priority_max = (flags >> 4) & 0x3F;
|
||||
if (priority_min > priority_max) {
|
||||
LOG_ERROR(Kernel,
|
||||
"Priority min is greater than priority max! priority_min={}, priority_max={}",
|
||||
core_num_min, priority_max);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
// The switch only has 4 usable cores.
|
||||
if (core_num_max >= 4) {
|
||||
LOG_ERROR(Kernel, "Invalid max cores specified! core_num_max={}", core_num_max);
|
||||
return ERR_INVALID_PROCESSOR_ID;
|
||||
}
|
||||
|
||||
@@ -259,6 +280,7 @@ ResultCode ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags)
|
||||
}
|
||||
|
||||
if (svc_number >= svc_capabilities.size()) {
|
||||
LOG_ERROR(Kernel, "Process svc capability is out of range! svc_number={}", svc_number);
|
||||
return ERR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
@@ -295,6 +317,8 @@ ResultCode ProcessCapabilities::HandleInterruptFlags(u32 flags) {
|
||||
// emulate that, it's sufficient to mark every interrupt as defined.
|
||||
|
||||
if (interrupt >= interrupt_capabilities.size()) {
|
||||
LOG_ERROR(Kernel, "Process interrupt capability is out of range! svc_number={}",
|
||||
interrupt);
|
||||
return ERR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
@@ -307,6 +331,7 @@ ResultCode ProcessCapabilities::HandleInterruptFlags(u32 flags) {
|
||||
ResultCode ProcessCapabilities::HandleProgramTypeFlags(u32 flags) {
|
||||
const u32 reserved = flags >> 17;
|
||||
if (reserved != 0) {
|
||||
LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
|
||||
return ERR_RESERVED_VALUE;
|
||||
}
|
||||
|
||||
@@ -324,6 +349,9 @@ ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) {
|
||||
const u32 major_version = kernel_version >> 19;
|
||||
|
||||
if (major_version != 0 || flags < 0x80000) {
|
||||
LOG_ERROR(Kernel,
|
||||
"Kernel version is non zero or flags are too small! major_version={}, flags={}",
|
||||
major_version, flags);
|
||||
return ERR_INVALID_CAPABILITY_DESCRIPTOR;
|
||||
}
|
||||
|
||||
@@ -334,6 +362,7 @@ ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) {
|
||||
ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) {
|
||||
const u32 reserved = flags >> 26;
|
||||
if (reserved != 0) {
|
||||
LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
|
||||
return ERR_RESERVED_VALUE;
|
||||
}
|
||||
|
||||
@@ -344,6 +373,7 @@ ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) {
|
||||
ResultCode ProcessCapabilities::HandleDebugFlags(u32 flags) {
|
||||
const u32 reserved = flags >> 19;
|
||||
if (reserved != 0) {
|
||||
LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
|
||||
return ERR_RESERVED_VALUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/kernel/readable_event.h"
|
||||
@@ -23,10 +24,12 @@ void ReadableEvent::Acquire(Thread* thread) {
|
||||
}
|
||||
|
||||
void ReadableEvent::Signal() {
|
||||
if (!is_signaled) {
|
||||
is_signaled = true;
|
||||
SynchronizationObject::Signal();
|
||||
};
|
||||
if (is_signaled) {
|
||||
return;
|
||||
}
|
||||
|
||||
is_signaled = true;
|
||||
SynchronizationObject::Signal();
|
||||
}
|
||||
|
||||
void ReadableEvent::Clear() {
|
||||
@@ -35,6 +38,8 @@ void ReadableEvent::Clear() {
|
||||
|
||||
ResultCode ReadableEvent::Reset() {
|
||||
if (!is_signaled) {
|
||||
LOG_ERROR(Kernel, "Handle is not signaled! object_id={}, object_type={}, object_name={}",
|
||||
GetObjectId(), GetTypeName(), GetName());
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) {
|
||||
limit[index] = value;
|
||||
return RESULT_SUCCESS;
|
||||
} else {
|
||||
LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}",
|
||||
static_cast<u32>(resource), value, index);
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
||||
ResultCode ServerSession::QueueSyncRequest(std::shared_ptr<Thread> thread,
|
||||
Core::Memory::Memory& memory) {
|
||||
u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))};
|
||||
std::shared_ptr<Kernel::HLERequestContext> context{
|
||||
std::make_shared<Kernel::HLERequestContext>(SharedFrom(this), std::move(thread))};
|
||||
auto context =
|
||||
std::make_shared<HLERequestContext>(kernel, memory, SharedFrom(this), std::move(thread));
|
||||
|
||||
context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
||||
request_queue.Push(std::move(context));
|
||||
|
||||
@@ -685,6 +685,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
|
||||
case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource:
|
||||
case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: {
|
||||
if (info_sub_id != 0) {
|
||||
LOG_ERROR(Kernel_SVC, "Info sub id is non zero! info_id={}, info_sub_id={}", info_id,
|
||||
info_sub_id);
|
||||
return ERR_INVALID_ENUM_VALUE;
|
||||
}
|
||||
|
||||
@@ -692,6 +694,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
|
||||
system.Kernel().CurrentProcess()->GetHandleTable();
|
||||
const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle));
|
||||
if (!process) {
|
||||
LOG_ERROR(Kernel_SVC, "Process is not valid! info_id={}, info_sub_id={}, handle={:08X}",
|
||||
info_id, info_sub_id, handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -773,7 +777,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) Unimplemented svcGetInfo id=0x{:016X}", info_id);
|
||||
LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id);
|
||||
return ERR_INVALID_ENUM_VALUE;
|
||||
}
|
||||
|
||||
@@ -783,10 +787,13 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
|
||||
|
||||
case GetInfoType::RegisterResourceLimit: {
|
||||
if (handle != 0) {
|
||||
LOG_ERROR(Kernel, "Handle is non zero! handle={:08X}", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (info_sub_id != 0) {
|
||||
LOG_ERROR(Kernel, "Info sub id is non zero! info_id={}, info_sub_id={}", info_id,
|
||||
info_sub_id);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
@@ -866,7 +873,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) Unimplemented svcGetInfo id=0x{:016X}", info_id);
|
||||
LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id);
|
||||
return ERR_INVALID_ENUM_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,6 +423,8 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {
|
||||
if (new_core == THREADPROCESSORID_DONT_UPDATE) {
|
||||
new_core = use_override ? ideal_core_override : ideal_core;
|
||||
if ((new_affinity_mask & (1ULL << new_core)) == 0) {
|
||||
LOG_ERROR(Kernel, "New affinity mask is incorrect! new_core={}, new_affinity_mask={}",
|
||||
new_core, new_affinity_mask);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,8 @@ public:
|
||||
|
||||
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
||||
public:
|
||||
IManagerForApplication() : ServiceFramework("IManagerForApplication") {
|
||||
explicit IManagerForApplication(Common::UUID user_id)
|
||||
: ServiceFramework("IManagerForApplication"), user_id(user_id) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||
@@ -254,12 +255,14 @@ private:
|
||||
}
|
||||
|
||||
void GetAccountId(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
// Should return a nintendo account ID
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw<u64>(1);
|
||||
rb.PushRaw<u64>(user_id.GetNintendoID());
|
||||
}
|
||||
|
||||
Common::UUID user_id;
|
||||
};
|
||||
|
||||
void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) {
|
||||
@@ -319,46 +322,37 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
|
||||
|
||||
void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
auto pid = rp.Pop<u64>();
|
||||
|
||||
LOG_DEBUG(Service_ACC, "called, process_id={}", pid);
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(InitializeApplicationInfoBase(pid));
|
||||
rb.Push(InitializeApplicationInfoBase());
|
||||
}
|
||||
|
||||
void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
auto pid = rp.Pop<u64>();
|
||||
|
||||
LOG_WARNING(Service_ACC, "(Partial implementation) called, process_id={}", pid);
|
||||
LOG_WARNING(Service_ACC, "(Partial implementation) called");
|
||||
|
||||
// TODO(ogniK): We require checking if the user actually owns the title and what not. As of
|
||||
// currently, we assume the user owns the title. InitializeApplicationInfoBase SHOULD be called
|
||||
// first then we do extra checks if the game is a digital copy.
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(InitializeApplicationInfoBase(pid));
|
||||
rb.Push(InitializeApplicationInfoBase());
|
||||
}
|
||||
|
||||
ResultCode Module::Interface::InitializeApplicationInfoBase(u64 process_id) {
|
||||
ResultCode Module::Interface::InitializeApplicationInfoBase() {
|
||||
if (application_info) {
|
||||
LOG_ERROR(Service_ACC, "Application already initialized");
|
||||
return ERR_ACCOUNTINFO_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
const auto& list = system.Kernel().GetProcessList();
|
||||
const auto iter = std::find_if(list.begin(), list.end(), [&process_id](const auto& process) {
|
||||
return process->GetProcessID() == process_id;
|
||||
});
|
||||
|
||||
if (iter == list.end()) {
|
||||
LOG_ERROR(Service_ACC, "Failed to find process ID");
|
||||
application_info.application_type = ApplicationType::Unknown;
|
||||
|
||||
return ERR_ACCOUNTINFO_BAD_APPLICATION;
|
||||
}
|
||||
|
||||
const auto launch_property = system.GetARPManager().GetLaunchProperty((*iter)->GetTitleID());
|
||||
// TODO(ogniK): This should be changed to reflect the target process for when we have multiple
|
||||
// processes emulated. As we don't actually have pid support we should assume we're just using
|
||||
// our own process
|
||||
const auto& current_process = system.Kernel().CurrentProcess();
|
||||
const auto launch_property =
|
||||
system.GetARPManager().GetLaunchProperty(current_process->GetTitleID());
|
||||
|
||||
if (launch_property.Failed()) {
|
||||
LOG_ERROR(Service_ACC, "Failed to get launch property");
|
||||
@@ -372,10 +366,12 @@ ResultCode Module::Interface::InitializeApplicationInfoBase(u64 process_id) {
|
||||
case FileSys::StorageId::Host:
|
||||
case FileSys::StorageId::NandUser:
|
||||
case FileSys::StorageId::SdCard:
|
||||
case FileSys::StorageId::None: // Yuzu specific, differs from hardware
|
||||
application_info.application_type = ApplicationType::Digital;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Service_ACC, "Invalid game storage ID");
|
||||
LOG_ERROR(Service_ACC, "Invalid game storage ID! storage_id={}",
|
||||
launch_property->base_game_storage_id);
|
||||
return ERR_ACCOUNTINFO_BAD_APPLICATION;
|
||||
}
|
||||
|
||||
@@ -389,7 +385,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IManagerForApplication>();
|
||||
rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser());
|
||||
}
|
||||
|
||||
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
|
||||
@@ -428,6 +424,17 @@ void Module::Interface::GetProfileEditor(Kernel::HLERequestContext& ctx) {
|
||||
rb.PushIpcInterface<IProfileEditor>(user_id, *profile_manager);
|
||||
}
|
||||
|
||||
void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
|
||||
// All users should be qualified. We don't actually have parental control or anything to do with
|
||||
// nintendo online currently. We're just going to assume the user running the game has access to
|
||||
// the game regardless of parental control settings.
|
||||
ctx.WriteBuffer(profile_manager->GetAllUsers());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
// A u8 is passed into this function which we can safely ignore. It's to determine if we have
|
||||
|
||||
@@ -33,9 +33,10 @@ public:
|
||||
void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx);
|
||||
void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx);
|
||||
void GetProfileEditor(Kernel::HLERequestContext& ctx);
|
||||
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
|
||||
|
||||
private:
|
||||
ResultCode InitializeApplicationInfoBase(u64 process_id);
|
||||
ResultCode InitializeApplicationInfoBase();
|
||||
|
||||
enum class ApplicationType : u32_le {
|
||||
GameCard = 0,
|
||||
|
||||
@@ -35,7 +35,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"},
|
||||
{120, nullptr, "ListOpenUsersInApplication"},
|
||||
{130, nullptr, "ActivateOpenContextRetention"},
|
||||
{140, nullptr, "ListQualifiedUsers"},
|
||||
{140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"},
|
||||
{150, nullptr, "AuthenticateApplicationAsync"},
|
||||
{190, nullptr, "GetUserLastOpenedApplication"},
|
||||
{191, nullptr, "ActivateOpenContextHolder"},
|
||||
|
||||
@@ -32,7 +32,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
||||
{130, nullptr, "LoadOpenContext"},
|
||||
{131, nullptr, "ListOpenContextStoredUsers"},
|
||||
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"},
|
||||
{141, nullptr, "ListQualifiedUsers"},
|
||||
{141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"},
|
||||
{150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -34,7 +34,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
||||
{112, nullptr, "LoadSaveDataThumbnail"},
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"},
|
||||
{130, nullptr, "ActivateOpenContextRetention"},
|
||||
{140, nullptr, "ListQualifiedUsers"},
|
||||
{140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"},
|
||||
{150, nullptr, "AuthenticateApplicationAsync"},
|
||||
{190, nullptr, "GetUserLastOpenedApplication"},
|
||||
{191, nullptr, "ActivateOpenContextHolder"},
|
||||
|
||||
@@ -43,20 +43,15 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 0x2};
|
||||
constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 0x3};
|
||||
constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7};
|
||||
constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 2};
|
||||
constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 3};
|
||||
constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 503};
|
||||
|
||||
enum class LaunchParameterKind : u32 {
|
||||
ApplicationSpecific = 1,
|
||||
AccountPreselectedUser = 2,
|
||||
};
|
||||
|
||||
enum class VrMode : u8 {
|
||||
Disabled = 0,
|
||||
Enabled = 1,
|
||||
};
|
||||
|
||||
constexpr u32 LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC = 0xC79497CA;
|
||||
|
||||
struct LaunchParameterAccountPreselectedUser {
|
||||
@@ -685,27 +680,21 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void ICommonStateGetter::IsVrModeEnabled(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushEnum(VrMode::Disabled);
|
||||
rb.Push(vr_mode_state);
|
||||
}
|
||||
|
||||
void ICommonStateGetter::SetVrModeEnabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto is_vr_mode_enabled = rp.Pop<bool>();
|
||||
vr_mode_state = rp.Pop<bool>();
|
||||
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called. is_vr_mode_enabled={}", is_vr_mode_enabled);
|
||||
LOG_WARNING(Service_AM, "VR Mode is {}", vr_mode_state ? "on" : "off");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
if (!is_vr_mode_enabled) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
} else {
|
||||
// TODO: Find better error code for this
|
||||
UNIMPLEMENTED_MSG("is_vr_mode_enabled={}", is_vr_mode_enabled);
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
}
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void ICommonStateGetter::SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1169,7 +1158,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
{121, nullptr, "ClearUserChannel"},
|
||||
{122, nullptr, "UnpopToUserChannel"},
|
||||
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
|
||||
{140, nullptr, "GetFriendInvitationStorageChannelEvent"},
|
||||
{140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
|
||||
{141, nullptr, "TryPopFromFriendInvitationStorageChannel"},
|
||||
{150, nullptr, "GetNotificationStorageChannelEvent"},
|
||||
{151, nullptr, "TryPopFromNotificationStorageChannel"},
|
||||
@@ -1186,6 +1175,9 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
auto& kernel = system.Kernel();
|
||||
gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
|
||||
|
||||
friend_invitation_storage_channel_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent");
|
||||
}
|
||||
|
||||
IApplicationFunctions::~IApplicationFunctions() = default;
|
||||
@@ -1343,12 +1335,23 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
std::array<u8, 0x10> version_string{};
|
||||
|
||||
FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
|
||||
const auto res = pm.GetControlMetadata();
|
||||
if (res.first != nullptr) {
|
||||
const auto& version = res.first->GetVersionString();
|
||||
std::copy(version.begin(), version.end(), version_string.begin());
|
||||
} else {
|
||||
constexpr u128 default_version = {1, 0};
|
||||
std::memcpy(version_string.data(), default_version.data(), sizeof(u128));
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 6};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(1);
|
||||
rb.Push<u64>(0);
|
||||
rb.PushRaw(version_string);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1500,6 +1503,14 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
|
||||
rb.PushCopyObjects(gpu_error_detected_event.readable);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(friend_invitation_storage_channel_event.readable);
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager,
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system) {
|
||||
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
|
||||
@@ -1514,14 +1525,15 @@ void InstallInterfaces(SM::ServiceManager& service_manager,
|
||||
std::make_shared<TCAP>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") {
|
||||
IHomeMenuFunctions::IHomeMenuFunctions(Kernel::KernelCore& kernel)
|
||||
: ServiceFramework("IHomeMenuFunctions"), kernel(kernel) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
|
||||
{11, nullptr, "LockForeground"},
|
||||
{12, nullptr, "UnlockForeground"},
|
||||
{20, nullptr, "PopFromGeneralChannel"},
|
||||
{21, nullptr, "GetPopFromGeneralChannelEvent"},
|
||||
{21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"},
|
||||
{30, nullptr, "GetHomeButtonWriterLockAccessor"},
|
||||
{31, nullptr, "GetWriterLockAccessorEx"},
|
||||
{100, nullptr, "PopRequestLaunchApplicationForDebug"},
|
||||
@@ -1531,6 +1543,9 @@ IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions"
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
pop_from_general_channel_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, "IHomeMenuFunctions:PopFromGeneralChannelEvent");
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
|
||||
@@ -1542,6 +1557,14 @@ void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx)
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(pop_from_general_channel_event.readable);
|
||||
}
|
||||
|
||||
IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
|
||||
@@ -191,6 +191,7 @@ private:
|
||||
|
||||
Core::System& system;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
bool vr_mode_state{};
|
||||
};
|
||||
|
||||
class IStorageImpl {
|
||||
@@ -280,20 +281,26 @@ private:
|
||||
void QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx);
|
||||
void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx);
|
||||
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
|
||||
void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx);
|
||||
|
||||
bool launch_popped_application_specific = false;
|
||||
bool launch_popped_account_preselect = false;
|
||||
Kernel::EventPair gpu_error_detected_event;
|
||||
Kernel::EventPair friend_invitation_storage_channel_event;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
|
||||
public:
|
||||
IHomeMenuFunctions();
|
||||
explicit IHomeMenuFunctions(Kernel::KernelCore& kernel);
|
||||
~IHomeMenuFunctions() override;
|
||||
|
||||
private:
|
||||
void RequestToGetForeground(Kernel::HLERequestContext& ctx);
|
||||
void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Kernel::EventPair pop_from_general_channel_event;
|
||||
Kernel::KernelCore& kernel;
|
||||
};
|
||||
|
||||
class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
|
||||
|
||||
@@ -202,7 +202,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IHomeMenuFunctions>();
|
||||
rb.PushIpcInterface<IHomeMenuFunctions>(system.Kernel());
|
||||
}
|
||||
|
||||
void GetGlobalStateController(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/audio/audin_u.h"
|
||||
|
||||
namespace Service::Audio {
|
||||
@@ -36,11 +39,12 @@ public:
|
||||
AudInU::AudInU() : ServiceFramework("audin:u") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "ListAudioIns"},
|
||||
{1, nullptr, "OpenAudioIn"},
|
||||
{2, nullptr, "Unknown"},
|
||||
{3, nullptr, "OpenAudioInAuto"},
|
||||
{4, nullptr, "ListAudioInsAuto"},
|
||||
{0, &AudInU::ListAudioIns, "ListAudioIns"},
|
||||
{1, &AudInU::OpenAudioIn, "OpenAudioIn"},
|
||||
{2, &AudInU::ListAudioIns, "ListAudioInsAuto"},
|
||||
{3, &AudInU::OpenAudioIn, "OpenAudioInAuto"},
|
||||
{4, &AudInU::ListAudioInsAutoFiltered, "ListAudioInsAutoFiltered"},
|
||||
{5, &AudInU::OpenAudioInProtocolSpecified, "OpenAudioInProtocolSpecified"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -49,4 +53,60 @@ AudInU::AudInU() : ServiceFramework("audin:u") {
|
||||
|
||||
AudInU::~AudInU() = default;
|
||||
|
||||
void AudInU::ListAudioIns(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
const std::size_t count = ctx.GetWriteBufferSize() / sizeof(AudioInDeviceName);
|
||||
|
||||
const std::size_t device_count = std::min(count, audio_device_names.size());
|
||||
std::vector<AudioInDeviceName> device_names;
|
||||
device_names.reserve(device_count);
|
||||
|
||||
for (std::size_t i = 0; i < device_count; i++) {
|
||||
const auto& device_name = audio_device_names[i];
|
||||
auto& entry = device_names.emplace_back();
|
||||
device_name.copy(entry.data(), device_name.size());
|
||||
}
|
||||
|
||||
ctx.WriteBuffer(device_names);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u32>(device_names.size()));
|
||||
}
|
||||
|
||||
void AudInU::ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
constexpr u32 device_count = 0;
|
||||
|
||||
// Since we don't actually use any other audio input devices, we return 0 devices. Filtered
|
||||
// device listing just omits the default input device
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u32>(device_count));
|
||||
}
|
||||
|
||||
void AudInU::OpenInOutImpl(Kernel::HLERequestContext& ctx) {
|
||||
AudInOutParams params{};
|
||||
params.channel_count = 2;
|
||||
params.sample_format = SampleFormat::PCM16;
|
||||
params.sample_rate = 48000;
|
||||
params.state = State::Started;
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 6, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw<AudInOutParams>(params);
|
||||
rb.PushIpcInterface<IAudioIn>();
|
||||
}
|
||||
|
||||
void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
OpenInOutImpl(ctx);
|
||||
}
|
||||
|
||||
void AudInU::OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
OpenInOutImpl(ctx);
|
||||
}
|
||||
|
||||
} // namespace Service::Audio
|
||||
|
||||
@@ -16,6 +16,35 @@ class AudInU final : public ServiceFramework<AudInU> {
|
||||
public:
|
||||
explicit AudInU();
|
||||
~AudInU() override;
|
||||
|
||||
private:
|
||||
enum class SampleFormat : u32_le {
|
||||
PCM16 = 2,
|
||||
};
|
||||
|
||||
enum class State : u32_le {
|
||||
Started = 0,
|
||||
Stopped = 1,
|
||||
};
|
||||
|
||||
struct AudInOutParams {
|
||||
u32_le sample_rate{};
|
||||
u32_le channel_count{};
|
||||
SampleFormat sample_format{};
|
||||
State state{};
|
||||
};
|
||||
static_assert(sizeof(AudInOutParams) == 0x10, "AudInOutParams is an invalid size");
|
||||
|
||||
using AudioInDeviceName = std::array<char, 256>;
|
||||
static constexpr std::array<std::string_view, 1> audio_device_names{{
|
||||
"BuiltInHeadset",
|
||||
}};
|
||||
|
||||
void ListAudioIns(Kernel::HLERequestContext& ctx);
|
||||
void ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx);
|
||||
void OpenInOutImpl(Kernel::HLERequestContext& ctx);
|
||||
void OpenAudioIn(Kernel::HLERequestContext& ctx);
|
||||
void OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Service::Audio
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#include <fmt/ostream.h>
|
||||
#include <httplib.h>
|
||||
#include <json.hpp>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/caps/caps_su.h"
|
||||
|
||||
namespace Service::Capture {
|
||||
@@ -9,8 +11,11 @@ namespace Service::Capture {
|
||||
CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{32, &CAPS_SU::SetShimLibraryVersion, "SetShimLibraryVersion"},
|
||||
{201, nullptr, "SaveScreenShot"},
|
||||
{203, nullptr, "SaveScreenShotEx0"},
|
||||
{205, nullptr, "SaveScreenShotEx1"},
|
||||
{210, nullptr, "SaveScreenShotEx2"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -19,4 +24,11 @@ CAPS_SU::CAPS_SU() : ServiceFramework("caps:su") {
|
||||
|
||||
CAPS_SU::~CAPS_SU() = default;
|
||||
|
||||
void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Capture, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
} // namespace Service::Capture
|
||||
|
||||
@@ -16,6 +16,9 @@ class CAPS_SU final : public ServiceFramework<CAPS_SU> {
|
||||
public:
|
||||
explicit CAPS_SU();
|
||||
~CAPS_SU() override;
|
||||
|
||||
private:
|
||||
void SetShimLibraryVersion(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Service::Capture
|
||||
|
||||
@@ -316,8 +316,8 @@ public:
|
||||
{8, &IFileSystem::OpenFile, "OpenFile"},
|
||||
{9, &IFileSystem::OpenDirectory, "OpenDirectory"},
|
||||
{10, &IFileSystem::Commit, "Commit"},
|
||||
{11, nullptr, "GetFreeSpaceSize"},
|
||||
{12, nullptr, "GetTotalSpaceSize"},
|
||||
{11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"},
|
||||
{12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"},
|
||||
{13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"},
|
||||
{14, nullptr, "GetFileTimeStampRaw"},
|
||||
{15, nullptr, "QueryEntry"},
|
||||
@@ -767,7 +767,7 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
||||
{1014, nullptr, "OutputMultiProgramTagAccessLog"},
|
||||
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
|
||||
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
|
||||
{1200, nullptr, "OpenMultiCommitManager"},
|
||||
{1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"},
|
||||
{1300, nullptr, "OpenBisWiper"},
|
||||
};
|
||||
// clang-format on
|
||||
@@ -988,4 +988,40 @@ void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(access_log_program_index);
|
||||
}
|
||||
|
||||
class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> {
|
||||
public:
|
||||
explicit IMultiCommitManager() : ServiceFramework("IMultiCommitManager") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IMultiCommitManager::Add, "Add"},
|
||||
{2, &IMultiCommitManager::Commit, "Commit"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
FileSys::VirtualFile backend;
|
||||
|
||||
void Add(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Commit(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
};
|
||||
|
||||
void FSP_SRV::OpenMultiCommitManager(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IMultiCommitManager>(std::make_shared<IMultiCommitManager>());
|
||||
}
|
||||
|
||||
} // namespace Service::FileSystem
|
||||
|
||||
@@ -50,6 +50,7 @@ private:
|
||||
void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
||||
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
|
||||
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
|
||||
void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
|
||||
|
||||
FileSystemController& fsc;
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
namespace Service::Glue {
|
||||
|
||||
constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 0x1E};
|
||||
constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 0x1F};
|
||||
constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 0x2A};
|
||||
constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 0x66};
|
||||
constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 30};
|
||||
constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 31};
|
||||
constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 42};
|
||||
constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 102};
|
||||
|
||||
} // namespace Service::Glue
|
||||
|
||||
@@ -157,7 +157,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
|
||||
{11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
|
||||
{21, &Hid::ActivateMouse, "ActivateMouse"},
|
||||
{31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
|
||||
{32, nullptr, "SendKeyboardLockKeyEvent"},
|
||||
{32, &Hid::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"},
|
||||
{40, nullptr, "AcquireXpadIdEventHandle"},
|
||||
{41, nullptr, "ReleaseXpadIdEventHandle"},
|
||||
{51, &Hid::ActivateXpad, "ActivateXpad"},
|
||||
@@ -233,7 +233,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
|
||||
{302, nullptr, "StopConsoleSixAxisSensor"},
|
||||
{303, nullptr, "ActivateSevenSixAxisSensor"},
|
||||
{304, nullptr, "StartSevenSixAxisSensor"},
|
||||
{305, nullptr, "StopSevenSixAxisSensor"},
|
||||
{305, &Hid::StopSevenSixAxisSensor, "StopSevenSixAxisSensor"},
|
||||
{306, &Hid::InitializeSevenSixAxisSensor, "InitializeSevenSixAxisSensor"},
|
||||
{307, nullptr, "FinalizeSevenSixAxisSensor"},
|
||||
{308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
|
||||
@@ -853,6 +853,17 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
|
||||
applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
|
||||
@@ -860,6 +871,15 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto flags{rp.Pop<u32>()};
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
class HidDbg final : public ServiceFramework<HidDbg> {
|
||||
public:
|
||||
explicit HidDbg() : ServiceFramework{"hid:dbg"} {
|
||||
|
||||
@@ -128,7 +128,9 @@ private:
|
||||
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
|
||||
void StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<IAppletResource> applet_resource;
|
||||
Core::System& system;
|
||||
|
||||
@@ -15,6 +15,66 @@
|
||||
|
||||
namespace Service::NIM {
|
||||
|
||||
class IShopServiceAsync final : public ServiceFramework<IShopServiceAsync> {
|
||||
public:
|
||||
IShopServiceAsync() : ServiceFramework("IShopServiceAsync") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Cancel"},
|
||||
{1, nullptr, "GetSize"},
|
||||
{2, nullptr, "Read"},
|
||||
{3, nullptr, "GetErrorCode"},
|
||||
{4, nullptr, "Request"},
|
||||
{5, nullptr, "Prepare"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
};
|
||||
|
||||
class IShopServiceAccessor final : public ServiceFramework<IShopServiceAccessor> {
|
||||
public:
|
||||
IShopServiceAccessor() : ServiceFramework("IShopServiceAccessor") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IShopServiceAccessor::CreateAsyncInterface, "CreateAsyncInterface"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateAsyncInterface(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IShopServiceAsync>();
|
||||
}
|
||||
};
|
||||
|
||||
class IShopServiceAccessServer final : public ServiceFramework<IShopServiceAccessServer> {
|
||||
public:
|
||||
IShopServiceAccessServer() : ServiceFramework("IShopServiceAccessServer") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IShopServiceAccessServer::CreateAccessorInterface, "CreateAccessorInterface"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateAccessorInterface(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IShopServiceAccessor>();
|
||||
}
|
||||
};
|
||||
|
||||
class NIM final : public ServiceFramework<NIM> {
|
||||
public:
|
||||
explicit NIM() : ServiceFramework{"nim"} {
|
||||
@@ -78,7 +138,7 @@ public:
|
||||
explicit NIM_ECA() : ServiceFramework{"nim:eca"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateServerInterface"},
|
||||
{0, &NIM_ECA::CreateServerInterface, "CreateServerInterface"},
|
||||
{1, nullptr, "RefreshDebugAvailability"},
|
||||
{2, nullptr, "ClearDebugResponse"},
|
||||
{3, nullptr, "RegisterDebugResponse"},
|
||||
@@ -87,6 +147,14 @@ public:
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateServerInterface(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IShopServiceAccessServer>();
|
||||
}
|
||||
};
|
||||
|
||||
class NIM_SHP final : public ServiceFramework<NIM_SHP> {
|
||||
|
||||
@@ -371,10 +371,15 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
|
||||
// Convert to application language, get priority list
|
||||
const auto application_language = ConvertToApplicationLanguage(language_code);
|
||||
if (application_language == std::nullopt) {
|
||||
LOG_ERROR(Service_NS, "Could not convert application language! language_code={}",
|
||||
language_code);
|
||||
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
|
||||
}
|
||||
const auto priority_list = GetApplicationLanguagePriorityList(*application_language);
|
||||
if (!priority_list) {
|
||||
LOG_ERROR(Service_NS,
|
||||
"Could not find application language priorities! application_language={}",
|
||||
*application_language);
|
||||
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -386,6 +391,8 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}",
|
||||
supported_languages);
|
||||
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -410,6 +417,7 @@ ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguag
|
||||
const auto language_code =
|
||||
ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language));
|
||||
if (language_code == std::nullopt) {
|
||||
LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language);
|
||||
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,9 +159,10 @@ private:
|
||||
static_assert(sizeof(IoctlFlushL2) == 8, "IoctlFlushL2 is incorrect size");
|
||||
|
||||
struct IoctlGetGpuTime {
|
||||
u64_le gpu_time;
|
||||
u64_le gpu_time{};
|
||||
INSERT_PADDING_WORDS(2);
|
||||
};
|
||||
static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size");
|
||||
static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size");
|
||||
|
||||
u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& output2, IoctlVersion version);
|
||||
|
||||
@@ -138,9 +138,7 @@ u32 BufferQueue::Query(QueryType type) {
|
||||
|
||||
switch (type) {
|
||||
case QueryType::NativeWindowFormat:
|
||||
// TODO(Subv): Use an enum for this
|
||||
static constexpr u32 FormatABGR8 = 1;
|
||||
return FormatABGR8;
|
||||
return static_cast<u32>(PixelFormat::RGBA8888);
|
||||
}
|
||||
|
||||
UNIMPLEMENTED();
|
||||
|
||||
@@ -66,6 +66,16 @@ public:
|
||||
Rotate270 = 0x07,
|
||||
};
|
||||
|
||||
enum class PixelFormat : u32 {
|
||||
RGBA8888 = 1,
|
||||
RGBX8888 = 2,
|
||||
RGB888 = 3,
|
||||
RGB565 = 4,
|
||||
BGRA8888 = 5,
|
||||
RGBA5551 = 6,
|
||||
RRGBA4444 = 7,
|
||||
};
|
||||
|
||||
struct Buffer {
|
||||
enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 };
|
||||
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
|
||||
namespace Service::PSM {
|
||||
|
||||
constexpr u32 BATTERY_FULLY_CHARGED = 100; // 100% Full
|
||||
constexpr u32 BATTERY_CURRENTLY_CHARGING = 1; // Plugged into an official dock
|
||||
|
||||
class PSM final : public ServiceFramework<PSM> {
|
||||
public:
|
||||
explicit PSM() : ServiceFramework{"psm"} {
|
||||
@@ -48,20 +45,30 @@ public:
|
||||
|
||||
private:
|
||||
void GetBatteryChargePercentage(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_PSM, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_PSM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(BATTERY_FULLY_CHARGED);
|
||||
rb.Push<u32>(battery_charge_percentage);
|
||||
}
|
||||
|
||||
void GetChargerType(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_PSM, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_PSM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(BATTERY_CURRENTLY_CHARGING);
|
||||
rb.PushEnum(charger_type);
|
||||
}
|
||||
|
||||
enum class ChargerType : u32 {
|
||||
Unplugged = 0,
|
||||
RegularCharger = 1,
|
||||
LowPowerCharger = 2,
|
||||
Unknown = 3,
|
||||
};
|
||||
|
||||
u32 battery_charge_percentage{100}; // 100%
|
||||
ChargerType charger_type{ChargerType::RegularCharger};
|
||||
};
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& sm) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user