Compare commits
102 Commits
mainline-0
...
mainline-0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
953011213c | ||
|
|
70c5fb86c7 | ||
|
|
a199c46be8 | ||
|
|
fcb2747ae5 | ||
|
|
a4f63df032 | ||
|
|
5eff65cd5d | ||
|
|
9188dc3bf9 | ||
|
|
a8295d2c53 | ||
|
|
3e0e4f146b | ||
|
|
bb31df62bb | ||
|
|
f2e34efcbb | ||
|
|
790a482bb4 | ||
|
|
c6bc13d0aa | ||
|
|
885d88825e | ||
|
|
360b0d1b30 | ||
|
|
02880a8195 | ||
|
|
b6f6733131 | ||
|
|
7f424d0f60 | ||
|
|
ebb30cbefb | ||
|
|
c5c89a4d5c | ||
|
|
cc9e682021 | ||
|
|
03b73aa575 | ||
|
|
61f6eaad45 | ||
|
|
cf770a68a5 | ||
|
|
d1f0d182a7 | ||
|
|
2cacf97099 | ||
|
|
d24fcaff77 | ||
|
|
f7d4c84807 | ||
|
|
64cbebc58f | ||
|
|
e0c46e6879 | ||
|
|
47a6bb2d5b | ||
|
|
f11b87ebf1 | ||
|
|
75dec14f21 | ||
|
|
23878bf360 | ||
|
|
86a1eb7789 | ||
|
|
12dc918937 | ||
|
|
86c397dd6e | ||
|
|
ef060ed40c | ||
|
|
581d2e36e5 | ||
|
|
27ab99490e | ||
|
|
19a0abc19b | ||
|
|
96d677bef0 | ||
|
|
d4a1afba4b | ||
|
|
fb9418798d | ||
|
|
b0b0786493 | ||
|
|
8714d40a77 | ||
|
|
8dc9f35baf | ||
|
|
883eb1a1a1 | ||
|
|
0fc596de6e | ||
|
|
18c1cb68fd | ||
|
|
096f339a2a | ||
|
|
fa0d65fc7b | ||
|
|
a056d8de16 | ||
|
|
bfa973a62b | ||
|
|
3ab0514698 | ||
|
|
cd66395944 | ||
|
|
56e237d1f9 | ||
|
|
08b2b1080a | ||
|
|
3d7c284e0f | ||
|
|
b6ae48966d | ||
|
|
0e8a3bf3e5 | ||
|
|
344d15f61e | ||
|
|
e9d2fad984 | ||
|
|
f1facaeaef | ||
|
|
e2ea0c3e11 | ||
|
|
028b1a34a9 | ||
|
|
f019817f8f | ||
|
|
ff5a0f370c | ||
|
|
7b069252f8 | ||
|
|
46c3047283 | ||
|
|
ae7dfa93be | ||
|
|
deb1b54eed | ||
|
|
39c66abd91 | ||
|
|
c4374d0d41 | ||
|
|
35d40b74b3 | ||
|
|
c414ebaa9c | ||
|
|
e07dfc4da3 | ||
|
|
63d30133f8 | ||
|
|
f1e4f3fc0c | ||
|
|
468576284d | ||
|
|
4d66ca97e5 | ||
|
|
c1a3d19897 | ||
|
|
654b77d2ec | ||
|
|
0c8b6b0351 | ||
|
|
9a62f5351a | ||
|
|
65bed6682c | ||
|
|
0e34f648f4 | ||
|
|
21e07df7b7 | ||
|
|
62a3d59288 | ||
|
|
4dc068a90c | ||
|
|
1bdae0fe29 | ||
|
|
ece5287843 | ||
|
|
b0ab803ce8 | ||
|
|
28bb248db6 | ||
|
|
442a1cc021 | ||
|
|
76ca2a5f82 | ||
|
|
a993df1ee2 | ||
|
|
1643af431c | ||
|
|
c2486f77e4 | ||
|
|
c0eb1aecfd | ||
|
|
57a46c69f1 | ||
|
|
c1e9ca4c08 |
@@ -1,12 +1,16 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
# Copy documentation
|
||||
cp license.txt "$REV_NAME"
|
||||
cp README.md "$REV_NAME"
|
||||
cp license.txt "$DIR_NAME"
|
||||
cp README.md "$DIR_NAME"
|
||||
|
||||
tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$REV_NAME"
|
||||
tar -cJvf "${REV_NAME}-source.tar.xz" src externals CMakeLists.txt README.md license.txt
|
||||
cp "${REV_NAME}-source.tar.xz" "$DIR_NAME"
|
||||
|
||||
mv "$REV_NAME" $RELEASE_NAME
|
||||
tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$DIR_NAME"
|
||||
|
||||
mv "$DIR_NAME" $RELEASE_NAME
|
||||
mv "${REV_NAME}-source.tar.xz" $RELEASE_NAME
|
||||
|
||||
7z a "$REV_NAME.7z" $RELEASE_NAME
|
||||
|
||||
|
||||
@@ -11,5 +11,4 @@ ninja
|
||||
|
||||
ccache -s
|
||||
|
||||
# Ignore zlib's tests, since they aren't gated behind a CMake option.
|
||||
ctest -VV -E "(example|example64)" -C Release
|
||||
ctest -VV -C Release
|
||||
|
||||
@@ -6,9 +6,15 @@ REV_NAME="yuzu-linux-${GITDATE}-${GITREV}"
|
||||
ARCHIVE_NAME="${REV_NAME}.tar.xz"
|
||||
COMPRESSION_FLAGS="-cJvf"
|
||||
|
||||
mkdir "$REV_NAME"
|
||||
if [ "${RELEASE_NAME}" = "mainline" ]; then
|
||||
DIR_NAME="${REV_NAME}"
|
||||
else
|
||||
DIR_NAME="${REV_NAME}_${RELEASE_NAME}"
|
||||
fi
|
||||
|
||||
cp build/bin/yuzu-cmd "$REV_NAME"
|
||||
cp build/bin/yuzu "$REV_NAME"
|
||||
mkdir "$DIR_NAME"
|
||||
|
||||
cp build/bin/yuzu-cmd "$DIR_NAME"
|
||||
cp build/bin/yuzu "$DIR_NAME"
|
||||
|
||||
. .ci/scripts/common/post-upload.sh
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
$GITDATE = $(git show -s --date=short --format='%ad') -replace "-",""
|
||||
param($BUILD_NAME)
|
||||
|
||||
$GITDATE = $(git show -s --date=short --format='%ad') -replace "-", ""
|
||||
$GITREV = $(git show -s --format='%h')
|
||||
$RELEASE_DIST = "yuzu-windows-msvc"
|
||||
|
||||
if ("$BUILD_NAME" -eq "mainline") {
|
||||
$RELEASE_DIST = "yuzu-windows-msvc"
|
||||
}
|
||||
else {
|
||||
$RELEASE_DIST = "yuzu-windows-msvc-$BUILD_NAME"
|
||||
}
|
||||
|
||||
$MSVC_BUILD_ZIP = "yuzu-windows-msvc-$GITDATE-$GITREV.zip" -replace " ", ""
|
||||
$MSVC_BUILD_PDB = "yuzu-windows-msvc-$GITDATE-$GITREV-debugsymbols.zip" -replace " ", ""
|
||||
$MSVC_SEVENZIP = "yuzu-windows-msvc-$GITDATE-$GITREV.7z" -replace " ", ""
|
||||
$MSVC_TAR = "yuzu-windows-msvc-$GITDATE-$GITREV.tar" -replace " ", ""
|
||||
$MSVC_TARXZ = "yuzu-windows-msvc-$GITDATE-$GITREV.tar.xz" -replace " ", ""
|
||||
$MSVC_SOURCE = "yuzu-windows-msvc-source-$GITDATE-$GITREV" -replace " ", ""
|
||||
$MSVC_SOURCE_TAR = "$MSVC_SOURCE.tar"
|
||||
$MSVC_SOURCE_TARXZ = "$MSVC_SOURCE_TAR.xz"
|
||||
|
||||
$env:BUILD_ZIP = $MSVC_BUILD_ZIP
|
||||
$env:BUILD_SYMBOLS = $MSVC_BUILD_PDB
|
||||
@@ -14,19 +25,33 @@ $env:BUILD_UPDATE = $MSVC_SEVENZIP
|
||||
|
||||
$BUILD_DIR = ".\build\bin\Release"
|
||||
|
||||
# Upload debugging symbols
|
||||
mkdir pdb
|
||||
Get-ChildItem "$BUILD_DIR\" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb
|
||||
7z a -tzip $MSVC_BUILD_PDB .\pdb\*.pdb
|
||||
rm "$BUILD_DIR\*.pdb"
|
||||
|
||||
# Create artifact directories
|
||||
mkdir $RELEASE_DIST
|
||||
mkdir $MSVC_SOURCE
|
||||
mkdir "artifacts"
|
||||
|
||||
# Build a tar.xz for the source of the release
|
||||
Copy-Item .\license.txt -Destination $MSVC_SOURCE
|
||||
Copy-Item .\README.md -Destination $MSVC_SOURCE
|
||||
Copy-Item .\src -Recurse -Destination $MSVC_SOURCE
|
||||
Copy-Item .\externals -Recurse -Destination $MSVC_SOURCE
|
||||
Copy-Item .\dist -Recurse -Destination $MSVC_SOURCE
|
||||
Copy-Item .\CMakeModules -Recurse -Destination $MSVC_SOURCE
|
||||
7z a -r -ttar $MSVC_SOURCE_TAR $MSVC_SOURCE
|
||||
7z a -r -txz $MSVC_SOURCE_TARXZ $MSVC_SOURCE_TAR
|
||||
|
||||
# Build the final release artifacts
|
||||
Copy-Item $MSVC_SOURCE_TARXZ -Destination $RELEASE_DIST
|
||||
Copy-Item "$BUILD_DIR\*" -Destination $RELEASE_DIST -Recurse
|
||||
rm "$RELEASE_DIST\*.exe"
|
||||
Get-ChildItem "$BUILD_DIR" -Recurse -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
Get-ChildItem "$BUILD_DIR" -Recurse -Filter "QtWebEngineProcess*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
Copy-Item .\license.txt -Destination $RELEASE_DIST
|
||||
Copy-Item .\README.md -Destination $RELEASE_DIST
|
||||
7z a -tzip $MSVC_BUILD_ZIP $RELEASE_DIST\*
|
||||
7z a $MSVC_SEVENZIP $RELEASE_DIST
|
||||
|
||||
|
||||
@@ -6,8 +6,14 @@ REV_NAME="yuzu-windows-mingw-${GITDATE}-${GITREV}"
|
||||
ARCHIVE_NAME="${REV_NAME}.tar.gz"
|
||||
COMPRESSION_FLAGS="-czvf"
|
||||
|
||||
mkdir "$REV_NAME"
|
||||
if [ "${RELEASE_NAME}" = "mainline" ]; then
|
||||
DIR_NAME="${REV_NAME}"
|
||||
else
|
||||
DIR_NAME="${REV_NAME}_${RELEASE_NAME}"
|
||||
fi
|
||||
|
||||
mkdir "$DIR_NAME"
|
||||
# get around the permission issues
|
||||
cp -r package/* "$REV_NAME"
|
||||
cp -r package/* "$DIR_NAME"
|
||||
|
||||
. .ci/scripts/common/post-upload.sh
|
||||
|
||||
@@ -17,6 +17,7 @@ steps:
|
||||
inputs:
|
||||
targetType: 'filePath'
|
||||
filePath: './.ci/scripts/windows/upload.ps1'
|
||||
arguments: '$(BuildName)'
|
||||
- publish: artifacts
|
||||
artifact: 'yuzu-$(BuildName)-windows-msvc'
|
||||
displayName: 'Upload Artifacts'
|
||||
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -47,8 +47,8 @@
|
||||
path = externals/sirit
|
||||
url = https://github.com/ReinUsesLisp/sirit
|
||||
[submodule "libzip"]
|
||||
path = externals/libzip
|
||||
url = https://github.com/DarkLordZach/libzip
|
||||
path = externals/libzip/libzip
|
||||
url = https://github.com/nih-at/libzip.git
|
||||
[submodule "zlib"]
|
||||
path = externals/zlib
|
||||
url = https://github.com/madler/zlib
|
||||
path = externals/zlib/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
|
||||
@@ -1 +1 @@
|
||||
**The Contributor's Guide has moved to [the Yuzu wiki](https://github.com/yuzu-emu/yuzu/wiki/Contributing).**
|
||||
**The Contributor's Guide has moved to [the yuzu wiki](https://github.com/yuzu-emu/yuzu/wiki/Contributing).**
|
||||
|
||||
1
externals/CMakeLists.txt
vendored
1
externals/CMakeLists.txt
vendored
@@ -76,6 +76,7 @@ endif()
|
||||
|
||||
# zlib
|
||||
add_subdirectory(zlib EXCLUDE_FROM_ALL)
|
||||
set(ZLIB_LIBRARIES z)
|
||||
|
||||
# libzip
|
||||
add_subdirectory(libzip EXCLUDE_FROM_ALL)
|
||||
|
||||
5043
externals/httplib/httplib.h
vendored
5043
externals/httplib/httplib.h
vendored
File diff suppressed because it is too large
Load Diff
1
externals/libzip
vendored
1
externals/libzip
vendored
Submodule externals/libzip deleted from bd7a8103e9
564
externals/libzip/CMakeLists.txt
vendored
Normal file
564
externals/libzip/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,564 @@
|
||||
# TODO:
|
||||
# create usable libtool .la file
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
|
||||
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libzip")
|
||||
|
||||
PROJECT(libzip C)
|
||||
|
||||
OPTION(ENABLE_COMMONCRYPTO "Enable use of CommonCrypto" ON)
|
||||
OPTION(ENABLE_GNUTLS "Enable use of GnuTLS" ON)
|
||||
OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" ON)
|
||||
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
|
||||
OPTION(ENABLE_WINDOWS_CRYPTO "Enable use of Windows cryptography libraries" ON)
|
||||
|
||||
OPTION(ENABLE_BZIP2 "Enable use of BZip2" OFF)
|
||||
OPTION(ENABLE_LZMA "Enable use of LZMA" OFF)
|
||||
|
||||
INCLUDE(CheckFunctionExists)
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
INCLUDE(CheckSymbolExists)
|
||||
INCLUDE(CheckTypeSize)
|
||||
INCLUDE(CheckCSourceRuns)
|
||||
INCLUDE(CheckCSourceCompiles)
|
||||
INCLUDE(CheckStructHasMember)
|
||||
INCLUDE(TestBigEndian)
|
||||
INCLUDE(GNUInstallDirs)
|
||||
IF(ENABLE_COMMONCRYPTO)
|
||||
CHECK_INCLUDE_FILES(CommonCrypto/CommonCrypto.h COMMONCRYPTO_FOUND)
|
||||
ELSE()
|
||||
SET(COMMONCRYPTO_FOUND FALSE)
|
||||
ENDIF()
|
||||
IF(ENABLE_GNUTLS)
|
||||
INCLUDE(FindNettle)
|
||||
INCLUDE(FindGnuTLS)
|
||||
ELSE()
|
||||
SET(GNUTLS_FOUND FALSE)
|
||||
ENDIF()
|
||||
IF(ENABLE_MBEDTLS)
|
||||
FIND_PATH(MBEDTLS_INCLUDE_DIR mbedtls/aes.h)
|
||||
FIND_LIBRARY(MBEDTLS_LIBRARIES NAMES mbedcrypto)
|
||||
ELSE()
|
||||
SET(MBEDTLS_LIBRARIES FALSE)
|
||||
ENDIF()
|
||||
IF(ENABLE_OPENSSL)
|
||||
INCLUDE(FindOpenSSL)
|
||||
ELSE()
|
||||
SET(OPENSSL_FOUND FALSE)
|
||||
ENDIF()
|
||||
IF(WIN32)
|
||||
IF(ENABLE_WINDOWS_CRYPTO)
|
||||
SET(WINDOWS_CRYPTO_FOUND TRUE)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(WINDOWS_CRYPTO_FOUND FALSE)
|
||||
ENDIF()
|
||||
|
||||
OPTION(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
OPTION(SHARED_LIB_VERSIONNING "Add SO version in .so build" ON)
|
||||
|
||||
SET(PACKAGE "libzip")
|
||||
SET(PACKAGE_NAME ${PACKAGE})
|
||||
SET(PACKAGE_VERSION_MAJOR "1")
|
||||
SET(PACKAGE_VERSION_MINOR "5")
|
||||
SET(PACKAGE_VERSION_MICRO "2a")
|
||||
#SET(VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}")
|
||||
SET(VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_MICRO}")
|
||||
SET(PACKAGE_VERSION ${VERSION})
|
||||
SET(LIBZIP_VERSION ${PACKAGE_VERSION})
|
||||
SET(LIBZIP_VERSION_MAJOR ${PACKAGE_VERSION_MAJOR})
|
||||
SET(LIBZIP_VERSION_MINOR ${PACKAGE_VERSION_MINOR})
|
||||
SET(LIBZIP_VERSION_MICRO ${PACKAGE_VERSION_MICRO})
|
||||
SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
|
||||
SET(ARCHIVE_NAME ${PACKAGE_NAME}-${PACKAGE_VERSION})
|
||||
IF(NOT TARGET dist)
|
||||
ADD_CUSTOM_TARGET(dist
|
||||
COMMAND git config tar.tar.xz.command "xz -c"
|
||||
COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.gz HEAD
|
||||
COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.xz HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
ADD_CUSTOM_TARGET(distcheck
|
||||
COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest 2>/dev/null || true
|
||||
COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
|
||||
COMMAND cmake -E tar xf ${ARCHIVE_NAME}.tar.gz
|
||||
COMMAND chmod -R u-w ${ARCHIVE_NAME}
|
||||
COMMAND mkdir ${ARCHIVE_NAME}-build
|
||||
COMMAND mkdir ${ARCHIVE_NAME}-dest
|
||||
COMMAND cd ${ARCHIVE_NAME}-build && cmake -DCMAKE_INSTALL_PREFIX=../${ARCHIVE_NAME}-dest ../${ARCHIVE_NAME}
|
||||
COMMAND cd ${ARCHIVE_NAME}-build && make -j4
|
||||
COMMAND cd ${ARCHIVE_NAME}-build && make test
|
||||
COMMAND cd ${ARCHIVE_NAME}-build && make install
|
||||
# COMMAND cd ${ARCHIVE_NAME}-build && make uninstall
|
||||
# COMMAND if [ `find ${ARCHIVE_NAME}-dest ! -type d | wc -l` -ne 0 ]; then echo leftover files in ${ARCHIVE_NAME}-dest; false; fi
|
||||
COMMAND cd ${ARCHIVE_NAME}-build && make clean
|
||||
COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
|
||||
COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
|
||||
COMMAND echo "${ARCHIVE_NAME}.tar.gz is ready for distribution."
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
ADD_DEPENDENCIES(distcheck dist)
|
||||
ENDIF(NOT TARGET dist)
|
||||
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
SET(HAVE_SHARED TRUE)
|
||||
ELSE()
|
||||
SET(ZIP_STATIC TRUE)
|
||||
ENDIF()
|
||||
|
||||
# Checks
|
||||
|
||||
CHECK_FUNCTION_EXISTS(_chmod HAVE__CHMOD)
|
||||
CHECK_FUNCTION_EXISTS(_close HAVE__CLOSE)
|
||||
CHECK_FUNCTION_EXISTS(_dup HAVE__DUP)
|
||||
CHECK_FUNCTION_EXISTS(_fdopen HAVE__FDOPEN)
|
||||
CHECK_FUNCTION_EXISTS(_fileno HAVE__FILENO)
|
||||
CHECK_FUNCTION_EXISTS(_open HAVE__OPEN)
|
||||
CHECK_FUNCTION_EXISTS(_setmode HAVE__SETMODE)
|
||||
CHECK_FUNCTION_EXISTS(_snprintf HAVE__SNPRINTF)
|
||||
CHECK_FUNCTION_EXISTS(_strdup HAVE__STRDUP)
|
||||
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
|
||||
CHECK_FUNCTION_EXISTS(_strtoi64 HAVE__STRTOI64)
|
||||
CHECK_FUNCTION_EXISTS(_strtoui64 HAVE__STRTOUI64)
|
||||
CHECK_FUNCTION_EXISTS(_unlink HAVE__UNLINK)
|
||||
CHECK_FUNCTION_EXISTS(arc4random HAVE_ARC4RANDOM)
|
||||
CHECK_FUNCTION_EXISTS(clonefile HAVE_CLONEFILE)
|
||||
CHECK_FUNCTION_EXISTS(explicit_bzero HAVE_EXPLICIT_BZERO)
|
||||
CHECK_FUNCTION_EXISTS(explicit_memset HAVE_EXPLICIT_MEMSET)
|
||||
CHECK_FUNCTION_EXISTS(fileno HAVE_FILENO)
|
||||
CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO)
|
||||
CHECK_FUNCTION_EXISTS(ftello HAVE_FTELLO)
|
||||
CHECK_FUNCTION_EXISTS(getprogname HAVE_GETPROGNAME)
|
||||
CHECK_FUNCTION_EXISTS(localtime_r HAVE_LOCALTIME_R)
|
||||
CHECK_FUNCTION_EXISTS(open HAVE_OPEN)
|
||||
CHECK_FUNCTION_EXISTS(setmode HAVE_SETMODE)
|
||||
CHECK_FUNCTION_EXISTS(snprintf HAVE_SNPRINTF)
|
||||
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP)
|
||||
CHECK_FUNCTION_EXISTS(stricmp HAVE_STRICMP)
|
||||
CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL)
|
||||
CHECK_FUNCTION_EXISTS(strtoull HAVE_STRTOULL)
|
||||
|
||||
CHECK_INCLUDE_FILES("sys/types.h;sys/stat.h;fts.h" HAVE_FTS_H)
|
||||
CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H)
|
||||
CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H)
|
||||
CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
|
||||
|
||||
CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H_LIBZIP)
|
||||
CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H_LIBZIP)
|
||||
CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H_LIBZIP)
|
||||
|
||||
# TODO: fix test
|
||||
# this test does not find __progname even when it exists
|
||||
#CHECK_SYMBOL_EXISTS(__progname stdlib.h HAVE___PROGNAME)
|
||||
|
||||
CHECK_TYPE_SIZE(__int8 __INT8_LIBZIP)
|
||||
CHECK_TYPE_SIZE(int8_t INT8_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE(uint8_t UINT8_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE(__int16 __INT16_LIBZIP)
|
||||
CHECK_TYPE_SIZE(int16_t INT16_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE(uint16_t UINT16_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE(__int32 __INT32_LIBZIP)
|
||||
CHECK_TYPE_SIZE(int32_t INT32_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE(uint32_t UINT32_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE(__int64 __INT64_LIBZIP)
|
||||
CHECK_TYPE_SIZE(int64_t INT64_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE(uint64_t UINT64_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE("short" SHORT_LIBZIP)
|
||||
CHECK_TYPE_SIZE("int" INT_LIBZIP)
|
||||
CHECK_TYPE_SIZE("long" LONG_LIBZIP)
|
||||
CHECK_TYPE_SIZE("long long" LONG_LONG_LIBZIP)
|
||||
CHECK_TYPE_SIZE("off_t" SIZEOF_OFF_T)
|
||||
CHECK_TYPE_SIZE("size_t" SIZE_T_LIBZIP)
|
||||
CHECK_TYPE_SIZE("ssize_t" SSIZE_T_LIBZIP)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
int main(int argc, char *argv[]) { unsigned long x = FICLONERANGE; }" HAVE_FICLONERANGE)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("
|
||||
int foo(char * _Nullable bar);
|
||||
int main(int argc, char *argv[]) { }" HAVE_NULLABLE)
|
||||
|
||||
TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
|
||||
|
||||
#FIND_PACKAGE(ZLIB 1.1.2 REQUIRED)
|
||||
INCLUDE_DIRECTORIES(../zlib/zlib)
|
||||
SET(CMAKE_REQUIRED_INCLUDES ../zlib/zlib)
|
||||
|
||||
IF(ENABLE_BZIP2)
|
||||
FIND_PACKAGE(BZip2)
|
||||
IF(BZIP2_FOUND)
|
||||
SET (HAVE_LIBBZ2 1)
|
||||
|
||||
INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR})
|
||||
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${BZIP2_LIBRARIES})
|
||||
ELSE()
|
||||
MESSAGE(WARNING "-- bzip2 library not found; bzip2 support disabled")
|
||||
ENDIF(BZIP2_FOUND)
|
||||
ENDIF(ENABLE_BZIP2)
|
||||
|
||||
IF(ENABLE_LZMA)
|
||||
FIND_PACKAGE(LibLZMA)
|
||||
IF(LIBLZMA_FOUND)
|
||||
SET (HAVE_LIBLZMA 1)
|
||||
|
||||
INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIR})
|
||||
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${LIBLZMA_LIBRARY})
|
||||
ELSE()
|
||||
MESSAGE(WARNING "-- lzma library not found; lzma support disabled")
|
||||
ENDIF(LIBLZMA_FOUND)
|
||||
ENDIF(ENABLE_LZMA)
|
||||
|
||||
|
||||
IF (COMMONCRYPTO_FOUND)
|
||||
SET (HAVE_CRYPTO 1)
|
||||
SET (HAVE_COMMONCRYPTO 1)
|
||||
ELSEIF (WINDOWS_CRYPTO_FOUND)
|
||||
SET (HAVE_CRYPTO 1)
|
||||
SET (HAVE_WINDOWS_CRYPTO 1)
|
||||
ELSEIF (GNUTLS_FOUND AND NETTLE_FOUND)
|
||||
SET (HAVE_CRYPTO 1)
|
||||
SET (HAVE_GNUTLS 1)
|
||||
INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_DIR} ${NETTLE_INCLUDE_DIR})
|
||||
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${GNUTLS_LIBRARY} ${NETTLE_LIBRARY})
|
||||
ELSEIF (OPENSSL_FOUND)
|
||||
SET (HAVE_CRYPTO 1)
|
||||
SET (HAVE_OPENSSL 1)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${OPENSSL_LIBRARIES})
|
||||
ELSEIF (MBEDTLS_LIBRARIES)
|
||||
SET (HAVE_CRYPTO 1)
|
||||
SET (HAVE_MBEDTLS 1)
|
||||
INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIR})
|
||||
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${MBEDTLS_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
IF (NOT HAVE_CRYPTO)
|
||||
MESSAGE(WARNING "-- neither Common Crypto, GnuTLS, mbed TLS, OpenSSL, nor Windows Cryptography found; AES support disabled")
|
||||
ENDIF()
|
||||
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS")
|
||||
ADD_DEFINITIONS("-D_CRT_NONSTDC_NO_DEPRECATE")
|
||||
ENDIF(MSVC)
|
||||
|
||||
if(WIN32)
|
||||
if(HAVE_WINDOWS_CRYPTO)
|
||||
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} bcrypt)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
|
||||
ADD_DEFINITIONS(-DMS_UWP)
|
||||
else(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
|
||||
SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} advapi32)
|
||||
endif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
|
||||
endif(WIN32)
|
||||
|
||||
ADD_DEFINITIONS("-DHAVE_CONFIG_H")
|
||||
|
||||
# rpath handling: use rpath in installed binaries
|
||||
IF(NOT CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
ENDIF()
|
||||
|
||||
# fixed size integral types
|
||||
|
||||
IF(HAVE_INTTYPES_H_LIBZIP)
|
||||
SET(LIBZIP_TYPES_INCLUDE "#define __STDC_FORMAT_MACROS 1
|
||||
#include <inttypes.h>")
|
||||
ELSEIF(HAVE_STDINT_H_LIBZIP)
|
||||
SET(LIBZIP_TYPES_INCLUDE "#include <stdint.h>")
|
||||
ELSEIF(HAVE_SYS_TYPES_H_LIBZIP)
|
||||
SET(LIBZIP_TYPES_INCLUDE "#include <sys/types.h>")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_INT8_T_LIBZIP)
|
||||
SET(ZIP_INT8_T int8_t)
|
||||
ELSEIF(HAVE___INT8_LIBZIP)
|
||||
SET(ZIP_INT8_T __int8)
|
||||
ELSE()
|
||||
SET(ZIP_INT8_T "signed char")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_UINT8_T_LIBZIP)
|
||||
SET(ZIP_UINT8_T uint8_t)
|
||||
ELSEIF(HAVE___INT8_LIBZIP)
|
||||
SET(ZIP_UINT8_T "unsigned __int8")
|
||||
ELSE()
|
||||
SET(ZIP_UINT8_T "unsigned char")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_INT16_T_LIBZIP)
|
||||
SET(ZIP_INT16_T int16_t)
|
||||
ELSEIF(HAVE___INT16_LIBZIP)
|
||||
SET(INT16_T_LIBZIP __int16)
|
||||
ELSEIF(SHORT_LIBZIP EQUAL 2)
|
||||
SET(INT16_T_LIBZIP short)
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_UINT16_T_LIBZIP)
|
||||
SET(ZIP_UINT16_T uint16_t)
|
||||
ELSEIF(HAVE___INT16_LIBZIP)
|
||||
SET(UINT16_T_LIBZIP "unsigned __int16")
|
||||
ELSEIF(SHORT_LIBZIP EQUAL 2)
|
||||
SET(UINT16_T_LIBZIP "unsigned short")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_INT32_T_LIBZIP)
|
||||
SET(ZIP_INT32_T int32_t)
|
||||
ELSEIF(HAVE___INT32_LIBZIP)
|
||||
SET(ZIP_INT32_T __int32)
|
||||
ELSEIF(INT_LIBZIP EQUAL 4)
|
||||
SET(ZIP_INT32_T int)
|
||||
ELSEIF(LONG_LIBZIP EQUAL 4)
|
||||
SET(ZIP_INT32_T long)
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_UINT32_T_LIBZIP)
|
||||
SET(ZIP_UINT32_T uint32_t)
|
||||
ELSEIF(HAVE___INT32_LIBZIP)
|
||||
SET(ZIP_UINT32_T "unsigned __int32")
|
||||
ELSEIF(INT_LIBZIP EQUAL 4)
|
||||
SET(ZIP_UINT32_T "unsigned int")
|
||||
ELSEIF(LONG_LIBZIP EQUAL 4)
|
||||
SET(ZIP_UINT32_T "unsigned long")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_INT64_T_LIBZIP)
|
||||
SET(ZIP_INT64_T int64_t)
|
||||
ELSEIF(HAVE___INT64_LIBZIP)
|
||||
SET(ZIP_INT64_T __int64)
|
||||
ELSEIF(LONG_LIBZIP EQUAL 8)
|
||||
SET(ZIP_INT64_T long)
|
||||
ELSEIF(LONG_LONG_LIBZIP EQUAL 8)
|
||||
SET(ZIP_INT64_T "long long")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_UINT64_T_LIBZIP)
|
||||
SET(ZIP_UINT64_T uint64_t)
|
||||
ELSEIF(HAVE___INT64_LIBZIP)
|
||||
SET(ZIP_UINT64_T "unsigned __int64")
|
||||
ELSEIF(LONG_LIBZIP EQUAL 8)
|
||||
SET(ZIP_UINT64_T "unsigned long")
|
||||
ELSEIF(LONG_LONG_LIBZIP EQUAL 8)
|
||||
SET(ZIP_UINT64_T "unsigned long long")
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_NULLABLE)
|
||||
SET(ZIP_NULLABLE_DEFINES)
|
||||
ELSE()
|
||||
SET(ZIP_NULLABLE_DEFINES "#define _Nullable
|
||||
#define _Nonnull")
|
||||
ENDIF()
|
||||
|
||||
# write out config file
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libzip/cmake-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/libzip/config.h)
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libzip/cmake-zipconf.h.in ${CMAKE_CURRENT_BINARY_DIR}/libzip/zipconf.h)
|
||||
|
||||
# installation
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libzip/zipconf.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
INSTALL(FILES libzip/lib/zip.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
SET(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
|
||||
ADD_LIBRARY(zip
|
||||
libzip/lib/zip_add.c
|
||||
libzip/lib/zip_add_dir.c
|
||||
libzip/lib/zip_add_entry.c
|
||||
libzip/lib/zip_algorithm_deflate.c
|
||||
libzip/lib/zip_buffer.c
|
||||
libzip/lib/zip_close.c
|
||||
libzip/lib/zip_delete.c
|
||||
libzip/lib/zip_dir_add.c
|
||||
libzip/lib/zip_dirent.c
|
||||
libzip/lib/zip_discard.c
|
||||
libzip/lib/zip_entry.c
|
||||
libzip/lib/zip_err_str.c
|
||||
libzip/lib/zip_error.c
|
||||
libzip/lib/zip_error_clear.c
|
||||
libzip/lib/zip_error_get.c
|
||||
libzip/lib/zip_error_get_sys_type.c
|
||||
libzip/lib/zip_error_strerror.c
|
||||
libzip/lib/zip_error_to_str.c
|
||||
libzip/lib/zip_extra_field.c
|
||||
libzip/lib/zip_extra_field_api.c
|
||||
libzip/lib/zip_fclose.c
|
||||
libzip/lib/zip_fdopen.c
|
||||
libzip/lib/zip_file_add.c
|
||||
libzip/lib/zip_file_error_clear.c
|
||||
libzip/lib/zip_file_error_get.c
|
||||
libzip/lib/zip_file_get_comment.c
|
||||
libzip/lib/zip_file_get_external_attributes.c
|
||||
libzip/lib/zip_file_get_offset.c
|
||||
libzip/lib/zip_file_rename.c
|
||||
libzip/lib/zip_file_replace.c
|
||||
libzip/lib/zip_file_set_comment.c
|
||||
libzip/lib/zip_file_set_encryption.c
|
||||
libzip/lib/zip_file_set_external_attributes.c
|
||||
libzip/lib/zip_file_set_mtime.c
|
||||
libzip/lib/zip_file_strerror.c
|
||||
libzip/lib/zip_filerange_crc.c
|
||||
libzip/lib/zip_fopen.c
|
||||
libzip/lib/zip_fopen_encrypted.c
|
||||
libzip/lib/zip_fopen_index.c
|
||||
libzip/lib/zip_fopen_index_encrypted.c
|
||||
libzip/lib/zip_fread.c
|
||||
libzip/lib/zip_fseek.c
|
||||
libzip/lib/zip_ftell.c
|
||||
libzip/lib/zip_get_archive_comment.c
|
||||
libzip/lib/zip_get_archive_flag.c
|
||||
libzip/lib/zip_get_encryption_implementation.c
|
||||
libzip/lib/zip_get_file_comment.c
|
||||
libzip/lib/zip_get_name.c
|
||||
libzip/lib/zip_get_num_entries.c
|
||||
libzip/lib/zip_get_num_files.c
|
||||
libzip/lib/zip_hash.c
|
||||
libzip/lib/zip_io_util.c
|
||||
libzip/lib/zip_libzip_version.c
|
||||
libzip/lib/zip_memdup.c
|
||||
libzip/lib/zip_name_locate.c
|
||||
libzip/lib/zip_new.c
|
||||
libzip/lib/zip_open.c
|
||||
libzip/lib/zip_progress.c
|
||||
libzip/lib/zip_rename.c
|
||||
libzip/lib/zip_replace.c
|
||||
libzip/lib/zip_set_archive_comment.c
|
||||
libzip/lib/zip_set_archive_flag.c
|
||||
libzip/lib/zip_set_default_password.c
|
||||
libzip/lib/zip_set_file_comment.c
|
||||
libzip/lib/zip_set_file_compression.c
|
||||
libzip/lib/zip_set_name.c
|
||||
libzip/lib/zip_source_accept_empty.c
|
||||
libzip/lib/zip_source_begin_write.c
|
||||
libzip/lib/zip_source_begin_write_cloning.c
|
||||
libzip/lib/zip_source_buffer.c
|
||||
libzip/lib/zip_source_call.c
|
||||
libzip/lib/zip_source_close.c
|
||||
libzip/lib/zip_source_commit_write.c
|
||||
libzip/lib/zip_source_compress.c
|
||||
libzip/lib/zip_source_crc.c
|
||||
libzip/lib/zip_source_error.c
|
||||
libzip/lib/zip_source_filep.c
|
||||
libzip/lib/zip_source_free.c
|
||||
libzip/lib/zip_source_function.c
|
||||
libzip/lib/zip_source_get_compression_flags.c
|
||||
libzip/lib/zip_source_is_deleted.c
|
||||
libzip/lib/zip_source_layered.c
|
||||
libzip/lib/zip_source_open.c
|
||||
libzip/lib/zip_source_pkware.c
|
||||
libzip/lib/zip_source_read.c
|
||||
libzip/lib/zip_source_remove.c
|
||||
libzip/lib/zip_source_rollback_write.c
|
||||
libzip/lib/zip_source_seek.c
|
||||
libzip/lib/zip_source_seek_write.c
|
||||
libzip/lib/zip_source_stat.c
|
||||
libzip/lib/zip_source_supports.c
|
||||
libzip/lib/zip_source_tell.c
|
||||
libzip/lib/zip_source_tell_write.c
|
||||
libzip/lib/zip_source_window.c
|
||||
libzip/lib/zip_source_write.c
|
||||
libzip/lib/zip_source_zip.c
|
||||
libzip/lib/zip_source_zip_new.c
|
||||
libzip/lib/zip_stat.c
|
||||
libzip/lib/zip_stat_index.c
|
||||
libzip/lib/zip_stat_init.c
|
||||
libzip/lib/zip_strerror.c
|
||||
libzip/lib/zip_string.c
|
||||
libzip/lib/zip_unchange.c
|
||||
libzip/lib/zip_unchange_all.c
|
||||
libzip/lib/zip_unchange_archive.c
|
||||
libzip/lib/zip_unchange_data.c
|
||||
libzip/lib/zip_utf-8.c
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
target_sources(zip PRIVATE
|
||||
libzip/lib/zip_source_win32handle.c
|
||||
libzip/lib/zip_source_win32utf8.c
|
||||
libzip/lib/zip_source_win32w.c
|
||||
)
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
|
||||
ELSE()
|
||||
target_sources(zip PRIVATE libzip/lib/zip_source_win32a.c)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
target_sources(zip PRIVATE
|
||||
libzip/lib/zip_mkstempm.c
|
||||
libzip/lib/zip_source_file.c
|
||||
libzip/lib/zip_random_unix.c
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_LIBBZ2)
|
||||
target_sources(zip PRIVATE libzip/lib/zip_algorithm_bzip2.c)
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_LIBLZMA)
|
||||
target_sources(zip PRIVATE libzip/lib/zip_algorithm_xz.c)
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_COMMONCRYPTO)
|
||||
target_sources(zip PRIVATE libzip/lib/zip_crypto_commoncrypto.c)
|
||||
ELSEIF(HAVE_WINDOWS_CRYPTO)
|
||||
target_sources(zip PRIVATE libzip/lib/zip_crypto_win.c)
|
||||
ELSEIF(HAVE_GNUTLS)
|
||||
target_sources(zip PRIVATE libzip/lib/zip_crypto_gnutls.c)
|
||||
ELSEIF(HAVE_OPENSSL)
|
||||
target_sources(zip PRIVATE libzip/lib/zip_crypto_openssl.c)
|
||||
ELSEIF(HAVE_MBEDTLS)
|
||||
target_sources(zip PRIVATE libzip/lib/zip_crypto_mbedtls.c)
|
||||
ENDIF()
|
||||
|
||||
IF(HAVE_CRYPTO)
|
||||
target_sources(zip PRIVATE
|
||||
libzip/lib/zip_winzip_aes.c
|
||||
libzip/lib/zip_source_winzip_aes_decode.c
|
||||
libzip/lib/zip_source_winzip_aes_encode.c
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
target_include_directories(zip
|
||||
PUBLIC
|
||||
libzip/lib
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libzip
|
||||
)
|
||||
|
||||
# pkgconfig file
|
||||
SET(prefix ${CMAKE_INSTALL_PREFIX})
|
||||
SET(exec_prefix \${prefix})
|
||||
SET(bindir \${exec_prefix}/${CMAKE_INSTALL_BINDIR})
|
||||
SET(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
|
||||
SET(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES BSD)
|
||||
SET(PKG_CONFIG_RPATH "-Wl,-R\${libdir}")
|
||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES BSD)
|
||||
get_target_property(LIBS_PRIVATE zip LINK_LIBRARIES)
|
||||
foreach(LIB ${LIBS_PRIVATE})
|
||||
if(LIB MATCHES "^/")
|
||||
get_filename_component(LIB ${LIB} NAME_WE)
|
||||
string(REGEX REPLACE "^lib" "" LIB ${LIB})
|
||||
endif()
|
||||
set(LIBS "${LIBS} -l${LIB}")
|
||||
endforeach()
|
||||
CONFIGURE_FILE(libzip/libzip.pc.in libzip/libzip.pc @ONLY)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libzip.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
ADD_CUSTOM_TARGET(update_zip_err_str
|
||||
COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/make_zip_err_str.sh ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip.h ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip_err_str.c
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip.h ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/make_zip_err_str.sh
|
||||
)
|
||||
|
||||
IF(SHARED_LIB_VERSIONNING)
|
||||
SET_TARGET_PROPERTIES(zip PROPERTIES VERSION 5.0 SOVERSION 5)
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(zip ${ZLIB_LIBRARIES} ${OPTIONAL_LIBRARY})
|
||||
INSTALL(TARGETS zip
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
1
externals/libzip/libzip
vendored
Submodule
1
externals/libzip/libzip
vendored
Submodule
Submodule externals/libzip/libzip added at 89bd6d63bd
6
externals/microprofile/microprofile.h
vendored
6
externals/microprofile/microprofile.h
vendored
@@ -814,7 +814,7 @@ struct MicroProfile
|
||||
|
||||
inline int MicroProfileLogType(MicroProfileLogEntry Index)
|
||||
{
|
||||
return ((MP_LOG_BEGIN_MASK & Index)>>62) & 0x3;
|
||||
return (int)(((MP_LOG_BEGIN_MASK & Index)>>62) & 0x3ULL);
|
||||
}
|
||||
|
||||
inline uint64_t MicroProfileLogTimerIndex(MicroProfileLogEntry Index)
|
||||
@@ -861,12 +861,12 @@ T MicroProfileMax(T a, T b)
|
||||
|
||||
inline int64_t MicroProfileMsToTick(float fMs, int64_t nTicksPerSecond)
|
||||
{
|
||||
return (int64_t)(fMs*0.001f*nTicksPerSecond);
|
||||
return (int64_t)(fMs*0.001f*(float)nTicksPerSecond);
|
||||
}
|
||||
|
||||
inline float MicroProfileTickToMsMultiplier(int64_t nTicksPerSecond)
|
||||
{
|
||||
return 1000.f / nTicksPerSecond;
|
||||
return 1000.f / (float)nTicksPerSecond;
|
||||
}
|
||||
|
||||
inline uint16_t MicroProfileGetGroupIndex(MicroProfileToken t)
|
||||
|
||||
81
externals/zlib/CMakeLists.txt
vendored
Normal file
81
externals/zlib/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
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/
|
||||
)
|
||||
0
externals/zlib → externals/zlib/zlib
vendored
0
externals/zlib → externals/zlib/zlib
vendored
@@ -3,17 +3,8 @@
|
||||
# could affect the result, but much more unlikely than the following files. Keeping a list of files
|
||||
# like this allows for much better caching since it doesn't force the user to recompile binary shaders every update
|
||||
set(VIDEO_CORE "${CMAKE_SOURCE_DIR}/src/video_core")
|
||||
if (DEFINED ENV{CI})
|
||||
if (DEFINED ENV{TRAVIS})
|
||||
set(BUILD_REPOSITORY $ENV{TRAVIS_REPO_SLUG})
|
||||
set(BUILD_TAG $ENV{TRAVIS_TAG})
|
||||
elseif(DEFINED ENV{APPVEYOR})
|
||||
set(BUILD_REPOSITORY $ENV{APPVEYOR_REPO_NAME})
|
||||
set(BUILD_TAG $ENV{APPVEYOR_REPO_TAG_NAME})
|
||||
elseif(DEFINED ENV{AZURE})
|
||||
set(BUILD_REPOSITORY $ENV{AZURE_REPO_NAME})
|
||||
set(BUILD_TAG $ENV{AZURE_REPO_TAG})
|
||||
endif()
|
||||
if (DEFINED ENV{AZURECIREPO})
|
||||
set(BUILD_REPOSITORY $ENV{AZURECIREPO})
|
||||
endif()
|
||||
if (DEFINED ENV{TITLEBARFORMATIDLE})
|
||||
set(TITLE_BAR_FORMAT_IDLE $ENV{TITLEBARFORMATIDLE})
|
||||
|
||||
@@ -28,18 +28,14 @@ __declspec(noinline, noreturn)
|
||||
}
|
||||
|
||||
#define ASSERT(_a_) \
|
||||
do \
|
||||
if (!(_a_)) { \
|
||||
assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \
|
||||
} \
|
||||
while (0)
|
||||
if (!(_a_)) { \
|
||||
LOG_CRITICAL(Debug, "Assertion Failed!"); \
|
||||
}
|
||||
|
||||
#define ASSERT_MSG(_a_, ...) \
|
||||
do \
|
||||
if (!(_a_)) { \
|
||||
assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
|
||||
} \
|
||||
while (0)
|
||||
if (!(_a_)) { \
|
||||
LOG_CRITICAL(Debug, "Assertion Failed! " __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define UNREACHABLE() ASSERT_MSG(false, "Unreachable code!")
|
||||
#define UNREACHABLE_MSG(...) ASSERT_MSG(false, __VA_ARGS__)
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/swap.h"
|
||||
|
||||
// Inlining
|
||||
#ifdef _WIN32
|
||||
#define FORCE_INLINE __forceinline
|
||||
#else
|
||||
#define FORCE_INLINE inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Abstract bitfield class
|
||||
*
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
|
||||
// Copyright 2019 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#if !defined(ARCHITECTURE_x86_64)
|
||||
@@ -16,18 +17,17 @@
|
||||
#define CONCAT2(x, y) DO_CONCAT2(x, y)
|
||||
#define DO_CONCAT2(x, y) x##y
|
||||
|
||||
// helper macro to properly align structure members.
|
||||
// Calling INSERT_PADDING_BYTES will add a new member variable with a name like "pad121",
|
||||
// depending on the current source line to make sure variable names are unique.
|
||||
#define INSERT_PADDING_BYTES(num_bytes) u8 CONCAT2(pad, __LINE__)[(num_bytes)]
|
||||
#define INSERT_PADDING_WORDS(num_words) u32 CONCAT2(pad, __LINE__)[(num_words)]
|
||||
/// Helper macros to insert unused bytes or words to properly align structs. These values will be
|
||||
/// zero-initialized.
|
||||
#define INSERT_PADDING_BYTES(num_bytes) \
|
||||
std::array<u8, num_bytes> CONCAT2(pad, __LINE__) {}
|
||||
#define INSERT_PADDING_WORDS(num_words) \
|
||||
std::array<u32, num_words> CONCAT2(pad, __LINE__) {}
|
||||
|
||||
// Inlining
|
||||
#ifdef _WIN32
|
||||
#define FORCE_INLINE __forceinline
|
||||
#else
|
||||
#define FORCE_INLINE inline __attribute__((always_inline))
|
||||
#endif
|
||||
/// These are similar to the INSERT_PADDING_* macros, but are needed for padding unions. This is
|
||||
/// because unions can only be initialized by one member.
|
||||
#define INSERT_UNION_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__)
|
||||
#define INSERT_UNION_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__)
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
@@ -58,7 +58,7 @@ std::string GetLastErrorMsg();
|
||||
namespace Common {
|
||||
|
||||
constexpr u32 MakeMagic(char a, char b, char c, char d) {
|
||||
return a | b << 8 | c << 16 | d << 24;
|
||||
return u32(a) | u32(b) << 8 | u32(c) << 16 | u32(d) << 24;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
||||
@@ -35,41 +35,6 @@ static inline u64 ComputeStructHash64(const T& data) {
|
||||
return ComputeHash64(&data, sizeof(data));
|
||||
}
|
||||
|
||||
/// A helper template that ensures the padding in a struct is initialized by memsetting to 0.
|
||||
template <typename T>
|
||||
struct HashableStruct {
|
||||
// In addition to being trivially copyable, T must also have a trivial default constructor,
|
||||
// because any member initialization would be overridden by memset
|
||||
static_assert(std::is_trivial_v<T>, "Type passed to HashableStruct must be trivial");
|
||||
/*
|
||||
* We use a union because "implicitly-defined copy/move constructor for a union X copies the
|
||||
* object representation of X." and "implicitly-defined copy assignment operator for a union X
|
||||
* copies the object representation (3.9) of X." = Bytewise copy instead of memberwise copy.
|
||||
* This is important because the padding bytes are included in the hash and comparison between
|
||||
* objects.
|
||||
*/
|
||||
union {
|
||||
T state;
|
||||
};
|
||||
|
||||
HashableStruct() {
|
||||
// Memset structure to zero padding bits, so that they will be deterministic when hashing
|
||||
std::memset(&state, 0, sizeof(T));
|
||||
}
|
||||
|
||||
bool operator==(const HashableStruct<T>& o) const {
|
||||
return std::memcmp(&state, &o.state, sizeof(T)) == 0;
|
||||
};
|
||||
|
||||
bool operator!=(const HashableStruct<T>& o) const {
|
||||
return !(*this == o);
|
||||
};
|
||||
|
||||
std::size_t Hash() const {
|
||||
return Common::ComputeStructHash64(state);
|
||||
}
|
||||
};
|
||||
|
||||
struct PairHash {
|
||||
template <class T1, class T2>
|
||||
std::size_t operator()(const std::pair<T1, T2>& pair) const noexcept {
|
||||
|
||||
@@ -522,6 +522,23 @@ add_library(core STATIC
|
||||
tools/freezer.h
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(core PRIVATE
|
||||
# 'expression' : signed/unsigned mismatch
|
||||
/we4018
|
||||
# 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point)
|
||||
/we4244
|
||||
# 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
|
||||
/we4245
|
||||
# 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
|
||||
/we4254
|
||||
# 'var' : conversion from 'size_t' to 'type', possible loss of data
|
||||
/we4267
|
||||
# 'context' : truncation from 'type1' to 'type2'
|
||||
/we4305
|
||||
)
|
||||
endif()
|
||||
|
||||
create_target_directory_groups(core)
|
||||
|
||||
target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
ARM_Interface::ThreadContext ctx;
|
||||
parent.SaveContext(ctx);
|
||||
parent.inner_unicorn.LoadContext(ctx);
|
||||
parent.inner_unicorn.ExecuteInstructions(static_cast<int>(num_instructions));
|
||||
parent.inner_unicorn.ExecuteInstructions(num_instructions);
|
||||
parent.inner_unicorn.SaveContext(ctx);
|
||||
parent.LoadContext(ctx);
|
||||
num_interpreted_instructions += num_instructions;
|
||||
|
||||
@@ -67,10 +67,11 @@ ARM_Unicorn::ARM_Unicorn(System& system) : system{system} {
|
||||
CHECKED(uc_reg_write(uc, UC_ARM64_REG_CPACR_EL1, &fpv));
|
||||
|
||||
uc_hook hook{};
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, -1));
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0, -1));
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, UINT64_MAX));
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0,
|
||||
UINT64_MAX));
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, -1));
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, UINT64_MAX));
|
||||
last_bkpt_hit = false;
|
||||
}
|
||||
}
|
||||
@@ -154,9 +155,10 @@ void ARM_Unicorn::SetTPIDR_EL0(u64 value) {
|
||||
|
||||
void ARM_Unicorn::Run() {
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
ExecuteInstructions(std::max(4000000, 0));
|
||||
ExecuteInstructions(std::max(4000000U, 0U));
|
||||
} else {
|
||||
ExecuteInstructions(std::max(system.CoreTiming().GetDowncount(), s64{0}));
|
||||
ExecuteInstructions(
|
||||
std::max(std::size_t(system.CoreTiming().GetDowncount()), std::size_t{0}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +168,7 @@ void ARM_Unicorn::Step() {
|
||||
|
||||
MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));
|
||||
|
||||
void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
|
||||
void ARM_Unicorn::ExecuteInstructions(std::size_t num_instructions) {
|
||||
MICROPROFILE_SCOPE(ARM_Jit_Unicorn);
|
||||
CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
|
||||
system.CoreTiming().AddTicks(num_instructions);
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
void LoadContext(const ThreadContext& ctx) override;
|
||||
void PrepareReschedule() override;
|
||||
void ClearExclusiveState() override;
|
||||
void ExecuteInstructions(int num_instructions);
|
||||
void ExecuteInstructions(std::size_t num_instructions);
|
||||
void Run() override;
|
||||
void Step() override;
|
||||
void ClearInstructionCache() override;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "common/file_util.h"
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/crypto/aes_util.h"
|
||||
#include "core/crypto/key_manager.h"
|
||||
@@ -378,8 +379,9 @@ std::vector<Ticket> GetTicketblob(const FileUtil::IOFile& ticket_save) {
|
||||
template <size_t size>
|
||||
static std::array<u8, size> operator^(const std::array<u8, size>& lhs,
|
||||
const std::array<u8, size>& rhs) {
|
||||
std::array<u8, size> out{};
|
||||
std::transform(lhs.begin(), lhs.end(), rhs.begin(), out.begin(), std::bit_xor<>());
|
||||
std::array<u8, size> out;
|
||||
std::transform(lhs.begin(), lhs.end(), rhs.begin(), out.begin(),
|
||||
[](u8 lhs, u8 rhs) { return u8(lhs ^ rhs); });
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -396,7 +398,7 @@ static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) {
|
||||
while (out.size() < target_size) {
|
||||
out.resize(out.size() + 0x20);
|
||||
seed_exp[in_size + 3] = static_cast<u8>(i);
|
||||
mbedtls_sha256(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0);
|
||||
mbedtls_sha256_ret(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0);
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -538,7 +540,7 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
|
||||
Key128 key = Common::HexStringToArray<16>(out[1]);
|
||||
s128_keys[{S128KeyType::Titlekey, rights_id[1], rights_id[0]}] = key;
|
||||
} else {
|
||||
std::transform(out[0].begin(), out[0].end(), out[0].begin(), ::tolower);
|
||||
out[0] = Common::ToLower(out[0]);
|
||||
if (s128_file_id.find(out[0]) != s128_file_id.end()) {
|
||||
const auto index = s128_file_id.at(out[0]);
|
||||
Key128 key = Common::HexStringToArray<16>(out[1]);
|
||||
@@ -668,23 +670,27 @@ void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname,
|
||||
const std::array<u8, Size>& key) {
|
||||
const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
|
||||
std::string filename = "title.keys_autogenerated";
|
||||
if (category == KeyCategory::Standard)
|
||||
if (category == KeyCategory::Standard) {
|
||||
filename = dev_mode ? "dev.keys_autogenerated" : "prod.keys_autogenerated";
|
||||
else if (category == KeyCategory::Console)
|
||||
} else if (category == KeyCategory::Console) {
|
||||
filename = "console.keys_autogenerated";
|
||||
const auto add_info_text = !FileUtil::Exists(yuzu_keys_dir + DIR_SEP + filename);
|
||||
FileUtil::CreateFullPath(yuzu_keys_dir + DIR_SEP + filename);
|
||||
std::ofstream file(yuzu_keys_dir + DIR_SEP + filename, std::ios::app);
|
||||
if (!file.is_open())
|
||||
return;
|
||||
if (add_info_text) {
|
||||
file
|
||||
<< "# This file is autogenerated by Yuzu\n"
|
||||
<< "# It serves to store keys that were automatically generated from the normal keys\n"
|
||||
<< "# If you are experiencing issues involving keys, it may help to delete this file\n";
|
||||
}
|
||||
|
||||
file << fmt::format("\n{} = {}", keyname, Common::HexToString(key));
|
||||
const auto path = yuzu_keys_dir + DIR_SEP + filename;
|
||||
const auto add_info_text = !FileUtil::Exists(path);
|
||||
FileUtil::CreateFullPath(path);
|
||||
FileUtil::IOFile file{path, "a"};
|
||||
if (!file.IsOpen()) {
|
||||
return;
|
||||
}
|
||||
if (add_info_text) {
|
||||
file.WriteString(
|
||||
"# This file is autogenerated by Yuzu\n"
|
||||
"# It serves to store keys that were automatically generated from the normal keys\n"
|
||||
"# If you are experiencing issues involving keys, it may help to delete this file\n");
|
||||
}
|
||||
|
||||
file.WriteString(fmt::format("\n{} = {}", keyname, Common::HexToString(key)));
|
||||
AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, filename, category == KeyCategory::Title);
|
||||
}
|
||||
|
||||
@@ -944,12 +950,10 @@ void KeyManager::DeriveETicket(PartitionDataManager& data) {
|
||||
return;
|
||||
}
|
||||
|
||||
Key128 rsa_oaep_kek{};
|
||||
std::transform(seed3.begin(), seed3.end(), mask0.begin(), rsa_oaep_kek.begin(),
|
||||
std::bit_xor<>());
|
||||
|
||||
if (rsa_oaep_kek == Key128{})
|
||||
const Key128 rsa_oaep_kek = seed3 ^ mask0;
|
||||
if (rsa_oaep_kek == Key128{}) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetKey(S128KeyType::Source, rsa_oaep_kek,
|
||||
static_cast<u64>(SourceKeyType::RSAOaepKekGeneration));
|
||||
|
||||
@@ -161,7 +161,7 @@ std::array<u8, key_size> FindKeyFromHex(const std::vector<u8>& binary,
|
||||
|
||||
std::array<u8, 0x20> temp{};
|
||||
for (size_t i = 0; i < binary.size() - key_size; ++i) {
|
||||
mbedtls_sha256(binary.data() + i, key_size, temp.data(), 0);
|
||||
mbedtls_sha256_ret(binary.data() + i, key_size, temp.data(), 0);
|
||||
|
||||
if (temp != hash)
|
||||
continue;
|
||||
@@ -189,7 +189,7 @@ static std::array<Key128, 0x20> FindEncryptedMasterKeyFromHex(const std::vector<
|
||||
AESCipher<Key128> cipher(key, Mode::ECB);
|
||||
for (size_t i = 0; i < binary.size() - 0x10; ++i) {
|
||||
cipher.Transcode(binary.data() + i, dec_temp.size(), dec_temp.data(), Op::Decrypt);
|
||||
mbedtls_sha256(dec_temp.data(), dec_temp.size(), temp.data(), 0);
|
||||
mbedtls_sha256_ret(dec_temp.data(), dec_temp.size(), temp.data(), 0);
|
||||
|
||||
for (size_t k = 0; k < out.size(); ++k) {
|
||||
if (temp == master_key_hashes[k]) {
|
||||
@@ -204,11 +204,12 @@ static std::array<Key128, 0x20> FindEncryptedMasterKeyFromHex(const std::vector<
|
||||
|
||||
FileSys::VirtualFile FindFileInDirWithNames(const FileSys::VirtualDir& dir,
|
||||
const std::string& name) {
|
||||
auto upper = name;
|
||||
std::transform(upper.begin(), upper.end(), upper.begin(), [](u8 c) { return std::toupper(c); });
|
||||
const auto upper = Common::ToUpper(name);
|
||||
|
||||
for (const auto& fname : {name, name + ".bin", upper, upper + ".BIN"}) {
|
||||
if (dir->GetFile(fname) != nullptr)
|
||||
if (dir->GetFile(fname) != nullptr) {
|
||||
return dir->GetFile(fname);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
@@ -32,11 +32,28 @@ enum class NCASectionFilesystemType : u8 {
|
||||
ROMFS = 0x3,
|
||||
};
|
||||
|
||||
struct IVFCLevel {
|
||||
u64_le offset;
|
||||
u64_le size;
|
||||
u32_le block_size;
|
||||
u32_le reserved;
|
||||
};
|
||||
static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
|
||||
|
||||
struct IVFCHeader {
|
||||
u32_le magic;
|
||||
u32_le magic_number;
|
||||
INSERT_UNION_PADDING_BYTES(8);
|
||||
std::array<IVFCLevel, 6> levels;
|
||||
INSERT_UNION_PADDING_BYTES(64);
|
||||
};
|
||||
static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
|
||||
|
||||
struct NCASectionHeaderBlock {
|
||||
INSERT_PADDING_BYTES(3);
|
||||
INSERT_UNION_PADDING_BYTES(3);
|
||||
NCASectionFilesystemType filesystem_type;
|
||||
NCASectionCryptoType crypto_type;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
INSERT_UNION_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size.");
|
||||
|
||||
@@ -44,7 +61,7 @@ struct NCASectionRaw {
|
||||
NCASectionHeaderBlock header;
|
||||
std::array<u8, 0x138> block_data;
|
||||
std::array<u8, 0x8> section_ctr;
|
||||
INSERT_PADDING_BYTES(0xB8);
|
||||
INSERT_UNION_PADDING_BYTES(0xB8);
|
||||
};
|
||||
static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size.");
|
||||
|
||||
@@ -52,19 +69,19 @@ struct PFS0Superblock {
|
||||
NCASectionHeaderBlock header_block;
|
||||
std::array<u8, 0x20> hash;
|
||||
u32_le size;
|
||||
INSERT_PADDING_BYTES(4);
|
||||
INSERT_UNION_PADDING_BYTES(4);
|
||||
u64_le hash_table_offset;
|
||||
u64_le hash_table_size;
|
||||
u64_le pfs0_header_offset;
|
||||
u64_le pfs0_size;
|
||||
INSERT_PADDING_BYTES(0x1B0);
|
||||
INSERT_UNION_PADDING_BYTES(0x1B0);
|
||||
};
|
||||
static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size.");
|
||||
|
||||
struct RomFSSuperblock {
|
||||
NCASectionHeaderBlock header_block;
|
||||
IVFCHeader ivfc;
|
||||
INSERT_PADDING_BYTES(0x118);
|
||||
INSERT_UNION_PADDING_BYTES(0x118);
|
||||
};
|
||||
static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size.");
|
||||
|
||||
@@ -72,24 +89,24 @@ struct BKTRHeader {
|
||||
u64_le offset;
|
||||
u64_le size;
|
||||
u32_le magic;
|
||||
INSERT_PADDING_BYTES(0x4);
|
||||
INSERT_UNION_PADDING_BYTES(0x4);
|
||||
u32_le number_entries;
|
||||
INSERT_PADDING_BYTES(0x4);
|
||||
INSERT_UNION_PADDING_BYTES(0x4);
|
||||
};
|
||||
static_assert(sizeof(BKTRHeader) == 0x20, "BKTRHeader has incorrect size.");
|
||||
|
||||
struct BKTRSuperblock {
|
||||
NCASectionHeaderBlock header_block;
|
||||
IVFCHeader ivfc;
|
||||
INSERT_PADDING_BYTES(0x18);
|
||||
INSERT_UNION_PADDING_BYTES(0x18);
|
||||
BKTRHeader relocation;
|
||||
BKTRHeader subsection;
|
||||
INSERT_PADDING_BYTES(0xC0);
|
||||
INSERT_UNION_PADDING_BYTES(0xC0);
|
||||
};
|
||||
static_assert(sizeof(BKTRSuperblock) == 0x200, "BKTRSuperblock has incorrect size.");
|
||||
|
||||
union NCASectionHeader {
|
||||
NCASectionRaw raw;
|
||||
NCASectionRaw raw{};
|
||||
PFS0Superblock pfs0;
|
||||
RomFSSuperblock romfs;
|
||||
BKTRSuperblock bktr;
|
||||
|
||||
@@ -147,7 +147,7 @@ std::vector<u32> KIP::GetKernelCapabilities() const {
|
||||
}
|
||||
|
||||
s32 KIP::GetMainThreadPriority() const {
|
||||
return header.main_thread_priority;
|
||||
return static_cast<s32>(header.main_thread_priority);
|
||||
}
|
||||
|
||||
u32 KIP::GetMainThreadStackSize() const {
|
||||
|
||||
@@ -52,14 +52,14 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) {
|
||||
}
|
||||
|
||||
void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space,
|
||||
u8 main_thread_prio, u8 main_thread_core,
|
||||
s32 main_thread_prio, u32 main_thread_core,
|
||||
u32 main_thread_stack_size, u64 title_id,
|
||||
u64 filesystem_permissions,
|
||||
KernelCapabilityDescriptors capabilities) {
|
||||
npdm_header.has_64_bit_instructions.Assign(is_64_bit);
|
||||
npdm_header.address_space_type.Assign(address_space);
|
||||
npdm_header.main_thread_priority = main_thread_prio;
|
||||
npdm_header.main_thread_cpu = main_thread_core;
|
||||
npdm_header.main_thread_priority = static_cast<u8>(main_thread_prio);
|
||||
npdm_header.main_thread_cpu = static_cast<u8>(main_thread_core);
|
||||
npdm_header.main_stack_size = main_thread_stack_size;
|
||||
aci_header.title_id = title_id;
|
||||
aci_file_access.permissions = filesystem_permissions;
|
||||
|
||||
@@ -47,8 +47,8 @@ public:
|
||||
Loader::ResultStatus Load(VirtualFile file);
|
||||
|
||||
// Load from parameters instead of NPDM file, used for KIP
|
||||
void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, u8 main_thread_prio,
|
||||
u8 main_thread_core, u32 main_thread_stack_size, u64 title_id,
|
||||
void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio,
|
||||
u32 main_thread_core, u32 main_thread_stack_size, u64 title_id,
|
||||
u64 filesystem_permissions, KernelCapabilityDescriptors capabilities);
|
||||
|
||||
bool Is64BitProgram() const;
|
||||
|
||||
@@ -62,7 +62,7 @@ static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bo
|
||||
Common::HexToString(nca_id, second_hex_upper));
|
||||
|
||||
Core::Crypto::SHA256Hash hash{};
|
||||
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
|
||||
mbedtls_sha256_ret(nca_id.data(), nca_id.size(), hash.data(), 0);
|
||||
return fmt::format(cnmt_suffix ? "/000000{:02X}/{}.cnmt.nca" : "/000000{:02X}/{}.nca", hash[0],
|
||||
Common::HexToString(nca_id, second_hex_upper));
|
||||
}
|
||||
@@ -141,7 +141,7 @@ bool PlaceholderCache::Create(const NcaID& id, u64 size) const {
|
||||
}
|
||||
|
||||
Core::Crypto::SHA256Hash hash{};
|
||||
mbedtls_sha256(id.data(), id.size(), hash.data(), 0);
|
||||
mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
|
||||
const auto dirname = fmt::format("000000{:02X}", hash[0]);
|
||||
|
||||
const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
|
||||
@@ -165,7 +165,7 @@ bool PlaceholderCache::Delete(const NcaID& id) const {
|
||||
}
|
||||
|
||||
Core::Crypto::SHA256Hash hash{};
|
||||
mbedtls_sha256(id.data(), id.size(), hash.data(), 0);
|
||||
mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
|
||||
const auto dirname = fmt::format("000000{:02X}", hash[0]);
|
||||
|
||||
const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
|
||||
@@ -603,7 +603,7 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
|
||||
OptionalHeader opt_header{0, 0};
|
||||
ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}};
|
||||
const auto& data = nca.GetBaseFile()->ReadBytes(0x100000);
|
||||
mbedtls_sha256(data.data(), data.size(), c_rec.hash.data(), 0);
|
||||
mbedtls_sha256_ret(data.data(), data.size(), c_rec.hash.data(), 0);
|
||||
memcpy(&c_rec.nca_id, &c_rec.hash, 16);
|
||||
const CNMT new_cnmt(header, opt_header, {c_rec}, {});
|
||||
if (!RawInstallYuzuMeta(new_cnmt))
|
||||
@@ -626,7 +626,7 @@ InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFuncti
|
||||
id = *override_id;
|
||||
} else {
|
||||
const auto& data = in->ReadBytes(0x100000);
|
||||
mbedtls_sha256(data.data(), data.size(), hash.data(), 0);
|
||||
mbedtls_sha256_ret(data.data(), data.size(), hash.data(), 0);
|
||||
memcpy(id.data(), hash.data(), 16);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,25 +13,6 @@
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
struct RomFSHeader;
|
||||
|
||||
struct IVFCLevel {
|
||||
u64_le offset;
|
||||
u64_le size;
|
||||
u32_le block_size;
|
||||
u32_le reserved;
|
||||
};
|
||||
static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
|
||||
|
||||
struct IVFCHeader {
|
||||
u32_le magic;
|
||||
u32_le magic_number;
|
||||
INSERT_PADDING_BYTES(8);
|
||||
std::array<IVFCLevel, 6> levels;
|
||||
INSERT_PADDING_BYTES(64);
|
||||
};
|
||||
static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
|
||||
|
||||
enum class RomFSExtractionType {
|
||||
Full, // Includes data directory
|
||||
Truncated, // Traverses into data directory
|
||||
|
||||
@@ -71,12 +71,12 @@ ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage,
|
||||
|
||||
if (res == nullptr) {
|
||||
// TODO(DarkLordZach): Find the right error code to use here
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
const auto romfs = res->GetRomFS();
|
||||
if (romfs == nullptr) {
|
||||
// TODO(DarkLordZach): Find the right error code to use here
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
return MakeResult<VirtualFile>(romfs);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
|
||||
// Return an error if the save data doesn't actually exist.
|
||||
if (out == nullptr) {
|
||||
// TODO(DarkLordZach): Find out correct error code.
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
return MakeResult<VirtualDir>(std::move(out));
|
||||
@@ -111,7 +111,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
|
||||
// Return an error if the save data doesn't actually exist.
|
||||
if (out == nullptr) {
|
||||
// TODO(Subv): Find out correct error code.
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
return MakeResult<VirtualDir>(std::move(out));
|
||||
|
||||
@@ -27,7 +27,7 @@ VirtualDir ExtractZIP(VirtualFile file) {
|
||||
|
||||
std::shared_ptr<VectorVfsDirectory> out = std::make_shared<VectorVfsDirectory>();
|
||||
|
||||
const auto num_entries = zip_get_num_entries(zip.get(), 0);
|
||||
const auto num_entries = static_cast<std::size_t>(zip_get_num_entries(zip.get(), 0));
|
||||
|
||||
zip_stat_t stat{};
|
||||
zip_stat_init(&stat);
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include "common/assert.h"
|
||||
|
||||
#include "common/file_util.h"
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/crypto/aes_util.h"
|
||||
#include "core/crypto/xts_encryption_layer.h"
|
||||
#include "core/file_sys/partition_filesystem.h"
|
||||
@@ -53,18 +54,15 @@ NAX::NAX(VirtualFile file_) : header(std::make_unique<NAXHeader>()), file(std::m
|
||||
return;
|
||||
}
|
||||
|
||||
std::string two_dir = match[1];
|
||||
std::string nca_id = match[2];
|
||||
std::transform(two_dir.begin(), two_dir.end(), two_dir.begin(), ::toupper);
|
||||
std::transform(nca_id.begin(), nca_id.end(), nca_id.begin(), ::tolower);
|
||||
|
||||
const std::string two_dir = Common::ToUpper(match[1]);
|
||||
const std::string nca_id = Common::ToLower(match[2]);
|
||||
status = Parse(fmt::format("/registered/{}/{}.nca", two_dir, nca_id));
|
||||
}
|
||||
|
||||
NAX::NAX(VirtualFile file_, std::array<u8, 0x10> nca_id)
|
||||
: header(std::make_unique<NAXHeader>()), file(std::move(file_)) {
|
||||
Core::Crypto::SHA256Hash hash{};
|
||||
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
|
||||
mbedtls_sha256_ret(nca_id.data(), nca_id.size(), hash.data(), 0);
|
||||
status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0],
|
||||
Common::HexToString(nca_id, false)));
|
||||
}
|
||||
@@ -93,8 +91,7 @@ Loader::ResultStatus NAX::Parse(std::string_view path) {
|
||||
std::size_t i = 0;
|
||||
for (; i < sd_keys.size(); ++i) {
|
||||
std::array<Core::Crypto::Key128, 2> nax_keys{};
|
||||
if (!CalculateHMAC256(nax_keys.data(), sd_keys[i].data(), 0x10, std::string(path).c_str(),
|
||||
path.size())) {
|
||||
if (!CalculateHMAC256(nax_keys.data(), sd_keys[i].data(), 0x10, path.data(), path.size())) {
|
||||
return Loader::ResultStatus::ErrorNAXKeyHMACFailed;
|
||||
}
|
||||
|
||||
|
||||
@@ -468,7 +468,8 @@ static u8 ReadByte() {
|
||||
|
||||
/// Calculate the checksum of the current command buffer.
|
||||
static u8 CalculateChecksum(const u8* buffer, std::size_t length) {
|
||||
return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>()));
|
||||
return static_cast<u8>(std::accumulate(buffer, buffer + length, u8{0},
|
||||
[](u8 lhs, u8 rhs) { return u8(lhs + rhs); }));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -160,7 +160,7 @@ struct DomainMessageHeader {
|
||||
// Used when responding to an IPC request, Server -> Client.
|
||||
struct {
|
||||
u32_le num_objects;
|
||||
INSERT_PADDING_WORDS(3);
|
||||
INSERT_UNION_PADDING_WORDS(3);
|
||||
};
|
||||
|
||||
// Used when performing an IPC request, Client -> Server.
|
||||
@@ -171,8 +171,10 @@ struct DomainMessageHeader {
|
||||
BitField<16, 16, u32> size;
|
||||
};
|
||||
u32_le object_id;
|
||||
INSERT_PADDING_WORDS(2);
|
||||
INSERT_UNION_PADDING_WORDS(2);
|
||||
};
|
||||
|
||||
std::array<u32, 4> raw{};
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect");
|
||||
|
||||
@@ -58,8 +58,7 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
|
||||
auto& kernel = Core::System::GetInstance().Kernel();
|
||||
if (!writable_event) {
|
||||
// Create event if not provided
|
||||
const auto pair = WritableEvent::CreateEventPair(kernel, ResetType::Automatic,
|
||||
"HLE Pause Event: " + reason);
|
||||
const auto pair = WritableEvent::CreateEventPair(kernel, "HLE Pause Event: " + reason);
|
||||
writable_event = pair.writable;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_cpu.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
@@ -78,7 +79,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
// thread.
|
||||
ASSERT(requesting_thread == current_thread);
|
||||
|
||||
const u32 addr_value = Memory::Read32(address);
|
||||
u32 addr_value = Memory::Read32(address);
|
||||
|
||||
// If the mutex isn't being held, just return success.
|
||||
if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) {
|
||||
@@ -89,6 +90,20 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
// This a workaround where an unknown bug writes the mutex value to give ownership to a cond var
|
||||
// waiting thread.
|
||||
if (holding_thread->GetStatus() == ThreadStatus::WaitCondVar) {
|
||||
if (holding_thread->GetMutexWaitAddress() == address) {
|
||||
Release(address, holding_thread.get());
|
||||
addr_value = Memory::Read32(address);
|
||||
if (addr_value == 0)
|
||||
return RESULT_SUCCESS;
|
||||
else {
|
||||
holding_thread = handle_table.Get<Thread>(addr_value & Mutex::MutexOwnerMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait until the mutex is released
|
||||
current_thread->SetMutexWaitAddress(address);
|
||||
current_thread->SetWaitHandle(requesting_thread_handle);
|
||||
@@ -104,14 +119,13 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultCode Mutex::Release(VAddr address) {
|
||||
ResultCode Mutex::Release(VAddr address, Thread* holding_thread) {
|
||||
// The mutex address must be 4-byte aligned
|
||||
if ((address % sizeof(u32)) != 0) {
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(current_thread, address);
|
||||
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(holding_thread, address);
|
||||
|
||||
// There are no more threads waiting for the mutex, release it completely.
|
||||
if (thread == nullptr) {
|
||||
@@ -120,7 +134,7 @@ ResultCode Mutex::Release(VAddr address) {
|
||||
}
|
||||
|
||||
// Transfer the ownership of the mutex from the previous owner to the new one.
|
||||
TransferMutexOwnership(address, current_thread, thread);
|
||||
TransferMutexOwnership(address, holding_thread, thread);
|
||||
|
||||
u32 mutex_value = thread->GetWaitHandle();
|
||||
|
||||
@@ -141,7 +155,10 @@ ResultCode Mutex::Release(VAddr address) {
|
||||
thread->SetWaitHandle(0);
|
||||
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
|
||||
|
||||
system.PrepareReschedule();
|
||||
if (thread->GetProcessorID() >= 0)
|
||||
system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
|
||||
if (holding_thread->GetProcessorID() >= 0)
|
||||
system.CpuCore(holding_thread->GetProcessorID()).PrepareReschedule();
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
Handle requesting_thread_handle);
|
||||
|
||||
/// Releases the mutex at the specified address.
|
||||
ResultCode Release(VAddr address);
|
||||
ResultCode Release(VAddr address, Thread* holding_thread);
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
|
||||
@@ -32,11 +32,6 @@ enum class HandleType : u32 {
|
||||
ServerSession,
|
||||
};
|
||||
|
||||
enum class ResetType {
|
||||
Automatic, ///< Reset automatically on object acquisition
|
||||
Manual, ///< Never reset automatically
|
||||
};
|
||||
|
||||
class Object : NonCopyable {
|
||||
public:
|
||||
explicit Object(KernelCore& kernel);
|
||||
|
||||
@@ -20,15 +20,13 @@ bool ReadableEvent::ShouldWait(const Thread* thread) const {
|
||||
|
||||
void ReadableEvent::Acquire(Thread* thread) {
|
||||
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
|
||||
|
||||
if (reset_type == ResetType::Automatic) {
|
||||
signaled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadableEvent::Signal() {
|
||||
signaled = true;
|
||||
WakeupAllWaitingThreads();
|
||||
if (!signaled) {
|
||||
signaled = true;
|
||||
WakeupAllWaitingThreads();
|
||||
};
|
||||
}
|
||||
|
||||
void ReadableEvent::Clear() {
|
||||
|
||||
@@ -27,10 +27,6 @@ public:
|
||||
return name;
|
||||
}
|
||||
|
||||
ResetType GetResetType() const {
|
||||
return reset_type;
|
||||
}
|
||||
|
||||
static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent;
|
||||
HandleType GetHandleType() const override {
|
||||
return HANDLE_TYPE;
|
||||
@@ -55,8 +51,7 @@ private:
|
||||
|
||||
void Signal();
|
||||
|
||||
ResetType reset_type;
|
||||
bool signaled;
|
||||
bool signaled{};
|
||||
|
||||
std::string name; ///< Name of event (optional)
|
||||
};
|
||||
|
||||
@@ -35,12 +35,12 @@ void GlobalScheduler::RemoveThread(const Thread* thread) {
|
||||
thread_list.end());
|
||||
}
|
||||
|
||||
void GlobalScheduler::UnloadThread(s32 core) {
|
||||
void GlobalScheduler::UnloadThread(std::size_t core) {
|
||||
Scheduler& sched = system.Scheduler(core);
|
||||
sched.UnloadThread();
|
||||
}
|
||||
|
||||
void GlobalScheduler::SelectThread(u32 core) {
|
||||
void GlobalScheduler::SelectThread(std::size_t core) {
|
||||
const auto update_thread = [](Thread* thread, Scheduler& sched) {
|
||||
if (thread != sched.selected_thread) {
|
||||
if (thread == nullptr) {
|
||||
@@ -77,9 +77,9 @@ void GlobalScheduler::SelectThread(u32 core) {
|
||||
// if we got a suggested thread, select it, else do a second pass.
|
||||
if (winner && winner->GetPriority() > 2) {
|
||||
if (winner->IsRunning()) {
|
||||
UnloadThread(winner->GetProcessorID());
|
||||
UnloadThread(static_cast<u32>(winner->GetProcessorID()));
|
||||
}
|
||||
TransferToCore(winner->GetPriority(), core, winner);
|
||||
TransferToCore(winner->GetPriority(), static_cast<s32>(core), winner);
|
||||
update_thread(winner, sched);
|
||||
return;
|
||||
}
|
||||
@@ -91,9 +91,9 @@ void GlobalScheduler::SelectThread(u32 core) {
|
||||
Thread* thread_on_core = scheduled_queue[src_core].front();
|
||||
Thread* to_change = *it;
|
||||
if (thread_on_core->IsRunning() || to_change->IsRunning()) {
|
||||
UnloadThread(src_core);
|
||||
UnloadThread(static_cast<u32>(src_core));
|
||||
}
|
||||
TransferToCore(thread_on_core->GetPriority(), core, thread_on_core);
|
||||
TransferToCore(thread_on_core->GetPriority(), static_cast<s32>(core), thread_on_core);
|
||||
current_thread = thread_on_core;
|
||||
break;
|
||||
}
|
||||
@@ -154,9 +154,9 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) {
|
||||
if (winner != nullptr) {
|
||||
if (winner != yielding_thread) {
|
||||
if (winner->IsRunning()) {
|
||||
UnloadThread(winner->GetProcessorID());
|
||||
UnloadThread(static_cast<u32>(winner->GetProcessorID()));
|
||||
}
|
||||
TransferToCore(winner->GetPriority(), core_id, winner);
|
||||
TransferToCore(winner->GetPriority(), s32(core_id), winner);
|
||||
}
|
||||
} else {
|
||||
winner = next_thread;
|
||||
@@ -196,9 +196,9 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread
|
||||
if (winner != nullptr) {
|
||||
if (winner != yielding_thread) {
|
||||
if (winner->IsRunning()) {
|
||||
UnloadThread(winner->GetProcessorID());
|
||||
UnloadThread(static_cast<u32>(winner->GetProcessorID()));
|
||||
}
|
||||
TransferToCore(winner->GetPriority(), core_id, winner);
|
||||
TransferToCore(winner->GetPriority(), static_cast<s32>(core_id), winner);
|
||||
}
|
||||
} else {
|
||||
winner = yielding_thread;
|
||||
@@ -248,7 +248,7 @@ void GlobalScheduler::PreemptThreads() {
|
||||
|
||||
if (winner != nullptr) {
|
||||
if (winner->IsRunning()) {
|
||||
UnloadThread(winner->GetProcessorID());
|
||||
UnloadThread(static_cast<u32>(winner->GetProcessorID()));
|
||||
}
|
||||
TransferToCore(winner->GetPriority(), s32(core_id), winner);
|
||||
current_thread =
|
||||
@@ -281,7 +281,7 @@ void GlobalScheduler::PreemptThreads() {
|
||||
|
||||
if (winner != nullptr) {
|
||||
if (winner->IsRunning()) {
|
||||
UnloadThread(winner->GetProcessorID());
|
||||
UnloadThread(static_cast<u32>(winner->GetProcessorID()));
|
||||
}
|
||||
TransferToCore(winner->GetPriority(), s32(core_id), winner);
|
||||
current_thread = winner;
|
||||
@@ -292,30 +292,30 @@ void GlobalScheduler::PreemptThreads() {
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalScheduler::Suggest(u32 priority, u32 core, Thread* thread) {
|
||||
void GlobalScheduler::Suggest(u32 priority, std::size_t core, Thread* thread) {
|
||||
suggested_queue[core].add(thread, priority);
|
||||
}
|
||||
|
||||
void GlobalScheduler::Unsuggest(u32 priority, u32 core, Thread* thread) {
|
||||
void GlobalScheduler::Unsuggest(u32 priority, std::size_t core, Thread* thread) {
|
||||
suggested_queue[core].remove(thread, priority);
|
||||
}
|
||||
|
||||
void GlobalScheduler::Schedule(u32 priority, u32 core, Thread* thread) {
|
||||
void GlobalScheduler::Schedule(u32 priority, std::size_t core, Thread* thread) {
|
||||
ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core.");
|
||||
scheduled_queue[core].add(thread, priority);
|
||||
}
|
||||
|
||||
void GlobalScheduler::SchedulePrepend(u32 priority, u32 core, Thread* thread) {
|
||||
void GlobalScheduler::SchedulePrepend(u32 priority, std::size_t core, Thread* thread) {
|
||||
ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core.");
|
||||
scheduled_queue[core].add(thread, priority, false);
|
||||
}
|
||||
|
||||
void GlobalScheduler::Reschedule(u32 priority, u32 core, Thread* thread) {
|
||||
void GlobalScheduler::Reschedule(u32 priority, std::size_t core, Thread* thread) {
|
||||
scheduled_queue[core].remove(thread, priority);
|
||||
scheduled_queue[core].add(thread, priority);
|
||||
}
|
||||
|
||||
void GlobalScheduler::Unschedule(u32 priority, u32 core, Thread* thread) {
|
||||
void GlobalScheduler::Unschedule(u32 priority, std::size_t core, Thread* thread) {
|
||||
scheduled_queue[core].remove(thread, priority);
|
||||
}
|
||||
|
||||
@@ -327,14 +327,14 @@ void GlobalScheduler::TransferToCore(u32 priority, s32 destination_core, Thread*
|
||||
}
|
||||
thread->SetProcessorID(destination_core);
|
||||
if (source_core >= 0) {
|
||||
Unschedule(priority, source_core, thread);
|
||||
Unschedule(priority, static_cast<u32>(source_core), thread);
|
||||
}
|
||||
if (destination_core >= 0) {
|
||||
Unsuggest(priority, destination_core, thread);
|
||||
Schedule(priority, destination_core, thread);
|
||||
Unsuggest(priority, static_cast<u32>(destination_core), thread);
|
||||
Schedule(priority, static_cast<u32>(destination_core), thread);
|
||||
}
|
||||
if (source_core >= 0) {
|
||||
Suggest(priority, source_core, thread);
|
||||
Suggest(priority, static_cast<u32>(source_core), thread);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ void GlobalScheduler::Shutdown() {
|
||||
thread_list.clear();
|
||||
}
|
||||
|
||||
Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id)
|
||||
Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id)
|
||||
: system(system), cpu_core(cpu_core), core_id(core_id) {}
|
||||
|
||||
Scheduler::~Scheduler() = default;
|
||||
|
||||
@@ -42,41 +42,34 @@ public:
|
||||
* Add a thread to the suggested queue of a cpu core. Suggested threads may be
|
||||
* picked if no thread is scheduled to run on the core.
|
||||
*/
|
||||
void Suggest(u32 priority, u32 core, Thread* thread);
|
||||
void Suggest(u32 priority, std::size_t core, Thread* thread);
|
||||
|
||||
/**
|
||||
* Remove a thread to the suggested queue of a cpu core. Suggested threads may be
|
||||
* picked if no thread is scheduled to run on the core.
|
||||
*/
|
||||
void Unsuggest(u32 priority, u32 core, Thread* thread);
|
||||
void Unsuggest(u32 priority, std::size_t core, Thread* thread);
|
||||
|
||||
/**
|
||||
* Add a thread to the scheduling queue of a cpu core. The thread is added at the
|
||||
* back the queue in its priority level.
|
||||
*/
|
||||
void Schedule(u32 priority, u32 core, Thread* thread);
|
||||
void Schedule(u32 priority, std::size_t core, Thread* thread);
|
||||
|
||||
/**
|
||||
* Add a thread to the scheduling queue of a cpu core. The thread is added at the
|
||||
* front the queue in its priority level.
|
||||
*/
|
||||
void SchedulePrepend(u32 priority, u32 core, Thread* thread);
|
||||
void SchedulePrepend(u32 priority, std::size_t core, Thread* thread);
|
||||
|
||||
/// Reschedule an already scheduled thread based on a new priority
|
||||
void Reschedule(u32 priority, u32 core, Thread* thread);
|
||||
void Reschedule(u32 priority, std::size_t core, Thread* thread);
|
||||
|
||||
/// Unschedules a thread.
|
||||
void Unschedule(u32 priority, u32 core, Thread* thread);
|
||||
|
||||
/**
|
||||
* Transfers a thread into an specific core. If the destination_core is -1
|
||||
* it will be unscheduled from its source code and added into its suggested
|
||||
* queue.
|
||||
*/
|
||||
void TransferToCore(u32 priority, s32 destination_core, Thread* thread);
|
||||
void Unschedule(u32 priority, std::size_t core, Thread* thread);
|
||||
|
||||
/// Selects a core and forces it to unload its current thread's context
|
||||
void UnloadThread(s32 core);
|
||||
void UnloadThread(std::size_t core);
|
||||
|
||||
/**
|
||||
* Takes care of selecting the new scheduled thread in three steps:
|
||||
@@ -90,9 +83,9 @@ public:
|
||||
* 3. Third is no suggested thread is found, we do a second pass and pick a running
|
||||
* thread in another core and swap it with its current thread.
|
||||
*/
|
||||
void SelectThread(u32 core);
|
||||
void SelectThread(std::size_t core);
|
||||
|
||||
bool HaveReadyThreads(u32 core_id) const {
|
||||
bool HaveReadyThreads(std::size_t core_id) const {
|
||||
return !scheduled_queue[core_id].empty();
|
||||
}
|
||||
|
||||
@@ -145,6 +138,13 @@ public:
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Transfers a thread into an specific core. If the destination_core is -1
|
||||
* it will be unscheduled from its source code and added into its suggested
|
||||
* queue.
|
||||
*/
|
||||
void TransferToCore(u32 priority, s32 destination_core, Thread* thread);
|
||||
|
||||
bool AskForReselectionOrMarkRedundant(Thread* current_thread, const Thread* winner);
|
||||
|
||||
static constexpr u32 min_regular_priority = 2;
|
||||
@@ -163,7 +163,7 @@ private:
|
||||
|
||||
class Scheduler final {
|
||||
public:
|
||||
explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id);
|
||||
explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id);
|
||||
~Scheduler();
|
||||
|
||||
/// Returns whether there are any threads that are ready to run.
|
||||
@@ -220,7 +220,7 @@ private:
|
||||
Core::ARM_Interface& cpu_core;
|
||||
u64 last_context_switch_time = 0;
|
||||
u64 idle_selection_count = 0;
|
||||
const u32 core_id;
|
||||
const std::size_t core_id;
|
||||
|
||||
bool is_context_switch_pending = false;
|
||||
};
|
||||
|
||||
@@ -578,7 +578,8 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) {
|
||||
}
|
||||
|
||||
auto* const current_process = system.Kernel().CurrentProcess();
|
||||
return current_process->GetMutex().Release(mutex_addr);
|
||||
return current_process->GetMutex().Release(mutex_addr,
|
||||
system.CurrentScheduler().GetCurrentThread());
|
||||
}
|
||||
|
||||
enum class BreakType : u32 {
|
||||
@@ -1615,12 +1616,14 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
|
||||
SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
||||
ASSERT(thread);
|
||||
|
||||
const auto release_result = current_process->GetMutex().Release(mutex_addr);
|
||||
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||
|
||||
const auto release_result =
|
||||
current_process->GetMutex().Release(mutex_addr, current_thread.get());
|
||||
if (release_result.IsError()) {
|
||||
return release_result;
|
||||
}
|
||||
|
||||
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||
current_thread->SetCondVarWaitAddress(condition_variable_addr);
|
||||
current_thread->SetMutexWaitAddress(mutex_addr);
|
||||
current_thread->SetWaitHandle(thread_handle);
|
||||
@@ -2099,7 +2102,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
const auto [readable_event, writable_event] =
|
||||
WritableEvent::CreateEventPair(kernel, ResetType::Manual, "CreateEvent");
|
||||
WritableEvent::CreateEventPair(kernel, "CreateEvent");
|
||||
|
||||
HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
||||
|
||||
|
||||
@@ -77,18 +77,6 @@ void Thread::CancelWakeupTimer() {
|
||||
callback_handle);
|
||||
}
|
||||
|
||||
static std::optional<s32> GetNextProcessorId(u64 mask) {
|
||||
for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) {
|
||||
if (mask & (1ULL << index)) {
|
||||
if (!Core::System::GetInstance().Scheduler(index).GetCurrentThread()) {
|
||||
// Core is enabled and not running any threads, use this one
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void Thread::ResumeFromWait() {
|
||||
ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
|
||||
|
||||
@@ -173,7 +161,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
|
||||
if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) {
|
||||
LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
|
||||
// TODO (bunnei): Find the correct error code to use here
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
@@ -401,7 +389,7 @@ void Thread::SetCurrentPriority(u32 new_priority) {
|
||||
|
||||
ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {
|
||||
const auto HighestSetCore = [](u64 mask, u32 max_cores) {
|
||||
for (s32 core = max_cores - 1; core >= 0; core--) {
|
||||
for (s32 core = static_cast<s32>(max_cores - 1); core >= 0; core--) {
|
||||
if (((mask >> core) & 1) != 0) {
|
||||
return core;
|
||||
}
|
||||
@@ -425,7 +413,7 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {
|
||||
if (old_affinity_mask != new_affinity_mask) {
|
||||
const s32 old_core = processor_id;
|
||||
if (processor_id >= 0 && ((affinity_mask >> processor_id) & 1) == 0) {
|
||||
if (ideal_core < 0) {
|
||||
if (static_cast<s32>(ideal_core) < 0) {
|
||||
processor_id = HighestSetCore(affinity_mask, GlobalScheduler::NUM_CPU_CORES);
|
||||
} else {
|
||||
processor_id = ideal_core;
|
||||
@@ -447,23 +435,23 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) {
|
||||
ThreadSchedStatus::Runnable) {
|
||||
// In this case the thread was running, now it's pausing/exitting
|
||||
if (processor_id >= 0) {
|
||||
scheduler.Unschedule(current_priority, processor_id, this);
|
||||
scheduler.Unschedule(current_priority, static_cast<u32>(processor_id), this);
|
||||
}
|
||||
|
||||
for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (core != processor_id && ((affinity_mask >> core) & 1) != 0) {
|
||||
scheduler.Unsuggest(current_priority, static_cast<u32>(core), this);
|
||||
for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {
|
||||
scheduler.Unsuggest(current_priority, core, this);
|
||||
}
|
||||
}
|
||||
} else if (GetSchedulingStatus() == ThreadSchedStatus::Runnable) {
|
||||
// The thread is now set to running from being stopped
|
||||
if (processor_id >= 0) {
|
||||
scheduler.Schedule(current_priority, processor_id, this);
|
||||
scheduler.Schedule(current_priority, static_cast<u32>(processor_id), this);
|
||||
}
|
||||
|
||||
for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (core != processor_id && ((affinity_mask >> core) & 1) != 0) {
|
||||
scheduler.Suggest(current_priority, static_cast<u32>(core), this);
|
||||
for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {
|
||||
scheduler.Suggest(current_priority, core, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,11 +465,11 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) {
|
||||
}
|
||||
auto& scheduler = Core::System::GetInstance().GlobalScheduler();
|
||||
if (processor_id >= 0) {
|
||||
scheduler.Unschedule(old_priority, processor_id, this);
|
||||
scheduler.Unschedule(old_priority, static_cast<u32>(processor_id), this);
|
||||
}
|
||||
|
||||
for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (core != processor_id && ((affinity_mask >> core) & 1) != 0) {
|
||||
if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {
|
||||
scheduler.Unsuggest(old_priority, core, this);
|
||||
}
|
||||
}
|
||||
@@ -491,14 +479,14 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) {
|
||||
|
||||
if (processor_id >= 0) {
|
||||
if (current_thread == this) {
|
||||
scheduler.SchedulePrepend(current_priority, processor_id, this);
|
||||
scheduler.SchedulePrepend(current_priority, static_cast<u32>(processor_id), this);
|
||||
} else {
|
||||
scheduler.Schedule(current_priority, processor_id, this);
|
||||
scheduler.Schedule(current_priority, static_cast<u32>(processor_id), this);
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (core != processor_id && ((affinity_mask >> core) & 1) != 0) {
|
||||
if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {
|
||||
scheduler.Suggest(current_priority, core, this);
|
||||
}
|
||||
}
|
||||
@@ -515,7 +503,7 @@ void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) {
|
||||
|
||||
for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (((old_affinity_mask >> core) & 1) != 0) {
|
||||
if (core == old_core) {
|
||||
if (core == static_cast<u32>(old_core)) {
|
||||
scheduler.Unschedule(current_priority, core, this);
|
||||
} else {
|
||||
scheduler.Unsuggest(current_priority, core, this);
|
||||
@@ -525,7 +513,7 @@ void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) {
|
||||
|
||||
for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) {
|
||||
if (((affinity_mask >> core) & 1) != 0) {
|
||||
if (core == processor_id) {
|
||||
if (core == static_cast<u32>(processor_id)) {
|
||||
scheduler.Schedule(current_priority, core, this);
|
||||
} else {
|
||||
scheduler.Suggest(current_priority, core, this);
|
||||
|
||||
@@ -23,6 +23,8 @@ SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_
|
||||
transfer_memory->owner_permissions = permissions;
|
||||
transfer_memory->owner_process = kernel.CurrentProcess();
|
||||
|
||||
transfer_memory->MapMemory(base_address, size, permissions);
|
||||
|
||||
return transfer_memory;
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ ResultVal<VAddr> VMManager::FindFreeRegion(VAddr begin, VAddr end, u64 size) con
|
||||
|
||||
if (vma_handle == vma_map.cend()) {
|
||||
// TODO(Subv): Find the correct error code here.
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
const VAddr target = std::max(begin, vma_handle->second.base);
|
||||
|
||||
@@ -51,17 +51,8 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
|
||||
if (ShouldWait(thread.get()))
|
||||
continue;
|
||||
|
||||
// A thread is ready to run if it's either in ThreadStatus::WaitSynch
|
||||
// and the rest of the objects it is waiting on are ready.
|
||||
bool ready_to_run = true;
|
||||
if (thread_status == ThreadStatus::WaitSynch) {
|
||||
ready_to_run = thread->AllWaitObjectsReady();
|
||||
}
|
||||
|
||||
if (ready_to_run) {
|
||||
candidate = thread.get();
|
||||
candidate_priority = thread->GetPriority();
|
||||
}
|
||||
candidate = thread.get();
|
||||
candidate_priority = thread->GetPriority();
|
||||
}
|
||||
|
||||
return candidate;
|
||||
|
||||
@@ -15,8 +15,7 @@ namespace Kernel {
|
||||
WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {}
|
||||
WritableEvent::~WritableEvent() = default;
|
||||
|
||||
EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_type,
|
||||
std::string name) {
|
||||
EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
|
||||
SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel));
|
||||
SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel));
|
||||
|
||||
@@ -24,7 +23,6 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_typ
|
||||
writable_event->readable = readable_event;
|
||||
readable_event->name = name + ":Readable";
|
||||
readable_event->signaled = false;
|
||||
readable_event->reset_type = reset_type;
|
||||
|
||||
return {std::move(readable_event), std::move(writable_event)};
|
||||
}
|
||||
@@ -33,10 +31,6 @@ SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const {
|
||||
return readable;
|
||||
}
|
||||
|
||||
ResetType WritableEvent::GetResetType() const {
|
||||
return readable->reset_type;
|
||||
}
|
||||
|
||||
void WritableEvent::Signal() {
|
||||
readable->Signal();
|
||||
}
|
||||
|
||||
@@ -24,11 +24,9 @@ public:
|
||||
/**
|
||||
* Creates an event
|
||||
* @param kernel The kernel instance to create this event under.
|
||||
* @param reset_type ResetType describing how to create event
|
||||
* @param name Optional name of event
|
||||
*/
|
||||
static EventPair CreateEventPair(KernelCore& kernel, ResetType reset_type,
|
||||
std::string name = "Unknown");
|
||||
static EventPair CreateEventPair(KernelCore& kernel, std::string name = "Unknown");
|
||||
|
||||
std::string GetTypeName() const override {
|
||||
return "WritableEvent";
|
||||
@@ -44,8 +42,6 @@ public:
|
||||
|
||||
SharedPtr<ReadableEvent> GetReadableEvent() const;
|
||||
|
||||
ResetType GetResetType() const;
|
||||
|
||||
void Signal();
|
||||
void Clear();
|
||||
bool IsSignaled() const;
|
||||
|
||||
@@ -146,6 +146,14 @@ constexpr bool operator!=(const ResultCode& a, const ResultCode& b) {
|
||||
/// The default success `ResultCode`.
|
||||
constexpr ResultCode RESULT_SUCCESS(0);
|
||||
|
||||
/**
|
||||
* Placeholder result code used for unknown error codes.
|
||||
*
|
||||
* @note This should only be used when a particular error code
|
||||
* is not known yet.
|
||||
*/
|
||||
constexpr ResultCode RESULT_UNKNOWN(UINT32_MAX);
|
||||
|
||||
/**
|
||||
* This is an optional value type. It holds a `ResultCode` and, if that code is a success code,
|
||||
* also holds a result of type `T`. If the code is an error code then trying to access the inner
|
||||
@@ -183,7 +191,7 @@ class ResultVal {
|
||||
public:
|
||||
/// Constructs an empty `ResultVal` with the given error code. The code must not be a success
|
||||
/// code.
|
||||
ResultVal(ResultCode error_code = ResultCode(-1)) : result_code(error_code) {
|
||||
ResultVal(ResultCode error_code = RESULT_UNKNOWN) : result_code(error_code) {
|
||||
ASSERT(error_code.IsError());
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ protected:
|
||||
LOG_ERROR(Service_ACC, "Failed to get profile base and data for user={}",
|
||||
user_id.Format());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code
|
||||
rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Get actual error code
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ protected:
|
||||
} else {
|
||||
LOG_ERROR(Service_ACC, "Failed to get profile base for user={}", user_id.Format());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code
|
||||
rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Get actual error code
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
|
||||
const auto user_list = profile_manager->GetAllUsers();
|
||||
if (std::all_of(user_list.begin(), user_list.end(),
|
||||
[](const auto& user) { return user.uuid == Common::INVALID_UUID; })) {
|
||||
rb.Push(ResultCode(-1)); // TODO(ogniK): Find the correct error code
|
||||
rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Find the correct error code
|
||||
rb.PushRaw<u128>(Common::INVALID_UUID);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ struct ProfileDataRaw {
|
||||
static_assert(sizeof(ProfileDataRaw) == 0x650, "ProfileDataRaw has incorrect size.");
|
||||
|
||||
// TODO(ogniK): Get actual error codes
|
||||
constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, -1);
|
||||
constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, -2);
|
||||
constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, u32(-1));
|
||||
constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, u32(-2));
|
||||
constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20);
|
||||
|
||||
constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/avators/";
|
||||
|
||||
@@ -289,8 +289,8 @@ ISelfController::ISelfController(Core::System& system,
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
|
||||
"ISelfController:LaunchableEvent");
|
||||
launchable_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "ISelfController:LaunchableEvent");
|
||||
|
||||
// This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is
|
||||
// called. Yuzu can just create it unconditionally, since it doesn't need to support multiple
|
||||
@@ -298,7 +298,7 @@ ISelfController::ISelfController(Core::System& system,
|
||||
// suspended if the event has previously been created by a call to
|
||||
// GetAccumulatedSuspendedTickChangedEvent.
|
||||
accumulated_suspended_tick_changed_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Manual, "ISelfController:AccumulatedSuspendedTickChangedEvent");
|
||||
kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent");
|
||||
accumulated_suspended_tick_changed_event.writable->Signal();
|
||||
}
|
||||
|
||||
@@ -523,10 +523,10 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
|
||||
}
|
||||
|
||||
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
|
||||
on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
|
||||
"AMMessageQueue:OnMessageRecieved");
|
||||
on_operation_mode_changed = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "AMMessageQueue:OperationModeChanged");
|
||||
on_new_message =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OnMessageRecieved");
|
||||
on_operation_mode_changed =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OperationModeChanged");
|
||||
}
|
||||
|
||||
AppletMessageQueue::~AppletMessageQueue() = default;
|
||||
@@ -847,17 +847,16 @@ private:
|
||||
void PopInteractiveOutData(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
|
||||
const auto storage = applet->GetBroker().PopInteractiveDataToGame();
|
||||
if (storage == nullptr) {
|
||||
LOG_ERROR(Service_AM,
|
||||
"storage is a nullptr. There is no data in the current interactive channel");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NO_DATA_IN_CHANNEL);
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IStorage>(std::move(*storage));
|
||||
}
|
||||
@@ -991,7 +990,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
|
||||
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast<u32>(applet_id));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1027,7 +1026,7 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
|
||||
if (transfer_mem == nullptr) {
|
||||
LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1077,6 +1076,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
{101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"},
|
||||
{102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"},
|
||||
{110, nullptr, "QueryApplicationPlayStatistics"},
|
||||
{111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"},
|
||||
{120, nullptr, "ExecuteProgram"},
|
||||
{121, nullptr, "ClearUserChannel"},
|
||||
{122, nullptr, "UnpopToUserChannel"},
|
||||
@@ -1091,7 +1091,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Manual, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
|
||||
kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
|
||||
}
|
||||
|
||||
IApplicationFunctions::~IApplicationFunctions() = default;
|
||||
@@ -1384,6 +1384,14 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
|
||||
rb.PushCopyObjects(gpu_error_detected_event.readable);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager,
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system) {
|
||||
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
|
||||
|
||||
@@ -256,6 +256,7 @@ private:
|
||||
void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx);
|
||||
void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx);
|
||||
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
|
||||
void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx);
|
||||
|
||||
bool launch_popped_application_specific = false;
|
||||
bool launch_popped_account_preselect = false;
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
namespace Service::AM::Applets {
|
||||
|
||||
AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) {
|
||||
state_changed_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:StateChangedEvent");
|
||||
pop_out_data_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopDataOutEvent");
|
||||
state_changed_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:StateChangedEvent");
|
||||
pop_out_data_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:PopDataOutEvent");
|
||||
pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
|
||||
kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
|
||||
}
|
||||
|
||||
AppletDataBroker::~AppletDataBroker() = default;
|
||||
@@ -88,6 +88,7 @@ std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() {
|
||||
|
||||
void AppletDataBroker::PushNormalDataFromGame(IStorage storage) {
|
||||
in_channel.push_back(std::make_unique<IStorage>(storage));
|
||||
pop_out_data_event.writable->Clear();
|
||||
}
|
||||
|
||||
void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) {
|
||||
@@ -97,6 +98,7 @@ void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) {
|
||||
|
||||
void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) {
|
||||
in_interactive_channel.push_back(std::make_unique<IStorage>(storage));
|
||||
pop_interactive_out_data_event.writable->Clear();
|
||||
}
|
||||
|
||||
void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) {
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace Service::AM::Applets {
|
||||
struct ShowError {
|
||||
u8 mode;
|
||||
bool jump;
|
||||
INSERT_PADDING_BYTES(4);
|
||||
INSERT_UNION_PADDING_BYTES(4);
|
||||
bool use_64bit_error_code;
|
||||
INSERT_PADDING_BYTES(1);
|
||||
INSERT_UNION_PADDING_BYTES(1);
|
||||
u64 error_code_64;
|
||||
u32 error_code_32;
|
||||
};
|
||||
@@ -32,7 +32,7 @@ static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size.");
|
||||
struct ShowErrorRecord {
|
||||
u8 mode;
|
||||
bool jump;
|
||||
INSERT_PADDING_BYTES(6);
|
||||
INSERT_UNION_PADDING_BYTES(6);
|
||||
u64 error_code_64;
|
||||
u64 posix_time;
|
||||
};
|
||||
@@ -41,7 +41,7 @@ static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect si
|
||||
struct SystemErrorArg {
|
||||
u8 mode;
|
||||
bool jump;
|
||||
INSERT_PADDING_BYTES(6);
|
||||
INSERT_UNION_PADDING_BYTES(6);
|
||||
u64 error_code_64;
|
||||
std::array<char, 8> language_code;
|
||||
std::array<char, 0x800> main_text;
|
||||
@@ -52,7 +52,7 @@ static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect si
|
||||
struct ApplicationErrorArg {
|
||||
u8 mode;
|
||||
bool jump;
|
||||
INSERT_PADDING_BYTES(6);
|
||||
INSERT_UNION_PADDING_BYTES(6);
|
||||
u32 error_code;
|
||||
std::array<char, 8> language_code;
|
||||
std::array<char, 0x800> main_text;
|
||||
@@ -65,6 +65,7 @@ union Error::ErrorArguments {
|
||||
ShowErrorRecord error_record;
|
||||
SystemErrorArg system_error;
|
||||
ApplicationErrorArg application_error;
|
||||
std::array<u8, 0x1018> raw{};
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -91,6 +91,7 @@ void SoftwareKeyboard::ExecuteInteractive() {
|
||||
|
||||
if (status == INTERACTIVE_STATUS_OK) {
|
||||
complete = true;
|
||||
broker.SignalStateChanged();
|
||||
} else {
|
||||
std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
|
||||
std::memcpy(string.data(), data.data() + 4, string.size() * 2);
|
||||
|
||||
@@ -337,7 +337,7 @@ void WebBrowser::ExecuteInternal() {
|
||||
void WebBrowser::InitializeShop() {
|
||||
if (frontend_e_commerce == nullptr) {
|
||||
LOG_ERROR(Service_AM, "Missing ECommerce Applet frontend!");
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ void WebBrowser::InitializeShop() {
|
||||
|
||||
if (url == args.end()) {
|
||||
LOG_ERROR(Service_AM, "Missing EShop Arguments URL for initialization!");
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ void WebBrowser::InitializeShop() {
|
||||
// Less is missing info, More is malformed
|
||||
if (split_query.size() != 2) {
|
||||
LOG_ERROR(Service_AM, "EShop Arguments has more than one question mark, malformed");
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ void WebBrowser::InitializeShop() {
|
||||
|
||||
if (scene == shop_query.end()) {
|
||||
LOG_ERROR(Service_AM, "No scene parameter was passed via shop query!");
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ void WebBrowser::InitializeShop() {
|
||||
const auto target = target_map.find(scene->second);
|
||||
if (target == target_map.end()) {
|
||||
LOG_ERROR(Service_AM, "Scene for shop query is invalid! (scene={})", scene->second);
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ void WebBrowser::InitializeOffline() {
|
||||
if (args.find(WebArgTLVType::DocumentPath) == args.end() ||
|
||||
args.find(WebArgTLVType::DocumentKind) == args.end() ||
|
||||
args.find(WebArgTLVType::ApplicationID) == args.end()) {
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
LOG_ERROR(Service_AM, "Missing necessary parameters for initialization!");
|
||||
}
|
||||
|
||||
@@ -476,7 +476,7 @@ void WebBrowser::InitializeOffline() {
|
||||
|
||||
offline_romfs = GetApplicationRomFS(system, title_id, type);
|
||||
if (offline_romfs == nullptr) {
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
LOG_ERROR(Service_AM, "Failed to find offline data for request!");
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ void WebBrowser::ExecuteShop() {
|
||||
const auto check_optional_parameter = [this](const auto& p) {
|
||||
if (!p.has_value()) {
|
||||
LOG_ERROR(Service_AM, "Missing one or more necessary parameters for execution!");
|
||||
status = ResultCode(-1);
|
||||
status = RESULT_UNKNOWN;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,8 @@ AOC_U::AOC_U(Core::System& system)
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
|
||||
"GetAddOnContentListChanged:Event");
|
||||
aoc_change_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "GetAddOnContentListChanged:Event");
|
||||
}
|
||||
|
||||
AOC_U::~AOC_U() = default;
|
||||
@@ -131,7 +131,7 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
|
||||
if (out.size() < offset) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
// TODO(DarkLordZach): Find the correct error code.
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
// This is the event handle used to check if the audio buffer was released
|
||||
buffer_event = Kernel::WritableEvent::CreateEventPair(
|
||||
system.Kernel(), Kernel::ResetType::Manual, "IAudioOutBufferReleased");
|
||||
buffer_event =
|
||||
Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioOutBufferReleased");
|
||||
|
||||
stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
|
||||
audio_params.channel_count, std::move(unique_name),
|
||||
|
||||
@@ -47,8 +47,8 @@ public:
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
system_event = Kernel::WritableEvent::CreateEventPair(
|
||||
system.Kernel(), Kernel::ResetType::Manual, "IAudioRenderer:SystemEvent");
|
||||
system_event =
|
||||
Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent");
|
||||
renderer = std::make_unique<AudioCore::AudioRenderer>(
|
||||
system.CoreTiming(), audren_params, system_event.writable, instance_number);
|
||||
}
|
||||
@@ -180,17 +180,17 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
|
||||
"IAudioOutBufferReleasedEvent");
|
||||
buffer_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "IAudioOutBufferReleasedEvent");
|
||||
|
||||
// Should be similar to audio_output_device_switch_event
|
||||
audio_input_device_switch_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "IAudioDevice:AudioInputDeviceSwitchedEvent");
|
||||
kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent");
|
||||
|
||||
// Should only be signalled when an audio output device has been changed, example: speaker
|
||||
// to headset
|
||||
audio_output_device_switch_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
|
||||
kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
LOG_ERROR(Audio, "Failed to decode opus data");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
// TODO(ogniK): Use correct error code
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
|
||||
LOG_ERROR(Audio, "Failed to create Opus decoder (error={}).", error);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
// TODO(ogniK): Use correct error code
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ namespace Service::BCAT {
|
||||
ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
|
||||
std::string_view event_name) {
|
||||
event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic,
|
||||
std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
|
||||
kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
|
||||
}
|
||||
|
||||
Kernel::SharedPtr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const {
|
||||
|
||||
@@ -114,7 +114,7 @@ void HandleDownloadDisplayResult(const AM::Applets::AppletManager& applet_manage
|
||||
|
||||
const auto& frontend{applet_manager.GetAppletFrontendSet()};
|
||||
frontend.error->ShowCustomErrorText(
|
||||
ResultCode(-1), "There was an error while attempting to use Boxcat.",
|
||||
RESULT_UNKNOWN, "There was an error while attempting to use Boxcat.",
|
||||
DOWNLOAD_RESULT_LOG_MESSAGES[static_cast<std::size_t>(res)], [] {});
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ private:
|
||||
using Digest = std::array<u8, 0x20>;
|
||||
static Digest DigestFile(std::vector<u8> bytes) {
|
||||
Digest out{};
|
||||
mbedtls_sha256(bytes.data(), bytes.size(), out.data(), 0);
|
||||
mbedtls_sha256_ret(bytes.data(), bytes.size(), out.data(), 0);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ u64 GetCurrentBuildID(const Core::System::CurrentBuildProcessID& id) {
|
||||
BCATDigest DigestFile(const FileSys::VirtualFile& file) {
|
||||
BCATDigest out{};
|
||||
const auto bytes = file->ReadAllBytes();
|
||||
mbedtls_md5(bytes.data(), bytes.size(), out.data());
|
||||
mbedtls_md5_ret(bytes.data(), bytes.size(), out.data());
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,7 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
register_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "BT:RegisterEvent");
|
||||
register_event = Kernel::WritableEvent::CreateEventPair(kernel, "BT:RegisterEvent");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -57,14 +57,12 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
|
||||
"IBtmUserCore:ScanEvent");
|
||||
connection_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "IBtmUserCore:ConnectionEvent");
|
||||
service_discovery = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "IBtmUserCore:Discovery");
|
||||
config_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
|
||||
"IBtmUserCore:ConfigEvent");
|
||||
scan_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ScanEvent");
|
||||
connection_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConnectionEvent");
|
||||
service_discovery =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:Discovery");
|
||||
config_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConfigEvent");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -40,7 +40,10 @@ static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
|
||||
if (dir_name.empty() || dir_name == "." || dir_name == "/" || dir_name == "\\")
|
||||
return base;
|
||||
|
||||
return base->GetDirectoryRelative(dir_name);
|
||||
const auto res = base->GetDirectoryRelative(dir_name);
|
||||
if (res == nullptr)
|
||||
return base->CreateDirectoryRelative(dir_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_)
|
||||
@@ -58,11 +61,11 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64
|
||||
auto file = dir->CreateFile(FileUtil::GetFilename(path));
|
||||
if (file == nullptr) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
if (!file->Resize(size)) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
@@ -80,7 +83,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) cons
|
||||
}
|
||||
if (!dir->DeleteFile(FileUtil::GetFilename(path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
@@ -94,7 +97,7 @@ ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_)
|
||||
auto new_dir = dir->CreateSubdirectory(FileUtil::GetFilename(path));
|
||||
if (new_dir == nullptr) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
@@ -104,7 +107,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_)
|
||||
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
|
||||
if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
@@ -114,7 +117,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str
|
||||
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
|
||||
if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
@@ -125,7 +128,7 @@ ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::stri
|
||||
|
||||
if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
@@ -142,7 +145,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
|
||||
return FileSys::ERROR_PATH_NOT_FOUND;
|
||||
if (!src->Rename(FileUtil::GetFilename(dest_path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
@@ -160,7 +163,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
|
||||
|
||||
if (!src->GetContainingDirectory()->DeleteFile(FileUtil::GetFilename(src_path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
@@ -177,7 +180,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa
|
||||
return FileSys::ERROR_PATH_NOT_FOUND;
|
||||
if (!src->Rename(FileUtil::GetFilename(dest_path))) {
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
@@ -189,7 +192,7 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa
|
||||
src_path, dest_path);
|
||||
|
||||
// TODO(DarkLordZach): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path_,
|
||||
@@ -287,7 +290,7 @@ ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFSCurrentProcess()
|
||||
|
||||
if (romfs_factory == nullptr) {
|
||||
// TODO(bunnei): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
return romfs_factory->OpenCurrentProcess(system.CurrentProcess()->GetTitleID());
|
||||
@@ -300,7 +303,7 @@ ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFS(
|
||||
|
||||
if (romfs_factory == nullptr) {
|
||||
// TODO(bunnei): Find a better error code for this
|
||||
return ResultCode(-1);
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
return romfs_factory->Open(title_id, storage_id, type);
|
||||
|
||||
@@ -785,7 +785,7 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
|
||||
static_cast<u8>(type), title_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
}
|
||||
|
||||
void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
|
||||
@@ -891,7 +891,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||
// TODO (bunnei): Find the right error code to use here
|
||||
LOG_CRITICAL(Service_FS, "no file system interface available!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -928,7 +928,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
|
||||
"could not open data storage with title_id={:016X}, storage_id={:02X}", title_id,
|
||||
static_cast<u8>(storage_id));
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
notification_event = Kernel::WritableEvent::CreateEventPair(
|
||||
system.Kernel(), Kernel::ResetType::Manual, "INotificationService:NotifyEvent");
|
||||
system.Kernel(), "INotificationService:NotifyEvent");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -174,7 +174,7 @@ void Controller_NPad::OnInit() {
|
||||
auto& kernel = system.Kernel();
|
||||
for (std::size_t i = 0; i < styleset_changed_events.size(); i++) {
|
||||
styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Manual, fmt::format("npad:NpadStyleSetChanged_{}", i));
|
||||
kernel, fmt::format("npad:NpadStyleSetChanged_{}", i));
|
||||
}
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
|
||||
@@ -203,13 +203,13 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
|
||||
{120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
|
||||
{121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
|
||||
{122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
|
||||
{123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
|
||||
{123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"},
|
||||
{124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
|
||||
{125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
|
||||
{126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
|
||||
{127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
|
||||
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
|
||||
{129, nullptr, "GetNpadHandheldActivationMode"},
|
||||
{129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
|
||||
{130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
|
||||
{131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
|
||||
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
|
||||
@@ -557,10 +557,126 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
|
||||
applet_resource_user_id);
|
||||
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
|
||||
// TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_id{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
const auto npad_joy_device_type{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID,
|
||||
"(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
|
||||
npad_id, applet_resource_user_id, npad_joy_device_type);
|
||||
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_id{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
|
||||
applet_resource_user_id);
|
||||
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto unknown_1{rp.Pop<u32>()};
|
||||
const auto unknown_2{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID,
|
||||
"(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
|
||||
unknown_1, unknown_2, applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.StartLRAssignmentMode();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.StopLRAssignmentMode();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
const auto mode{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
|
||||
applet_resource_user_id, mode);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::GetNpadHandheldActivationMode(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::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_1{rp.Pop<u32>()};
|
||||
const auto npad_2{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
|
||||
applet_resource_user_id, npad_1, npad_2);
|
||||
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
if (controller.SwapNpadAssignment(npad_1, npad_2)) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
} else {
|
||||
LOG_ERROR(Service_HID, "Npads are not connected!");
|
||||
rb.Push(ERR_NPAD_NOT_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
@@ -635,47 +751,6 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
|
||||
applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
|
||||
}
|
||||
|
||||
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_id{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
|
||||
applet_resource_user_id);
|
||||
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto unknown_1{rp.Pop<u32>()};
|
||||
const auto unknown_2{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID,
|
||||
"(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
|
||||
unknown_1, unknown_2, applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
const auto mode{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
|
||||
applet_resource_user_id, mode);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_HID, "called");
|
||||
|
||||
@@ -769,49 +844,6 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.StartLRAssignmentMode();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.StopLRAssignmentMode();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_1{rp.Pop<u32>()};
|
||||
const auto npad_2{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
|
||||
applet_resource_user_id, npad_1, npad_2);
|
||||
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
if (controller.SwapNpadAssignment(npad_1, npad_2)) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
} else {
|
||||
LOG_ERROR(Service_HID, "Npads are not connected!");
|
||||
rb.Push(ERR_NPAD_NOT_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
class HidDbg final : public ServiceFramework<HidDbg> {
|
||||
public:
|
||||
explicit HidDbg() : ServiceFramework{"hid:dbg"} {
|
||||
|
||||
@@ -106,14 +106,19 @@ private:
|
||||
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
|
||||
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
|
||||
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
|
||||
void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
|
||||
void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
|
||||
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
|
||||
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
|
||||
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
|
||||
void SendVibrationValue(Kernel::HLERequestContext& ctx);
|
||||
void SendVibrationValues(Kernel::HLERequestContext& ctx);
|
||||
void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
|
||||
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
|
||||
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
|
||||
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx);
|
||||
void PermitVibration(Kernel::HLERequestContext& ctx);
|
||||
@@ -123,9 +128,6 @@ private:
|
||||
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
|
||||
void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<IAppletResource> applet_resource;
|
||||
Core::System& system;
|
||||
|
||||
@@ -294,7 +294,7 @@ public:
|
||||
Memory::ReadBlock(nro_address, nro_data.data(), nro_size);
|
||||
|
||||
SHA256Hash hash{};
|
||||
mbedtls_sha256(nro_data.data(), nro_data.size(), hash.data(), 0);
|
||||
mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0);
|
||||
|
||||
// NRO Hash is already loaded
|
||||
if (std::any_of(nro.begin(), nro.end(), [&hash](const std::pair<VAddr, NROInfo>& info) {
|
||||
|
||||
@@ -242,7 +242,7 @@ private:
|
||||
const auto index = db.IndexOf(uuid);
|
||||
if (index > MAX_MIIS) {
|
||||
// TODO(DarkLordZach): Find a better error code
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
rb.Push(index);
|
||||
} else {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -268,7 +268,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
// TODO(DarkLordZach): Find a better error code
|
||||
rb.Push(success ? RESULT_SUCCESS : ResultCode(-1));
|
||||
rb.Push(success ? RESULT_SUCCESS : RESULT_UNKNOWN);
|
||||
}
|
||||
|
||||
void AddOrReplace(Kernel::HLERequestContext& ctx) {
|
||||
@@ -282,7 +282,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
// TODO(DarkLordZach): Find a better error code
|
||||
rb.Push(success ? RESULT_SUCCESS : ResultCode(-1));
|
||||
rb.Push(success ? RESULT_SUCCESS : RESULT_UNKNOWN);
|
||||
}
|
||||
|
||||
void Delete(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -16,18 +16,14 @@
|
||||
#include "core/hle/service/nfp/nfp_user.h"
|
||||
|
||||
namespace Service::NFP {
|
||||
|
||||
namespace ErrCodes {
|
||||
[[maybe_unused]] constexpr ResultCode ERR_TAG_FAILED(ErrorModule::NFP,
|
||||
-1); // TODO(ogniK): Find the actual error code
|
||||
constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152);
|
||||
} // namespace ErrCodes
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
|
||||
: ServiceFramework(name), module(std::move(module)), system(system) {
|
||||
auto& kernel = system.Kernel();
|
||||
nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
|
||||
"IUser:NFCTagDetected");
|
||||
nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:NFCTagDetected");
|
||||
}
|
||||
|
||||
Module::Interface::~Interface() = default;
|
||||
@@ -66,10 +62,9 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
deactivate_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "IUser:DeactivateEvent");
|
||||
availability_change_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic, "IUser:AvailabilityChangeEvent");
|
||||
deactivate_event = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:DeactivateEvent");
|
||||
availability_change_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, "IUser:AvailabilityChangeEvent");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "core/hle/kernel/writable_event.h"
|
||||
#include "core/hle/service/nifm/nifm.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::NIFM {
|
||||
|
||||
@@ -69,10 +70,8 @@ public:
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
|
||||
"IRequest:Event1");
|
||||
event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
|
||||
"IRequest:Event2");
|
||||
event1 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event1");
|
||||
event2 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event2");
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -88,7 +87,12 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushEnum(RequestState::Connected);
|
||||
|
||||
if (Settings::values.bcat_backend == "none") {
|
||||
rb.PushEnum(RequestState::NotSubmitted);
|
||||
} else {
|
||||
rb.PushEnum(RequestState::Connected);
|
||||
}
|
||||
}
|
||||
|
||||
void GetResult(Kernel::HLERequestContext& ctx) {
|
||||
@@ -196,14 +200,22 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u8>(1);
|
||||
if (Settings::values.bcat_backend == "none") {
|
||||
rb.Push<u8>(0);
|
||||
} else {
|
||||
rb.Push<u8>(1);
|
||||
}
|
||||
}
|
||||
void IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u8>(1);
|
||||
if (Settings::values.bcat_backend == "none") {
|
||||
rb.Push<u8>(0);
|
||||
} else {
|
||||
rb.Push<u8>(1);
|
||||
}
|
||||
}
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
@@ -141,8 +141,7 @@ public:
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
finished_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, Kernel::ResetType::Automatic,
|
||||
"IEnsureNetworkClockAvailabilityService:FinishEvent");
|
||||
kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -271,7 +271,7 @@ void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestC
|
||||
"output buffer is too small! (actual={:016X}, expected_min=0x4000)", size);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
// TODO(DarkLordZach): Find a better error code for this.
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestC
|
||||
0x4000 + control.second->GetSize());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
// TODO(DarkLordZach): Find a better error code for this.
|
||||
rb.Push(ResultCode(-1));
|
||||
rb.Push(RESULT_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output,
|
||||
const auto key = Common::swap32(EXPECTED_RESULT ^ EXPECTED_MAGIC);
|
||||
std::vector<u32> transformed_font(input.size() + 2);
|
||||
transformed_font[0] = Common::swap32(EXPECTED_MAGIC);
|
||||
transformed_font[1] = Common::swap32(input.size() * sizeof(u32)) ^ key;
|
||||
transformed_font[1] = Common::swap32(static_cast<u32>(input.size() * sizeof(u32))) ^ key;
|
||||
std::transform(input.begin(), input.end(), transformed_font.begin() + 2,
|
||||
[key](u32 in) { return in ^ key; });
|
||||
std::memcpy(output.data() + offset, transformed_font.data(),
|
||||
|
||||
@@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
|
||||
switch (static_cast<IoctlCommand>(command.raw)) {
|
||||
case IoctlCommand::IocSetNVMAPfdCommand:
|
||||
return SetNVMAPfd(input, output);
|
||||
case IoctlCommand::IocSubmit:
|
||||
return Submit(input, output);
|
||||
case IoctlCommand::IocGetSyncpoint:
|
||||
return GetSyncpoint(input, output);
|
||||
case IoctlCommand::IocGetWaitbase:
|
||||
return GetWaitbase(input, output);
|
||||
case IoctlCommand::IocMapBuffer:
|
||||
return MapBuffer(input, output);
|
||||
case IoctlCommand::IocMapBufferEx:
|
||||
return MapBufferEx(input, output);
|
||||
case IoctlCommand::IocUnmapBufferEx:
|
||||
return UnmapBufferEx(input, output);
|
||||
}
|
||||
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl");
|
||||
@@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
|
||||
|
||||
u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSetNvmapFD params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD));
|
||||
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
|
||||
|
||||
nvmap_fd = params.nvmap_fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSubmit params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetSyncpoint params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint));
|
||||
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
||||
params.value = 0; // Seems to be hard coded at 0
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetWaitbase params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase));
|
||||
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
||||
params.value = 0; // Seems to be hard coded at 0
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBuffer params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
|
||||
params.address_1);
|
||||
params.address_1 = 0;
|
||||
params.address_2 = 0;
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBufferEx params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
|
||||
params.address_1);
|
||||
params.address_1 = 0;
|
||||
params.address_2 = 0;
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlUnmapBufferEx params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -23,16 +23,66 @@ public:
|
||||
private:
|
||||
enum class IoctlCommand : u32_le {
|
||||
IocSetNVMAPfdCommand = 0x40044801,
|
||||
IocSubmit = 0xC0400001,
|
||||
IocGetSyncpoint = 0xC0080002,
|
||||
IocGetWaitbase = 0xC0080003,
|
||||
IocMapBuffer = 0xC01C0009,
|
||||
IocMapBufferEx = 0xC0A40009,
|
||||
IocUnmapBufferEx = 0xC0A4000A,
|
||||
};
|
||||
|
||||
struct IoctlSetNvmapFD {
|
||||
u32_le nvmap_fd;
|
||||
};
|
||||
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
|
||||
static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size");
|
||||
|
||||
struct IoctlSubmit {
|
||||
INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size");
|
||||
|
||||
struct IoctlGetSyncpoint {
|
||||
u32 unknown; // seems to be ignored? Nintendo added this
|
||||
u32 value;
|
||||
};
|
||||
static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size");
|
||||
|
||||
struct IoctlGetWaitbase {
|
||||
u32 unknown; // seems to be ignored? Nintendo added this
|
||||
u32 value;
|
||||
};
|
||||
static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size");
|
||||
|
||||
struct IoctlMapBuffer {
|
||||
u32 unknown;
|
||||
u32 address_1;
|
||||
u32 address_2;
|
||||
INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
|
||||
|
||||
struct IoctlMapBufferEx {
|
||||
u32 unknown;
|
||||
u32 address_1;
|
||||
u32 address_2;
|
||||
INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size");
|
||||
|
||||
struct IoctlUnmapBufferEx {
|
||||
INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");
|
||||
|
||||
u32_le nvmap_fd{};
|
||||
|
||||
u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
};
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
|
||||
switch (static_cast<IoctlCommand>(command.raw)) {
|
||||
case IoctlCommand::IocSetNVMAPfdCommand:
|
||||
return SetNVMAPfd(input, output);
|
||||
case IoctlCommand::IocSubmit:
|
||||
return Submit(input, output);
|
||||
case IoctlCommand::IocGetSyncpoint:
|
||||
return GetSyncpoint(input, output);
|
||||
case IoctlCommand::IocGetWaitbase:
|
||||
return GetWaitbase(input, output);
|
||||
case IoctlCommand::IocMapBuffer:
|
||||
return MapBuffer(input, output);
|
||||
case IoctlCommand::IocMapBufferEx:
|
||||
return MapBuffer(input, output);
|
||||
case IoctlCommand::IocUnmapBufferEx:
|
||||
return UnmapBufferEx(input, output);
|
||||
}
|
||||
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl");
|
||||
@@ -30,11 +42,67 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
|
||||
|
||||
u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSetNvmapFD params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD));
|
||||
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
|
||||
|
||||
nvmap_fd = params.nvmap_fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSubmit params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetSyncpoint params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint));
|
||||
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
||||
params.value = 0; // Seems to be hard coded at 0
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetWaitbase params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase));
|
||||
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
||||
params.value = 0; // Seems to be hard coded at 0
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBuffer params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
|
||||
params.address_1);
|
||||
params.address_1 = 0;
|
||||
params.address_2 = 0;
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlMapBufferEx params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
|
||||
params.address_1);
|
||||
params.address_1 = 0;
|
||||
params.address_2 = 0;
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlUnmapBufferEx params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx));
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -23,6 +23,12 @@ public:
|
||||
private:
|
||||
enum class IoctlCommand : u32_le {
|
||||
IocSetNVMAPfdCommand = 0x40044801,
|
||||
IocSubmit = 0xC0400001,
|
||||
IocGetSyncpoint = 0xC0080002,
|
||||
IocGetWaitbase = 0xC0080003,
|
||||
IocMapBuffer = 0xC01C0009,
|
||||
IocMapBufferEx = 0xC03C0009,
|
||||
IocUnmapBufferEx = 0xC03C000A,
|
||||
};
|
||||
|
||||
struct IoctlSetNvmapFD {
|
||||
@@ -30,9 +36,53 @@ private:
|
||||
};
|
||||
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
|
||||
|
||||
struct IoctlSubmit {
|
||||
INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size");
|
||||
|
||||
struct IoctlGetSyncpoint {
|
||||
u32 unknown; // seems to be ignored? Nintendo added this
|
||||
u32 value;
|
||||
};
|
||||
static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size");
|
||||
|
||||
struct IoctlGetWaitbase {
|
||||
u32 unknown; // seems to be ignored? Nintendo added this
|
||||
u32 value;
|
||||
};
|
||||
static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size");
|
||||
|
||||
struct IoctlMapBuffer {
|
||||
u32 unknown;
|
||||
u32 address_1;
|
||||
u32 address_2;
|
||||
INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
|
||||
|
||||
struct IoctlMapBufferEx {
|
||||
u32 unknown;
|
||||
u32 address_1;
|
||||
u32 address_2;
|
||||
INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size");
|
||||
|
||||
struct IoctlUnmapBufferEx {
|
||||
INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure
|
||||
};
|
||||
static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size");
|
||||
|
||||
u32_le nvmap_fd{};
|
||||
|
||||
u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
};
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -40,8 +40,7 @@ Module::Module(Core::System& system) {
|
||||
auto& kernel = system.Kernel();
|
||||
for (u32 i = 0; i < MaxNvEvents; i++) {
|
||||
std::string event_label = fmt::format("NVDRV::NvEvent_{}", i);
|
||||
events_interface.events[i] =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, event_label);
|
||||
events_interface.events[i] = Kernel::WritableEvent::CreateEventPair(kernel, event_label);
|
||||
events_interface.status[i] = EventState::Free;
|
||||
events_interface.registered[i] = false;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@ namespace Service::NVFlinger {
|
||||
|
||||
BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id)
|
||||
: id(id), layer_id(layer_id) {
|
||||
buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
|
||||
"BufferQueue NativeHandle");
|
||||
buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, "BufferQueue NativeHandle");
|
||||
}
|
||||
|
||||
BufferQueue::~BufferQueue() = default;
|
||||
|
||||
@@ -34,12 +34,12 @@ static void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time,
|
||||
additional_info = {};
|
||||
return;
|
||||
}
|
||||
calendar_time.year = tm->tm_year + 1900;
|
||||
calendar_time.month = tm->tm_mon + 1;
|
||||
calendar_time.day = tm->tm_mday;
|
||||
calendar_time.hour = tm->tm_hour;
|
||||
calendar_time.minute = tm->tm_min;
|
||||
calendar_time.second = tm->tm_sec;
|
||||
calendar_time.year = static_cast<u16_le>(tm->tm_year + 1900);
|
||||
calendar_time.month = static_cast<u8>(tm->tm_mon + 1);
|
||||
calendar_time.day = static_cast<u8>(tm->tm_mday);
|
||||
calendar_time.hour = static_cast<u8>(tm->tm_hour);
|
||||
calendar_time.minute = static_cast<u8>(tm->tm_min);
|
||||
calendar_time.second = static_cast<u8>(tm->tm_sec);
|
||||
|
||||
additional_info.day_of_week = tm->tm_wday;
|
||||
additional_info.day_of_year = tm->tm_yday;
|
||||
@@ -322,7 +322,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
|
||||
if (tm == nullptr) {
|
||||
LOG_ERROR(Service_Time, "tm is a nullptr");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1)); // TODO(ogniK): Find appropriate error code
|
||||
rb.Push(RESULT_UNKNOWN); // TODO(ogniK): Find appropriate error code
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -331,12 +331,12 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
|
||||
const SteadyClockTimePoint steady_clock_time_point{static_cast<u64_le>(ms.count() / 1000), {}};
|
||||
|
||||
CalendarTime calendar_time{};
|
||||
calendar_time.year = tm->tm_year + 1900;
|
||||
calendar_time.month = tm->tm_mon + 1;
|
||||
calendar_time.day = tm->tm_mday;
|
||||
calendar_time.hour = tm->tm_hour;
|
||||
calendar_time.minute = tm->tm_min;
|
||||
calendar_time.second = tm->tm_sec;
|
||||
calendar_time.year = static_cast<u16_le>(tm->tm_year + 1900);
|
||||
calendar_time.month = static_cast<u8>(tm->tm_mon + 1);
|
||||
calendar_time.day = static_cast<u8>(tm->tm_mday);
|
||||
calendar_time.hour = static_cast<u8>(tm->tm_hour);
|
||||
calendar_time.minute = static_cast<u8>(tm->tm_min);
|
||||
calendar_time.second = static_cast<u8>(tm->tm_sec);
|
||||
|
||||
ClockSnapshot clock_snapshot{};
|
||||
clock_snapshot.system_posix_time = time_since_epoch;
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace Service::VI {
|
||||
|
||||
Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} {
|
||||
auto& kernel = system.Kernel();
|
||||
vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
|
||||
fmt::format("Display VSync Event {}", id));
|
||||
vsync_event =
|
||||
Kernel::WritableEvent::CreateEventPair(kernel, fmt::format("Display VSync Event {}", id));
|
||||
}
|
||||
|
||||
Display::~Display() = default;
|
||||
|
||||
@@ -45,7 +45,7 @@ struct DisplayInfo {
|
||||
|
||||
/// Whether or not the display has a limited number of layers.
|
||||
u8 has_limited_layers{1};
|
||||
INSERT_PADDING_BYTES(7){};
|
||||
INSERT_PADDING_BYTES(7);
|
||||
|
||||
/// Indicates the total amount of layers supported by the display.
|
||||
/// @note This is only valid if has_limited_layers is set.
|
||||
@@ -541,7 +541,7 @@ private:
|
||||
} else {
|
||||
// Wait the current thread until a buffer becomes available
|
||||
ctx.SleepClientThread(
|
||||
"IHOSBinderDriver::DequeueBuffer", -1,
|
||||
"IHOSBinderDriver::DequeueBuffer", UINT64_MAX,
|
||||
[=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
|
||||
Kernel::ThreadWakeupReason reason) {
|
||||
// Repeat TransactParcel DequeueBuffer when a buffer is available
|
||||
|
||||
@@ -81,7 +81,7 @@ double PerfStats::GetMeanFrametime() {
|
||||
return 0;
|
||||
}
|
||||
const double sum = std::accumulate(perf_history.begin() + IgnoreFrames,
|
||||
perf_history.begin() + current_index, 0);
|
||||
perf_history.begin() + current_index, 0.0);
|
||||
return sum / (current_index - IgnoreFrames);
|
||||
}
|
||||
|
||||
|
||||
@@ -180,3 +180,9 @@ target_link_libraries(video_core PRIVATE glad)
|
||||
if (ENABLE_VULKAN)
|
||||
target_link_libraries(video_core PRIVATE sirit)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(video_core PRIVATE /we4267)
|
||||
else()
|
||||
target_compile_options(video_core PRIVATE -Werror=conversion -Wno-error=sign-conversion)
|
||||
endif()
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/icl/interval_map.hpp>
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
@@ -30,7 +34,7 @@ public:
|
||||
using BufferInfo = std::pair<const TBufferType*, u64>;
|
||||
|
||||
BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4,
|
||||
bool is_written = false) {
|
||||
bool is_written = false, bool use_fast_cbuf = false) {
|
||||
std::lock_guard lock{mutex};
|
||||
|
||||
auto& memory_manager = system.GPU().MemoryManager();
|
||||
@@ -43,9 +47,13 @@ public:
|
||||
// Cache management is a big overhead, so only cache entries with a given size.
|
||||
// TODO: Figure out which size is the best for given games.
|
||||
constexpr std::size_t max_stream_size = 0x800;
|
||||
if (size < max_stream_size) {
|
||||
if (use_fast_cbuf || size < max_stream_size) {
|
||||
if (!is_written && !IsRegionWritten(cache_addr, cache_addr + size - 1)) {
|
||||
return StreamBufferUpload(host_ptr, size, alignment);
|
||||
if (use_fast_cbuf) {
|
||||
return ConstBufferUpload(host_ptr, size);
|
||||
} else {
|
||||
return StreamBufferUpload(host_ptr, size, alignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +160,10 @@ protected:
|
||||
virtual void CopyBlock(const TBuffer& src, const TBuffer& dst, std::size_t src_offset,
|
||||
std::size_t dst_offset, std::size_t size) = 0;
|
||||
|
||||
virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) {
|
||||
return {};
|
||||
}
|
||||
|
||||
/// Register an object into the cache
|
||||
void Register(const MapInterval& new_map, bool inherit_written = false) {
|
||||
const CacheAddr cache_ptr = new_map->GetStart();
|
||||
|
||||
@@ -28,6 +28,13 @@ void Fermi2D::CallMethod(const GPU::MethodCall& method_call) {
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<u32, u32> DelimitLine(u32 src_1, u32 src_2, u32 dst_1, u32 dst_2, u32 src_line) {
|
||||
const u32 line_a = src_2 - src_1;
|
||||
const u32 line_b = dst_2 - dst_1;
|
||||
const u32 excess = std::max<s32>(0, line_a - src_line + src_1);
|
||||
return {line_b - (excess * line_b) / line_a, excess};
|
||||
}
|
||||
|
||||
void Fermi2D::HandleSurfaceCopy() {
|
||||
LOG_DEBUG(HW_GPU, "Requested a surface copy with operation {}",
|
||||
static_cast<u32>(regs.operation));
|
||||
@@ -47,10 +54,27 @@ void Fermi2D::HandleSurfaceCopy() {
|
||||
src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width);
|
||||
src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height);
|
||||
}
|
||||
u32 dst_blit_x2 = regs.blit_dst_x + regs.blit_dst_width;
|
||||
u32 dst_blit_y2 = regs.blit_dst_y + regs.blit_dst_height;
|
||||
const auto [new_dst_w, src_excess_x] =
|
||||
DelimitLine(src_blit_x1, src_blit_x2, regs.blit_dst_x, dst_blit_x2, regs.src.width);
|
||||
const auto [new_dst_h, src_excess_y] =
|
||||
DelimitLine(src_blit_y1, src_blit_y2, regs.blit_dst_y, dst_blit_y2, regs.src.height);
|
||||
dst_blit_x2 = new_dst_w + regs.blit_dst_x;
|
||||
src_blit_x2 = src_blit_x2 - src_excess_x;
|
||||
dst_blit_y2 = new_dst_h + regs.blit_dst_y;
|
||||
src_blit_y2 = src_blit_y2 - src_excess_y;
|
||||
const auto [new_src_w, dst_excess_x] =
|
||||
DelimitLine(regs.blit_dst_x, dst_blit_x2, src_blit_x1, src_blit_x2, regs.dst.width);
|
||||
const auto [new_src_h, dst_excess_y] =
|
||||
DelimitLine(regs.blit_dst_y, dst_blit_y2, src_blit_y1, src_blit_y2, regs.dst.height);
|
||||
src_blit_x2 = new_src_w + src_blit_x1;
|
||||
dst_blit_x2 = dst_blit_x2 - dst_excess_x;
|
||||
src_blit_y2 = new_src_h + src_blit_y1;
|
||||
dst_blit_y2 = dst_blit_y2 - dst_excess_y;
|
||||
const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2};
|
||||
const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y,
|
||||
regs.blit_dst_x + regs.blit_dst_width,
|
||||
regs.blit_dst_y + regs.blit_dst_height};
|
||||
const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y, dst_blit_x2,
|
||||
dst_blit_y2};
|
||||
Config copy_config;
|
||||
copy_config.operation = regs.operation;
|
||||
copy_config.filter = regs.blit_control.filter;
|
||||
|
||||
@@ -99,19 +99,19 @@ public:
|
||||
|
||||
union {
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(0x80);
|
||||
INSERT_UNION_PADDING_WORDS(0x80);
|
||||
|
||||
Surface dst;
|
||||
|
||||
INSERT_PADDING_WORDS(2);
|
||||
INSERT_UNION_PADDING_WORDS(2);
|
||||
|
||||
Surface src;
|
||||
|
||||
INSERT_PADDING_WORDS(0x15);
|
||||
INSERT_UNION_PADDING_WORDS(0x15);
|
||||
|
||||
Operation operation;
|
||||
|
||||
INSERT_PADDING_WORDS(0x177);
|
||||
INSERT_UNION_PADDING_WORDS(0x177);
|
||||
|
||||
union {
|
||||
u32 raw;
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
BitField<4, 1, Filter> filter;
|
||||
} blit_control;
|
||||
|
||||
INSERT_PADDING_WORDS(0x8);
|
||||
INSERT_UNION_PADDING_WORDS(0x8);
|
||||
|
||||
u32 blit_dst_x;
|
||||
u32 blit_dst_y;
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
u64 blit_src_x;
|
||||
u64 blit_src_y;
|
||||
|
||||
INSERT_PADDING_WORDS(0x21);
|
||||
INSERT_UNION_PADDING_WORDS(0x21);
|
||||
};
|
||||
std::array<u32, NUM_REGS> reg_array;
|
||||
};
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
|
||||
union {
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(0x60);
|
||||
INSERT_UNION_PADDING_WORDS(0x60);
|
||||
|
||||
Upload::Registers upload;
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
|
||||
u32 data_upload;
|
||||
|
||||
INSERT_PADDING_WORDS(0x3F);
|
||||
INSERT_UNION_PADDING_WORDS(0x3F);
|
||||
|
||||
struct {
|
||||
u32 address;
|
||||
@@ -72,11 +72,11 @@ public:
|
||||
}
|
||||
} launch_desc_loc;
|
||||
|
||||
INSERT_PADDING_WORDS(0x1);
|
||||
INSERT_UNION_PADDING_WORDS(0x1);
|
||||
|
||||
u32 launch;
|
||||
|
||||
INSERT_PADDING_WORDS(0x4A7);
|
||||
INSERT_UNION_PADDING_WORDS(0x4A7);
|
||||
|
||||
struct {
|
||||
u32 address_high;
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
}
|
||||
} tsc;
|
||||
|
||||
INSERT_PADDING_WORDS(0x3);
|
||||
INSERT_UNION_PADDING_WORDS(0x3);
|
||||
|
||||
struct {
|
||||
u32 address_high;
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
}
|
||||
} tic;
|
||||
|
||||
INSERT_PADDING_WORDS(0x22);
|
||||
INSERT_UNION_PADDING_WORDS(0x22);
|
||||
|
||||
struct {
|
||||
u32 address_high;
|
||||
@@ -111,11 +111,11 @@ public:
|
||||
}
|
||||
} code_loc;
|
||||
|
||||
INSERT_PADDING_WORDS(0x3FE);
|
||||
INSERT_UNION_PADDING_WORDS(0x3FE);
|
||||
|
||||
u32 tex_cb_index;
|
||||
|
||||
INSERT_PADDING_WORDS(0x374);
|
||||
INSERT_UNION_PADDING_WORDS(0x374);
|
||||
};
|
||||
std::array<u32, NUM_REGS> reg_array;
|
||||
};
|
||||
@@ -179,7 +179,7 @@ public:
|
||||
};
|
||||
|
||||
INSERT_PADDING_WORDS(0x11);
|
||||
} launch_description;
|
||||
} launch_description{};
|
||||
|
||||
struct {
|
||||
u32 write_offset = 0;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user