Compare commits
329 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33558d14e5 | |||
| c37fc73a02 | |||
| d152537e50 | |||
| 5d4e87373f | |||
| 1c36156594 | |||
| 300701a06b | |||
| a776f15557 | |||
| 1c89f8a855 | |||
| 81e4d9c2ee | |||
| 49be6be8f4 | |||
| b861a9c5d0 | |||
| 9828e6cafc | |||
| 3d8d9ef61c | |||
| 5d13978bbf | |||
| b844aecb9e | |||
| f57c8c1c35 | |||
| bbbc5f6e6c | |||
| ac0c60b740 | |||
| f2f95a20a3 | |||
| 12f213ffad | |||
| 66e1cf96e2 | |||
| c3b7229fbb | |||
| f96a0ce9d2 | |||
| ba592070f7 | |||
| 6a2ea62f82 | |||
| 6cfd817b5a | |||
| c99ef4b09f | |||
| 7e131f8fb6 | |||
| 10171c19c3 | |||
| e0853095e3 | |||
| 5a365506f7 | |||
| 4aee1b378a | |||
| 9f5e3ecb8c | |||
| 7b9614fcf3 | |||
| 8e62a0e22d | |||
| f89d3d5077 | |||
| 145e059cdf | |||
| 22916a7e8d | |||
| 07f458f991 | |||
| 6180a58d7a | |||
| 5cc2a7c09e | |||
| e584653b72 | |||
| f4b346a6f8 | |||
| cb1b71bc57 | |||
| 95060efb7d | |||
| b82dd61a0c | |||
| c84d10686f | |||
| d652a81078 | |||
| fc76d2df38 | |||
| 1a98682ea0 | |||
| 64437a531b | |||
| 4d26170bd6 | |||
| 36831a3d6a | |||
| e7c0df4eac | |||
| a296c19633 | |||
| 8b5f7a0770 | |||
| 7b9a36be7d | |||
| cbe1628cf2 | |||
| d482c078bc | |||
| 38f9332905 | |||
| 96f1f9e45e | |||
| f031cd9b42 | |||
| 3aa15c8a23 | |||
| a3cc3aa8b8 | |||
| 29f67448e9 | |||
| 976a3ed3bf | |||
| 98c0944419 | |||
| bf78b197a3 | |||
| 427960fee8 | |||
| 75da7d80dc | |||
| 7eb730ee03 | |||
| 4b9fa7a417 | |||
| 6163acc8c5 | |||
| 4add5b6bf0 | |||
| 1ae3b37fbe | |||
| 23c710cf53 | |||
| e29b81c444 | |||
| 73dba6d6e0 | |||
| 09e845a539 | |||
| e1744ceab2 | |||
| cbb1b1f28e | |||
| 59f9938849 | |||
| 8db318094f | |||
| 5a4206e05d | |||
| 6794ae35a1 | |||
| 8676913e73 | |||
| 2ef120fdcd | |||
| 08c1a14b13 | |||
| 4a138aa918 | |||
| 793a21a825 | |||
| 6fd76054b4 | |||
| c80be9e54b | |||
| 56ebae773c | |||
| fad6647255 | |||
| edb2b60f2f | |||
| d894ccb4ea | |||
| bd09dc8ea8 | |||
| a1e19e1cf8 | |||
| 799dbfc2c5 | |||
| 54e6cf95d7 | |||
| 3ea0e391db | |||
| 4fd21f7764 | |||
| f8009451a9 | |||
| f5c48a00b4 | |||
| c70338a9a9 | |||
| e83540d80c | |||
| 24dde5d42b | |||
| 8e15afb2c4 | |||
| 911cd678ff | |||
| f11770b88b | |||
| 514ef9a9c5 | |||
| 57070aa8ff | |||
| e06c6b5ac8 | |||
| a6dada6c36 | |||
| a058cf2ff0 | |||
| 142d25c0d7 | |||
| 4e6231a321 | |||
| 29d87a3743 | |||
| 9a2b06f35f | |||
| 4e2f3a289c | |||
| db70cd058a | |||
| b6cdf18165 | |||
| 7d710cbf8c | |||
| 654c4e3c06 | |||
| a3271b08b7 | |||
| b0de5970ce | |||
| db7f84f9f8 | |||
| 58140e1d3a | |||
| 315d9c308b | |||
| d13c0ee393 | |||
| 7740cac6dd | |||
| ead8e5e0c3 | |||
| 195de818b6 | |||
| 5c0113ce59 | |||
| db2341c842 | |||
| b7b87096d8 | |||
| 6a41b22a1b | |||
| 5696065727 | |||
| e9281843bf | |||
| 43184a271f | |||
| a7e1bc34de | |||
| 98c46f7eb0 | |||
| 3de0f042c6 | |||
| f115032095 | |||
| 0b628cb50e | |||
| 751775a04c | |||
| 177bb3c569 | |||
| 3cf8c629fa | |||
| 3947250daa | |||
| 96be211c88 | |||
| b00b8ae71b | |||
| 45f416c4f1 | |||
| c58149f5b6 | |||
| 579a6c9311 | |||
| 08e7a23121 | |||
| bf190fd3d8 | |||
| ea3a73b598 | |||
| 9989fb4bbc | |||
| 0524f4a540 | |||
| 43febd392c | |||
| dea894161a | |||
| 710f07049d | |||
| fe977c4288 | |||
| f5b9d86e42 | |||
| 9ab4802d07 | |||
| f0828ebbc0 | |||
| 84b1624b23 | |||
| 47da39a2ff | |||
| 7bec3b30b7 | |||
| ad5a62b62d | |||
| f080798000 | |||
| 6af81d649f | |||
| 5f3f8eeec6 | |||
| 9b4302bc2f | |||
| fa618a2bf7 | |||
| 6915025c7e | |||
| 5cf80c05a5 | |||
| 711afeb688 | |||
| 96165cd21d | |||
| 1a07f40c4b | |||
| eb5ea82bb1 | |||
| cd9ff08235 | |||
| 957713015a | |||
| a639772dfe | |||
| 6c85d97d6c | |||
| 7feb13671a | |||
| 3f066cca4a | |||
| c86d221ba5 | |||
| 5870dad639 | |||
| 53a70c6e77 | |||
| 45fecf0059 | |||
| a6e4b77273 | |||
| f932cc4073 | |||
| 6bf77166e1 | |||
| 6b9d0d5df5 | |||
| 9778322d99 | |||
| 6ff04ec91b | |||
| c7700fcd72 | |||
| 027b1d5cab | |||
| ce65a1c2a7 | |||
| 650b0c7c30 | |||
| 823b23f800 | |||
| b47db88ded | |||
| 20b92f50d9 | |||
| b401ad85d1 | |||
| e9df63119b | |||
| caa6c9b471 | |||
| bb8e43f16c | |||
| 2c71d08ea2 | |||
| 500f7901ac | |||
| 5fb716fc21 | |||
| 31ef970f23 | |||
| a770eaf500 | |||
| e171f3af41 | |||
| 1041284384 | |||
| 6555de6ef5 | |||
| b81e77cffa | |||
| a1741f21cc | |||
| 76a36f45bf | |||
| a767beec60 | |||
| 183bea3b98 | |||
| 6981cbb985 | |||
| fdfcc6c5ea | |||
| b86ecf7441 | |||
| 5107d1b69b | |||
| e133c8c2c3 | |||
| 450ab7c289 | |||
| 32bfb808ae | |||
| 1f19804cab | |||
| 9ff6003dfc | |||
| f725ea7d0d | |||
| 39d17a94c6 | |||
| 8153e5338f | |||
| 999caea021 | |||
| b70665865f | |||
| 6a9e0c52c3 | |||
| 44b3709d1d | |||
| b060165817 | |||
| 98fc073f89 | |||
| ba29f0ccd1 | |||
| 3473e19508 | |||
| 22bd7dcc42 | |||
| 79d09d02ed | |||
| a6313fa46c | |||
| 2a7431bd61 | |||
| 90851459c8 | |||
| 27c9bf137c | |||
| 2205790dd4 | |||
| 0115c2f70a | |||
| 7bce99d77b | |||
| 47b65868f4 | |||
| 8735a06f3c | |||
| d35fecbeea | |||
| 0e388639cc | |||
| 17e6ad1fe8 | |||
| a3f077c783 | |||
| 86b3229746 | |||
| 06b0e35fb9 | |||
| 6fbca1acfd | |||
| f0e36c6365 | |||
| e9cb7000cc | |||
| 0e8b0e414a | |||
| ec3114d6d8 | |||
| 60fc51ed22 | |||
| 603b775f4a | |||
| 964ce3d6aa | |||
| fb88e1c1c9 | |||
| 7081b89e97 | |||
| c6ab1aa227 | |||
| 8a509afc20 | |||
| 6a95e0877b | |||
| 28c37ab465 | |||
| 842edbcbe7 | |||
| 3e556c710b | |||
| 4289ffef1c | |||
| 0c051a83a7 | |||
| 82dedb1fbb | |||
| 04c0f309be | |||
| 8408d51359 | |||
| a8ada492b2 | |||
| 55d6ee65ae | |||
| 69ecf8aea7 | |||
| f2b51668b4 | |||
| c2527c9e1b | |||
| 0bcd45c1d4 | |||
| ecf0022fd1 | |||
| 4d4a70ad0e | |||
| 0f45a8c180 | |||
| ad3e740c09 | |||
| 7e6cc02e09 | |||
| 7000ef4471 | |||
| 0beda6fa89 | |||
| a41d2e43fd | |||
| c98158b460 | |||
| 02a53c582c | |||
| 192f4825a2 | |||
| bcce3acd5f | |||
| 8cd6b9275a | |||
| 5fa9dfac6a | |||
| fe51c7b960 | |||
| cf5346c263 | |||
| 776b3b5efa | |||
| 520524285a | |||
| ec8cb1668c | |||
| 1b7b59466d | |||
| e45e9c20dd | |||
| 450cb1771c | |||
| f7a3d45c2c | |||
| 65eb625843 | |||
| c06b957a8a | |||
| 05064dfaf4 | |||
| 425610b98a | |||
| 0d34b97948 | |||
| c6426245e4 | |||
| 6fe41870ab | |||
| 2d4e02f277 | |||
| 6d7d3fff6d | |||
| cc145eaf2e | |||
| da6d1d359c | |||
| 92ae57c9ee | |||
| 8409979dc5 | |||
| 8bc92a2cbb | |||
| 2de4c03faa | |||
| 382a7c94a2 | |||
| 1d7a00666e | |||
| 14c0289542 | |||
| 69ebdfd689 | |||
| fc21ece784 | |||
| a3ededdcf1 |
@@ -3,13 +3,13 @@
|
||||
# Pull all the submodules except llvm
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ && !/SPIRV/ { print $3 }' .gitmodules)
|
||||
|
||||
# Prefer newer Clang than in base system (see also .ci/install-freebsd.sh)
|
||||
# libc++ isn't in llvm* packages, so download manually
|
||||
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/llvm-project-15.0.6.src.tar.xz
|
||||
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.1/llvm-project-16.0.1.src.tar.xz
|
||||
tar xf llvm*.tar.xz
|
||||
export CC=clang15 CXX=clang++15
|
||||
export CC=clang16 CXX=clang++16
|
||||
cmake -B libcxx_build -G Ninja -S llvm*/libcxx \
|
||||
-DLLVM_CCACHE_BUILD=ON \
|
||||
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
|
||||
@@ -20,7 +20,7 @@ export CXXFLAGS="$CXXFLAGS -nostdinc++ -isystem$PWD/libcxx_prefix/include/c++/v1
|
||||
export LDFLAGS="$LDFLAGS -nostdlib++ -L$PWD/libcxx_prefix/lib -l:libc++.a -lcxxrt"
|
||||
|
||||
CONFIGURE_ARGS="
|
||||
-DWITH_LLVM=OFF
|
||||
-DWITH_LLVM=ON
|
||||
-DUSE_SDL=OFF
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF
|
||||
|
||||
+5
-10
@@ -9,15 +9,10 @@ if [ -z "$CIRRUS_CI" ]; then
|
||||
cd rpcs3 || exit 1
|
||||
fi
|
||||
|
||||
# Pull all the submodules except llvm, since it is built separately and we just download that build
|
||||
# Pull all the submodules except llvm
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
|
||||
# Download pre-compiled llvm libs
|
||||
curl -sLO https://github.com/RPCS3/llvm-mirror/releases/download/custom-build/llvmlibs-linux.tar.gz
|
||||
mkdir llvmlibs
|
||||
tar -xzf ./llvmlibs-linux.tar.gz -C llvmlibs
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ && !/SPIRV/ { print $3 }' .gitmodules)
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
@@ -42,8 +37,6 @@ export CFLAGS="$CFLAGS -fuse-ld=${LINKER}"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DBUILD_LLVM_SUBMODULE=OFF \
|
||||
-DLLVM_DIR=llvmlibs/lib/cmake/llvm/ \
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF \
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF \
|
||||
-DCMAKE_C_FLAGS="$CFLAGS" \
|
||||
@@ -51,8 +44,10 @@ cmake .. \
|
||||
-DCMAKE_AR="$AR" \
|
||||
-DCMAKE_RANLIB="$RANLIB" \
|
||||
-DUSE_SYSTEM_CURL=ON \
|
||||
-DUSE_SDL=OFF \
|
||||
-DUSE_SDL=ON \
|
||||
-DOpenGL_GL_PREFERENCE=LEGACY \
|
||||
-DLLVM_DIR=/opt/llvm/lib/cmake/llvm \
|
||||
-DSTATIC_LINK_LLVM=ON \
|
||||
-G Ninja
|
||||
|
||||
ninja; build_status=$?;
|
||||
|
||||
+8
-7
@@ -1,10 +1,12 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
brew install -f --overwrite llvm@14 nasm ninja git p7zip create-dmg ccache
|
||||
brew install -f --overwrite nasm ninja git p7zip create-dmg ccache pipenv
|
||||
|
||||
#/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
arch -x86_64 /usr/local/homebrew/bin/brew install -f --overwrite llvm@14 sdl2 glew cmake
|
||||
arch -x86_64 /usr/local/homebrew/bin/brew update
|
||||
arch -x86_64 /usr/local/homebrew/bin/brew install -f --overwrite llvm@16 sdl2 glew cmake
|
||||
arch -x86_64 /usr/local/homebrew/bin/brew link -f llvm@16
|
||||
|
||||
#export MACOSX_DEPLOYMENT_TARGET=12.0
|
||||
export CXX=clang++
|
||||
@@ -21,19 +23,18 @@ export CMAKE_EXTRA_OPTS='-DLLVM_TARGETS_TO_BUILD=X86'
|
||||
export WORKDIR;
|
||||
WORKDIR="$(pwd)"
|
||||
|
||||
#get Qt
|
||||
# Get Qt
|
||||
git clone https://github.com/engnr/qt-downloader.git
|
||||
cd qt-downloader
|
||||
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
|
||||
pip3 install pipenv
|
||||
pipenv run pip3 install py7zr requests semantic_version lxml
|
||||
pipenv run ./qt-downloader macos desktop 5.15.2 clang_64 --opensource
|
||||
"/opt/homebrew/bin/pipenv" run pip3 install py7zr requests semantic_version lxml
|
||||
"/opt/homebrew/bin/pipenv" run ./qt-downloader macos desktop 5.15.2 clang_64 --opensource
|
||||
cd ..
|
||||
|
||||
export Qt5_DIR="$WORKDIR/qt-downloader/5.15.2/clang_64/lib/cmake/Qt5"
|
||||
export SDL2_DIR="$BREW_X64_PATH/opt/sdl2/lib/cmake/SDL2"
|
||||
|
||||
export PATH="$BREW_PATH/opt/llvm@14/bin:$WORKDIR/qt-downloader/5.15.2/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
|
||||
export PATH="$BREW_X64_PATH/opt/llvm@16/bin:$WORKDIR/qt-downloader/5.15.2/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
|
||||
export LDFLAGS="-L$BREW_X64_PATH/lib -Wl,-rpath,$BREW_X64_PATH/lib"
|
||||
export CPPFLAGS="-I$BREW_X64_PATH/include -msse -msse2 -mcx16 -no-pie"
|
||||
export LIBRARY_PATH="$BREW_X64_PATH/lib"
|
||||
|
||||
+14
-40
@@ -3,48 +3,27 @@
|
||||
cd build || exit 1
|
||||
|
||||
if [ "$DEPLOY_APPIMAGE" = "true" ]; then
|
||||
DESTDIR=appdir ninja install
|
||||
QT_APPIMAGE="linuxdeployqt.AppImage"
|
||||
DESTDIR=AppDir ninja install
|
||||
|
||||
curl -sL "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" > "$QT_APPIMAGE"
|
||||
chmod a+x "$QT_APPIMAGE"
|
||||
"./$QT_APPIMAGE" --appimage-extract
|
||||
./squashfs-root/AppRun ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs
|
||||
ls ./appdir/usr/lib/
|
||||
rm -r ./appdir/usr/share/doc
|
||||
cp "$(readlink -f /lib/x86_64-linux-gnu/libnsl.so.1)" ./appdir/usr/lib/libnsl.so.1
|
||||
export PATH=/rpcs3/build/squashfs-root/usr/bin/:"${PATH}"
|
||||
curl -sL -o /usr/bin/linuxdeploy https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
chmod +x /usr/bin/linuxdeploy
|
||||
curl -sL -o /usr/bin/linuxdeploy-plugin-qt https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
chmod +x /usr/bin/linuxdeploy-plugin-qt
|
||||
curl -sL -o linuxdeploy-plugin-checkrt.sh https://github.com/linuxdeploy/linuxdeploy-plugin-checkrt/releases/download/continuous/linuxdeploy-plugin-checkrt-x86_64.sh
|
||||
chmod +x ./linuxdeploy-plugin-checkrt.sh
|
||||
|
||||
# Embed newer libstdc++ for distros that don't come with it (ubuntu 16.04)
|
||||
mkdir -p appdir/usr/optional/ ; mkdir -p appdir/usr/optional/libstdc++/
|
||||
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./appdir/usr/optional/libstdc++/
|
||||
EXTRA_QT_PLUGINS="svg;" APPIMAGE_EXTRACT_AND_RUN=1 linuxdeploy --appdir AppDir --plugin qt
|
||||
|
||||
# Remove libwayland-client because it has platform-dependent exports and breaks other OSes
|
||||
rm -f ./appdir/usr/lib/libwayland-client.so*
|
||||
rm -f ./AppDir/usr/lib/libwayland-client.so*
|
||||
|
||||
# Remove libgmodule and libglib due to g_source_set_static_name symbol conflict with host libraries
|
||||
rm -f ./appdir/usr/lib/libgmodule-2.0.so*
|
||||
rm -f ./appdir/usr/lib/libglib-2.0.so*
|
||||
# Remove git directory containing local commit history file
|
||||
rm -rf ./AppDir/usr/share/rpcs3/git
|
||||
|
||||
# Install latest appimage runner
|
||||
rm ./appdir/AppRun
|
||||
curl -sL https://github.com/RPCS3/AppImageKit-checkrt/releases/download/continuous2/AppRun-patched-x86_64 -o ./appdir/AppRun
|
||||
chmod a+x ./appdir/AppRun
|
||||
curl -sL https://github.com/RPCS3/AppImageKit-checkrt/releases/download/continuous2/exec-x86_64.so -o ./appdir/usr/optional/exec.so
|
||||
./linuxdeploy-plugin-checkrt.sh --appdir AppDir
|
||||
|
||||
# Compile checker binary for AppImageKit-checkrt
|
||||
|
||||
# This may need updating if you update the compiler or rpcs3 uses newer c++ features
|
||||
# See https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/config/abi/pre/gnu.ver
|
||||
# for which definitions correlate to which CXXABI version.
|
||||
# Currently we target a minimum of GLIBCXX_3.4.29 and CXXABI_1.3.11
|
||||
printf "#include <sstream>\n#include <exception>\n#include <memory_resource>\nint main(){auto x = std::stringbuf();x.get_allocator();std::make_exception_ptr(0);std::pmr::get_default_resource();}" \
|
||||
| $CXX -x c++ -std=c++2a -o ./appdir/usr/optional/checker -
|
||||
|
||||
# Package it up and send it off
|
||||
./squashfs-root/usr/bin/appimagetool "$APPDIR"
|
||||
|
||||
ls
|
||||
linuxdeploy --appimage-extract
|
||||
./squashfs-root/plugins/linuxdeploy-plugin-appimage/usr/bin/appimagetool AppDir -g
|
||||
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT="$(git rev-list --count HEAD)"
|
||||
@@ -61,9 +40,4 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
|
||||
FILESIZE=$(stat -c %s ./rpcs3*.AppImage)
|
||||
SHA256SUM=$(sha256sum ./rpcs3*.AppImage | awk '{ print $1 }')
|
||||
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
|
||||
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_PPA" = "true" ]; then
|
||||
export DEBFULLNAME="RPCS3 Build Bot"
|
||||
fi
|
||||
|
||||
+3
-2
@@ -15,7 +15,7 @@ echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
|
||||
cd bin
|
||||
mkdir "rpcs3.app/Contents/lib/"
|
||||
|
||||
cp "/usr/local/Homebrew/opt/llvm@14/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
|
||||
cp "/usr/local/Homebrew/opt/llvm@16/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
|
||||
|
||||
rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQml.framework" \
|
||||
@@ -23,7 +23,8 @@ rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQuick.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtVirtualKeyboard.framework" \
|
||||
"rpcs3.app/Contents/Plugins/platforminputcontexts" \
|
||||
"rpcs3.app/Contents/Plugins/virtualkeyboard"
|
||||
"rpcs3.app/Contents/Plugins/virtualkeyboard" \
|
||||
"rpcs3.app/Contents/Resources/git"
|
||||
|
||||
# Need to do this rename hack due to case insensitive filesystem
|
||||
mv rpcs3.app RPCS3_.app
|
||||
|
||||
@@ -5,6 +5,7 @@ ARTIFACT_DIR="$BUILD_ARTIFACTSTAGINGDIRECTORY"
|
||||
|
||||
# Remove unecessary files
|
||||
rm -f ./bin/rpcs3.exp ./bin/rpcs3.lib ./bin/rpcs3.pdb ./bin/vc_redist.x64.exe
|
||||
rm -rf ./bin/git
|
||||
|
||||
# Prepare compatibility database for packaging, as well as
|
||||
# certificate for ssl (auto-updater)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
curl -L -o "./llvm.lock" "https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z.sha256"
|
||||
curl -L -o "./llvm.lock" "https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win-16.0.1/llvmlibs_mt.7z.sha256"
|
||||
curl -L -o "./glslang.lock" "https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z.sha256"
|
||||
|
||||
@@ -9,7 +9,7 @@ export ASSUME_ALWAYS_YES=true
|
||||
pkg info # debug
|
||||
|
||||
# Prefer newer Clang than in base system (see also .ci/build-freebsd.sh)
|
||||
pkg install llvm15
|
||||
pkg install llvm16
|
||||
|
||||
# Mandatory dependencies (qt5-dbus and qt5-gui are pulled via qt5-widgets)
|
||||
pkg install git ccache cmake ninja qt5-qmake qt5-buildtools qt5-widgets qt5-concurrent qt5-multimedia qt5-svg glew openal-soft ffmpeg
|
||||
|
||||
@@ -19,7 +19,7 @@ QT_DECL_URL="${QT_HOST}${QT_PREFIX}qtdeclarative${QT_SUFFIX}"
|
||||
QT_TOOL_URL="${QT_HOST}${QT_PREFIX}qttools${QT_SUFFIX}"
|
||||
QT_MM_URL="${QT_HOST}${QT_PREFIX}qtmultimedia${QT_SUFFIX}"
|
||||
QT_SVG_URL="${QT_HOST}${QT_PREFIX}qtsvg${QT_SUFFIX}"
|
||||
LLVMLIBS_URL='https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z'
|
||||
LLVMLIBS_URL='https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win-16.0.1/llvmlibs_mt.7z'
|
||||
GLSLANG_URL='https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z'
|
||||
VULKAN_SDK_URL="https://www.dropbox.com/s/cs77c3iv5mbo0bt/VulkanSDK-${VULKAN_VER}-Installer.exe"
|
||||
|
||||
@@ -40,7 +40,7 @@ DEP_URLS=" \
|
||||
# Pull all the submodules except llvm, since it is built separately and we just download that build
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/llvm/ && !/SPIRV/ { print $3 }' .gitmodules)
|
||||
|
||||
# Git bash doesn't have rev, so here it is
|
||||
rev()
|
||||
@@ -79,7 +79,7 @@ for url in $DEP_URLS; do
|
||||
# shellcheck disable=SC1003
|
||||
case "$url" in
|
||||
*qt*) checksum=$(curl -L "${url}.sha1"); algo="sha1"; outDir='C:\Qt\' ;;
|
||||
*llvm*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="." ;;
|
||||
*llvm*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="./3rdparty/llvm" ;;
|
||||
*glslang*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="./lib/Release-x64" ;;
|
||||
*Vulkan*)
|
||||
# Vulkan setup needs to be run in batch environment
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ windows_task:
|
||||
|
||||
linux_task:
|
||||
container:
|
||||
image: rpcs3/rpcs3-ci-bionic:1.6
|
||||
image: rpcs3/rpcs3-ci-bionic:1.8
|
||||
cpu: 4
|
||||
memory: 16G
|
||||
env:
|
||||
|
||||
+7
-1
@@ -36,7 +36,6 @@
|
||||
/ipch
|
||||
/rpcs3/Debug
|
||||
/rpcs3/Release
|
||||
/llvm_build
|
||||
|
||||
!/bin
|
||||
/bin/*
|
||||
@@ -104,6 +103,7 @@ rpcs3/rpcs3_autogen/*
|
||||
|
||||
# QtCreator
|
||||
CMakeLists.txt.user
|
||||
*.autosave
|
||||
|
||||
# CLion
|
||||
/.idea/*
|
||||
@@ -125,6 +125,12 @@ yaml-cpp.pc
|
||||
# miniupnp
|
||||
/3rdparty/miniupnp/x64/*
|
||||
|
||||
# llvm
|
||||
/3rdparty/llvm/llvm_build
|
||||
|
||||
# legacy llvm
|
||||
/llvm_build
|
||||
|
||||
# ssl certificate
|
||||
cacert.pem
|
||||
|
||||
|
||||
+9
-5
@@ -7,9 +7,9 @@
|
||||
url = ../../RPCS3/asmjit.git
|
||||
branch = aarch64
|
||||
ignore = dirty
|
||||
[submodule "llvm"]
|
||||
path = llvm
|
||||
url = ../../RPCS3/llvm-mirror.git
|
||||
[submodule "3rdparty/llvm/llvm"]
|
||||
path = 3rdparty/llvm/llvm
|
||||
url = ../../llvm/llvm-project.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/glslang"]
|
||||
path = 3rdparty/glslang/glslang
|
||||
@@ -78,8 +78,12 @@
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/libsdl-org/SDL"]
|
||||
path = 3rdparty/libsdl-org/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
url = ../../libsdl-org/SDL.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/miniupnp/miniupnp"]
|
||||
path = 3rdparty/miniupnp/miniupnp
|
||||
url = https://github.com/miniupnp/miniupnp.git
|
||||
url = ../../miniupnp/miniupnp.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/rtmidi/rtmidi"]
|
||||
path = 3rdparty/rtmidi/rtmidi
|
||||
url = ../../thestk/rtmidi
|
||||
|
||||
Vendored
+8
-2
@@ -78,7 +78,7 @@ add_subdirectory(hidapi)
|
||||
|
||||
# Vulkan
|
||||
add_subdirectory(glslang EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(SPIRV EXCLUDE_FROM_ALL)
|
||||
#add_subdirectory(SPIRV EXCLUDE_FROM_ALL)
|
||||
|
||||
|
||||
# yaml-cpp
|
||||
@@ -189,7 +189,7 @@ if(USE_VULKAN)
|
||||
if(VULKAN_FOUND)
|
||||
add_library(3rdparty_vulkan INTERFACE)
|
||||
target_compile_definitions(3rdparty_vulkan INTERFACE -DHAVE_VULKAN)
|
||||
target_link_libraries(3rdparty_vulkan INTERFACE SPIRV SPIRV-Tools-opt Vulkan::Vulkan)
|
||||
target_link_libraries(3rdparty_vulkan INTERFACE SPIRV Vulkan::Vulkan)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Wayland)
|
||||
@@ -345,6 +345,8 @@ if(USE_SDL)
|
||||
message(STATUS "Using system SDL2")
|
||||
add_library(3rdparty_sdl2 INTERFACE)
|
||||
target_compile_definitions(3rdparty_sdl2 INTERFACE -DHAVE_SDL2=1)
|
||||
target_include_directories(3rdparty_sdl2 INTERFACE ${SDL2_INCLUDE_DIRS})
|
||||
target_link_libraries(3rdparty_sdl2 INTERFACE ${SDL2_LIBRARIES})
|
||||
set(SDL2_TARGET 3rdparty_sdl2)
|
||||
else()
|
||||
message(FATAL_ERROR "SDL2 is not available on this system")
|
||||
@@ -361,6 +363,9 @@ endif()
|
||||
# MINIUPNP
|
||||
add_subdirectory(miniupnp EXCLUDE_FROM_ALL)
|
||||
|
||||
# RTMIDI
|
||||
add_subdirectory(rtmidi EXCLUDE_FROM_ALL)
|
||||
|
||||
# add nice ALIAS targets for ease of use
|
||||
if(USE_SYSTEM_LIBUSB)
|
||||
add_library(3rdparty::libusb ALIAS usb-1.0-shared)
|
||||
@@ -389,3 +394,4 @@ add_library(3rdparty::libcurl ALIAS libcurl)
|
||||
add_library(3rdparty::soundtouch ALIAS soundtouch)
|
||||
add_library(3rdparty::sdl2 ALIAS ${SDL2_TARGET})
|
||||
add_library(3rdparty::miniupnpc ALIAS libminiupnpc-static)
|
||||
add_library(3rdparty::rtmidi ALIAS rtmidi)
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/FAudio updated: c42b6814c2...cac0aca5f7
Vendored
+1
-1
@@ -4,7 +4,7 @@ include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(moltenvk
|
||||
GIT_REPOSITORY https://github.com/KhronosGroup/MoltenVK.git
|
||||
GIT_TAG fb581e4
|
||||
GIT_TAG 4c6bfbe
|
||||
BUILD_IN_SOURCE 1
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK
|
||||
CONFIGURE_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/fetchDependencies" --macos
|
||||
|
||||
+1
@@ -70,6 +70,7 @@
|
||||
<PreprocessorDefinitions>SOUNDTOUCH_ALLOW_SSE;ST_NO_EXCEPTION_HANDLING;USE_MULTICH_ALWAYS;SOUNDTOUCH_FLOAT_SAMPLES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>./soundtouch/source/SoundTouch;./soundtouch/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/asmjit/asmjit updated: 06d0badec5...c59847629d
Vendored
+1
@@ -187,6 +187,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>ASMJIT_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
Vendored
+1
@@ -79,6 +79,7 @@
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>OUTSIDE_SPEEX;RANDOM_PREFIX=speex;FLOATING_POINT;_USE_SSE;_USE_SSE2;EXPORT=;USE_WASAPI;USE_WINMM;CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>./cubeb/subprojects/;./extra/;./cubeb/src/;./cubeb/include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/curl/curl updated: c12fb3ddaf...1561d06752
Vendored
+25
-9
@@ -64,8 +64,14 @@
|
||||
<ClCompile Include="curl\lib\asyn-ares.c" />
|
||||
<ClCompile Include="curl\lib\asyn-thread.c" />
|
||||
<ClCompile Include="curl\lib\base64.c" />
|
||||
<ClCompile Include="curl\lib\bufq.c" />
|
||||
<ClCompile Include="curl\lib\bufref.c" />
|
||||
<ClCompile Include="curl\lib\c-hyper.c" />
|
||||
<ClCompile Include="curl\lib\cf-h1-proxy.c" />
|
||||
<ClCompile Include="curl\lib\cf-h2-proxy.c" />
|
||||
<ClCompile Include="curl\lib\cf-haproxy.c" />
|
||||
<ClCompile Include="curl\lib\cf-https-connect.c" />
|
||||
<ClCompile Include="curl\lib\cf-socket.c" />
|
||||
<ClCompile Include="curl\lib\cfilters.c" />
|
||||
<ClCompile Include="curl\lib\conncache.c" />
|
||||
<ClCompile Include="curl\lib\connect.c" />
|
||||
@@ -78,6 +84,7 @@
|
||||
<ClCompile Include="curl\lib\curl_gethostname.c" />
|
||||
<ClCompile Include="curl\lib\curl_get_line.c" />
|
||||
<ClCompile Include="curl\lib\curl_gssapi.c" />
|
||||
<ClCompile Include="curl\lib\curl_log.c" />
|
||||
<ClCompile Include="curl\lib\curl_memrchr.c" />
|
||||
<ClCompile Include="curl\lib\curl_multibyte.c" />
|
||||
<ClCompile Include="curl\lib\curl_ntlm_core.c" />
|
||||
@@ -91,6 +98,7 @@
|
||||
<ClCompile Include="curl\lib\dict.c" />
|
||||
<ClCompile Include="curl\lib\doh.c" />
|
||||
<ClCompile Include="curl\lib\dynbuf.c" />
|
||||
<ClCompile Include="curl\lib\dynhds.c" />
|
||||
<ClCompile Include="curl\lib\easy.c" />
|
||||
<ClCompile Include="curl\lib\easygetopt.c" />
|
||||
<ClCompile Include="curl\lib\easyoptions.c" />
|
||||
@@ -104,7 +112,6 @@
|
||||
<ClCompile Include="curl\lib\getenv.c" />
|
||||
<ClCompile Include="curl\lib\getinfo.c" />
|
||||
<ClCompile Include="curl\lib\gopher.c" />
|
||||
<ClCompile Include="curl\lib\h2h3.c" />
|
||||
<ClCompile Include="curl\lib\hash.c" />
|
||||
<ClCompile Include="curl\lib\headers.c" />
|
||||
<ClCompile Include="curl\lib\hmac.c" />
|
||||
@@ -115,6 +122,7 @@
|
||||
<ClCompile Include="curl\lib\hostsyn.c" />
|
||||
<ClCompile Include="curl\lib\hsts.c" />
|
||||
<ClCompile Include="curl\lib\http.c" />
|
||||
<ClCompile Include="curl\lib\http1.c" />
|
||||
<ClCompile Include="curl\lib\http2.c" />
|
||||
<ClCompile Include="curl\lib\http_aws_sigv4.c" />
|
||||
<ClCompile Include="curl\lib\http_chunks.c" />
|
||||
@@ -179,11 +187,13 @@
|
||||
<ClCompile Include="curl\lib\vauth\gsasl.c" />
|
||||
<ClCompile Include="curl\lib\version.c" />
|
||||
<ClCompile Include="curl\lib\version_win32.c" />
|
||||
<ClCompile Include="curl\lib\vquic\curl_msh3.c" />
|
||||
<ClCompile Include="curl\lib\vquic\curl_ngtcp2.c" />
|
||||
<ClCompile Include="curl\lib\vquic\curl_quiche.c" />
|
||||
<ClCompile Include="curl\lib\vtls\hostcheck.c" />
|
||||
<ClCompile Include="curl\lib\vtls\rustls.c" />
|
||||
<ClCompile Include="curl\lib\vtls\x509asn1.c" />
|
||||
<ClCompile Include="curl\lib\warnless.c" />
|
||||
<ClCompile Include="curl\lib\wildcard.c" />
|
||||
<ClCompile Include="curl\lib\vauth\cleartext.c" />
|
||||
<ClCompile Include="curl\lib\vauth\cram.c" />
|
||||
<ClCompile Include="curl\lib\vauth\digest.c" />
|
||||
@@ -196,8 +206,6 @@
|
||||
<ClCompile Include="curl\lib\vauth\spnego_gssapi.c" />
|
||||
<ClCompile Include="curl\lib\vauth\spnego_sspi.c" />
|
||||
<ClCompile Include="curl\lib\vauth\vauth.c" />
|
||||
<ClCompile Include="curl\lib\vquic\ngtcp2.c" />
|
||||
<ClCompile Include="curl\lib\vquic\quiche.c" />
|
||||
<ClCompile Include="curl\lib\vquic\vquic.c" />
|
||||
<ClCompile Include="curl\lib\vssh\libssh.c" />
|
||||
<ClCompile Include="curl\lib\vssh\libssh2.c" />
|
||||
@@ -231,8 +239,14 @@
|
||||
<ClInclude Include="curl\lib\amigaos.h" />
|
||||
<ClInclude Include="curl\lib\arpa_telnet.h" />
|
||||
<ClInclude Include="curl\lib\asyn.h" />
|
||||
<ClInclude Include="curl\lib\bufq.h" />
|
||||
<ClInclude Include="curl\lib\bufref.h" />
|
||||
<ClInclude Include="curl\lib\c-hyper.h" />
|
||||
<ClInclude Include="curl\lib\cf-h1-proxy.h" />
|
||||
<ClInclude Include="curl\lib\cf-h2-proxy.h" />
|
||||
<ClInclude Include="curl\lib\cf-haproxy.h" />
|
||||
<ClInclude Include="curl\lib\cf-https-connect.h" />
|
||||
<ClInclude Include="curl\lib\cf-socket.h" />
|
||||
<ClInclude Include="curl\lib\cfilters.h" />
|
||||
<ClInclude Include="curl\lib\config-amigaos.h" />
|
||||
<ClInclude Include="curl\lib\config-dos.h" />
|
||||
@@ -259,6 +273,7 @@
|
||||
<ClInclude Include="curl\lib\curl_hmac.h" />
|
||||
<ClInclude Include="curl\lib\curl_krb5.h" />
|
||||
<ClInclude Include="curl\lib\curl_ldap.h" />
|
||||
<ClInclude Include="curl\lib\curl_log.h" />
|
||||
<ClInclude Include="curl\lib\curl_md4.h" />
|
||||
<ClInclude Include="curl\lib\curl_md5.h" />
|
||||
<ClInclude Include="curl\lib\curl_memory.h" />
|
||||
@@ -280,6 +295,7 @@
|
||||
<ClInclude Include="curl\lib\doh.h" />
|
||||
<ClInclude Include="curl\lib\dotdot.h" />
|
||||
<ClInclude Include="curl\lib\dynbuf.h" />
|
||||
<ClInclude Include="curl\lib\dynhds.h" />
|
||||
<ClInclude Include="curl\lib\easyif.h" />
|
||||
<ClInclude Include="curl\lib\easyoptions.h" />
|
||||
<ClInclude Include="curl\lib\easy_lock.h" />
|
||||
@@ -293,12 +309,12 @@
|
||||
<ClInclude Include="curl\lib\functypes.h" />
|
||||
<ClInclude Include="curl\lib\getinfo.h" />
|
||||
<ClInclude Include="curl\lib\gopher.h" />
|
||||
<ClInclude Include="curl\lib\h2h3.h" />
|
||||
<ClInclude Include="curl\lib\hash.h" />
|
||||
<ClInclude Include="curl\lib\headers.h" />
|
||||
<ClInclude Include="curl\lib\hostip.h" />
|
||||
<ClInclude Include="curl\lib\hsts.h" />
|
||||
<ClInclude Include="curl\lib\http.h" />
|
||||
<ClInclude Include="curl\lib\http1.h" />
|
||||
<ClInclude Include="curl\lib\http2.h" />
|
||||
<ClInclude Include="curl\lib\http_aws_sigv4.h" />
|
||||
<ClInclude Include="curl\lib\http_chunks.h" />
|
||||
@@ -325,7 +341,6 @@
|
||||
<ClInclude Include="curl\lib\pop3.h" />
|
||||
<ClInclude Include="curl\lib\progress.h" />
|
||||
<ClInclude Include="curl\lib\psl.h" />
|
||||
<ClInclude Include="curl\lib\quic.h" />
|
||||
<ClInclude Include="curl\lib\rand.h" />
|
||||
<ClInclude Include="curl\lib\rename.h" />
|
||||
<ClInclude Include="curl\lib\rtsp.h" />
|
||||
@@ -360,16 +375,17 @@
|
||||
<ClInclude Include="curl\lib\urlapi-int.h" />
|
||||
<ClInclude Include="curl\lib\urldata.h" />
|
||||
<ClInclude Include="curl\lib\version_win32.h" />
|
||||
<ClInclude Include="curl\lib\vquic\curl_msh3.h" />
|
||||
<ClInclude Include="curl\lib\vquic\curl_ngtcp2.h" />
|
||||
<ClInclude Include="curl\lib\vquic\curl_quiche.h" />
|
||||
<ClInclude Include="curl\lib\vquic\vquic_int.h" />
|
||||
<ClInclude Include="curl\lib\vtls\hostcheck.h" />
|
||||
<ClInclude Include="curl\lib\vtls\rustls.h" />
|
||||
<ClInclude Include="curl\lib\vtls\x509asn1.h" />
|
||||
<ClInclude Include="curl\lib\warnless.h" />
|
||||
<ClInclude Include="curl\lib\wildcard.h" />
|
||||
<ClInclude Include="curl\lib\vauth\digest.h" />
|
||||
<ClInclude Include="curl\lib\vauth\ntlm.h" />
|
||||
<ClInclude Include="curl\lib\vauth\vauth.h" />
|
||||
<ClInclude Include="curl\lib\vquic\ngtcp2.h" />
|
||||
<ClInclude Include="curl\lib\vquic\quiche.h" />
|
||||
<ClInclude Include="curl\lib\vquic\vquic.h" />
|
||||
<ClInclude Include="curl\lib\vssh\ssh.h" />
|
||||
<ClInclude Include="curl\lib\vssh\wolfssh.h" />
|
||||
|
||||
+75
-27
@@ -330,9 +330,6 @@
|
||||
<ClCompile Include="curl\lib\warnless.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\wildcard.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vauth\cleartext.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -369,12 +366,6 @@
|
||||
<ClCompile Include="curl\lib\vauth\vauth.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vquic\ngtcp2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vquic\quiche.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vssh\libssh.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -456,9 +447,6 @@
|
||||
<ClCompile Include="curl\lib\vauth\gsasl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\h2h3.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vtls\hostcheck.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -486,6 +474,42 @@
|
||||
<ClCompile Include="curl\lib\idn.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\curl_log.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\cf-https-connect.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\cf-socket.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vquic\curl_msh3.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vquic\curl_ngtcp2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\vquic\curl_quiche.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\http1.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\dynhds.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\bufq.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\cf-h1-proxy.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\cf-h2-proxy.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\cf-haproxy.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="curl\include\curl\curl.h">
|
||||
@@ -764,9 +788,6 @@
|
||||
<ClInclude Include="curl\lib\psl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\quic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\rand.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -863,9 +884,6 @@
|
||||
<ClInclude Include="curl\lib\warnless.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\wildcard.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vauth\digest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -875,12 +893,6 @@
|
||||
<ClInclude Include="curl\lib\vauth\vauth.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vquic\ngtcp2.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vquic\quiche.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vssh\ssh.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -956,9 +968,6 @@
|
||||
<ClInclude Include="curl\lib\vtls\rustls.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\h2h3.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vtls\hostcheck.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -992,6 +1001,45 @@
|
||||
<ClInclude Include="curl\lib\idn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\curl_log.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\cf-https-connect.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\cf-socket.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vquic\curl_msh3.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vquic\curl_ngtcp2.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vquic\curl_quiche.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\vquic\vquic_int.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\http1.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\dynhds.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\bufq.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\cf-h1-proxy.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\cf-h2-proxy.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\cf-haproxy.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="curl\lib\libcurl.rc">
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/hidapi/hidapi updated: ecf1b62882...8b43a97a93
Vendored
+1
-1
Submodule 3rdparty/libsdl-org/SDL updated: adf31f6ec0...ac13ca9ab6
Vendored
+1
@@ -453,6 +453,7 @@
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>SDL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
Vendored
+35
-28
@@ -2,10 +2,10 @@ if(WITH_LLVM)
|
||||
CHECK_CXX_COMPILER_FLAG("-msse -msse2 -mcx16" COMPILER_X86)
|
||||
CHECK_CXX_COMPILER_FLAG("-march=armv8-a+lse" COMPILER_ARM)
|
||||
|
||||
if(BUILD_LLVM_SUBMODULE)
|
||||
if(BUILD_LLVM)
|
||||
message(STATUS "LLVM will be built from the submodule.")
|
||||
|
||||
set(LLVM_TARGETS_TO_BUILD "AArch64;X86")
|
||||
set(LLVM_TARGETS_TO_BUILD "AArch64;X86" CACHE STRING "Semicolon-separated list of targets to build, or \"all\".")
|
||||
option(LLVM_BUILD_RUNTIME OFF)
|
||||
option(LLVM_BUILD_TOOLS OFF)
|
||||
option(LLVM_INCLUDE_BENCHMARKS OFF)
|
||||
@@ -32,54 +32,61 @@ if(WITH_LLVM)
|
||||
endif()
|
||||
|
||||
# LLVM needs to be built out-of-tree
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/llvm ${CMAKE_CURRENT_BINARY_DIR}/llvm_build EXCLUDE_FROM_ALL)
|
||||
set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/llvm_build/lib/cmake/llvm/")
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/3rdparty/llvm/llvm/llvm ${CMAKE_BINARY_DIR}/3rdparty/llvm/llvm_build EXCLUDE_FROM_ALL)
|
||||
set(LLVM_DIR "${CMAKE_BINARY_DIR}/3rdparty/llvm/llvm_build/lib/cmake/llvm/")
|
||||
|
||||
set(CMAKE_CXX_FLAGS ${CXX_FLAGS_OLD})
|
||||
set(STATIC_LINK_LLVM ON CACHE BOOL "Link against LLVM statically. This will get set to ON if you build LLVM from the submodule." FORCE)
|
||||
|
||||
# now tries to find LLVM again
|
||||
find_package(LLVM 13.0 CONFIG)
|
||||
find_package(LLVM 16.0 CONFIG)
|
||||
if(NOT LLVM_FOUND)
|
||||
message(FATAL_ERROR "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(STATUS "Using prebuilt LLVM")
|
||||
message(STATUS "Using prebuilt or system LLVM")
|
||||
|
||||
if (LLVM_DIR AND NOT IS_ABSOLUTE "${LLVM_DIR}")
|
||||
# change relative LLVM_DIR to be relative to the source dir
|
||||
set(LLVM_DIR ${CMAKE_SOURCE_DIR}/${LLVM_DIR})
|
||||
endif()
|
||||
|
||||
find_package(LLVM 13.0 CONFIG)
|
||||
find_package(LLVM 16.0 CONFIG)
|
||||
|
||||
if (NOT LLVM_FOUND)
|
||||
if (LLVM_VERSION AND LLVM_VERSION_MAJOR LESS 11)
|
||||
message(FATAL_ERROR "Found LLVM version ${LLVM_VERSION}. Required version 11.0. \
|
||||
Enable BUILD_LLVM_SUBMODULE option to build LLVM from included as a git submodule.")
|
||||
if (LLVM_VERSION AND LLVM_VERSION_MAJOR LESS 16)
|
||||
message(FATAL_ERROR "Found LLVM version ${LLVM_VERSION}. Required version 16. \
|
||||
Enable BUILD_LLVM option to build LLVM from included as a git submodule.")
|
||||
endif()
|
||||
|
||||
message(FATAL_ERROR "Can't find LLVM libraries from the CMAKE_PREFIX_PATH path or LLVM_DIR. \
|
||||
Enable BUILD_LLVM_SUBMODULE option to build LLVM from included as a git submodule.")
|
||||
Enable BUILD_LLVM option to build LLVM from included as a git submodule.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(LLVM_LIBS LLVMMCJIT)
|
||||
|
||||
if(COMPILER_X86)
|
||||
set(LLVM_LIBS ${LLVM_LIBS} LLVMX86CodeGen LLVMX86AsmParser)
|
||||
endif()
|
||||
|
||||
if(COMPILER_ARM)
|
||||
set(LLVM_LIBS ${LLVM_LIBS} LLVMX86CodeGen LLVMX86AsmParser LLVMAArch64CodeGen LLVMAArch64AsmParser)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR CMAKE_SYSTEM MATCHES "Linux")
|
||||
set(LLVM_LIBS ${LLVM_LIBS} LLVMIntelJITEvents)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM MATCHES "Linux")
|
||||
set(LLVM_LIBS ${LLVM_LIBS} LLVMPerfJITEvents)
|
||||
if (STATIC_LINK_LLVM)
|
||||
if (NOT DEFINED LLVM_TARGETS_TO_BUILD)
|
||||
if(COMPILER_ARM)
|
||||
set(LLVM_TARGETS_TO_BUILD "AArch64;X86" CACHE STRING "Semicolon-separated list of targets to build, or \"all\".")
|
||||
else()
|
||||
set(LLVM_TARGETS_TO_BUILD "X86" CACHE STRING "Semicolon-separated list of targets to build, or \"all\".")
|
||||
endif()
|
||||
endif()
|
||||
if(WIN32 OR CMAKE_SYSTEM MATCHES "Linux")
|
||||
set (LLVM_ADDITIONAL_LIBS ${LLVM_ADDITIONAL_LIBS} IntelJITEvents)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM MATCHES "Linux")
|
||||
set (LLVM_ADDITIONAL_LIBS ${LLVM_ADDITIONAL_LIBS} PerfJITEvents)
|
||||
endif()
|
||||
llvm_map_components_to_libnames(LLVM_LIBS
|
||||
${LLVM_TARGETS_TO_BUILD}
|
||||
${LLVM_ADDITIONAL_LIBS}
|
||||
Core
|
||||
ExecutionEngine
|
||||
MCJIT
|
||||
)
|
||||
else()
|
||||
set(LLVM_LIBS LLVM)
|
||||
endif()
|
||||
|
||||
add_library(3rdparty_llvm INTERFACE)
|
||||
|
||||
+1
Submodule 3rdparty/llvm/llvm added at cd89023f79
+4
-4
@@ -14,9 +14,9 @@
|
||||
<ProjectGuid>{8BC303AB-25BE-4276-8E57-73F171B2D672}</ProjectGuid>
|
||||
<Keyword>MakeFileProj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\buildfiles\msvc\common_default.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\buildfiles\msvc\common_default_macros.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
@@ -39,9 +39,9 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<CmakeReleaseCLI>call vsdevcmd.bat -arch=amd64
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="./Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm</CmakeReleaseCLI>
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="./Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm/llvm</CmakeReleaseCLI>
|
||||
<CmakeDebugCLI>call vsdevcmd.bat -arch=amd64
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="./Debug" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm</CmakeDebugCLI>
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="cl.exe" -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX="./Debug" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm/llvm</CmakeDebugCLI>
|
||||
<CmakeCleanCLI>echo Cleaning..
|
||||
for /F "delims= eol=|" %%f in ('
|
||||
dir /b ^| findstr /V "[^.]*\build[^.]*\.vcxproj"') do (
|
||||
Vendored
Vendored
+4
-4
@@ -14,9 +14,9 @@
|
||||
<ProjectGuid>{A37E4273-85DB-4217-B775-CE971B87D9DF}</ProjectGuid>
|
||||
<Keyword>MakeFileProj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\buildfiles\msvc\common_default_clang_cl.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_clang_cl.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\buildfiles\msvc\common_default_macros.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
@@ -39,9 +39,9 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<CmakeReleaseCLI>call vsdevcmd.bat -arch=amd64
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DCMAKE_INSTALL_PREFIX="./Release" -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm</CmakeReleaseCLI>
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DCMAKE_INSTALL_PREFIX="./Release" -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm/llvm</CmakeReleaseCLI>
|
||||
<CmakeDebugCLI>call vsdevcmd.bat -arch=amd64
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DCMAKE_INSTALL_PREFIX="./Debug" -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm</CmakeDebugCLI>
|
||||
cmake -G Ninja -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE="Debug" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DCMAKE_INSTALL_PREFIX="./Debug" -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_INTEL_JITEVENTS=ON ../llvm/llvm</CmakeDebugCLI>
|
||||
<CmakeCleanCLI>echo Cleaning..
|
||||
for /F "delims= eol=|" %%f in ('
|
||||
dir /b ^| findstr /V "[^.]*\build[^.]*\.vcxproj"') do (
|
||||
Vendored
+1
-1
Submodule 3rdparty/miniupnp/miniupnp updated: f4a739d730...e439318cf7
Vendored
+8
-3
@@ -12,18 +12,20 @@
|
||||
#include <thread>
|
||||
#include <sys/types.h>
|
||||
#if _WIN32
|
||||
#define read_portable(a, b, c) (recv(a, b, c, 0))
|
||||
#define write_portable(a, b, c) (send(a, b, c, 0))
|
||||
#define read_portable(a, b, c) (recv(a, b, ::narrow<int>(c), 0))
|
||||
#define write_portable(a, b, c) (send(a, b, ::narrow<int>(c), 0))
|
||||
#define close_portable(a) (closesocket(a))
|
||||
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
|
||||
#include <WinSock2.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#define read_portable(a, b, c) (read(a, b, c))
|
||||
#define write_portable(a, b, c) (write(a, b, c))
|
||||
#define close_portable(a) (close(a))
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
@@ -533,7 +535,10 @@ namespace pine
|
||||
// yes very good windows s/sun/sin/g sure is fine
|
||||
server.sin_family = AF_INET;
|
||||
// localhost only
|
||||
server.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
if (!inet_pton(server.sin_family, "127.0.0.1", &server.sin_addr.s_addr))
|
||||
{
|
||||
fmt::throw_exception("IPC: Failed to convert localhost");
|
||||
}
|
||||
server.sin_port = htons(Impl::get_port());
|
||||
|
||||
if (bind(m_sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
add_subdirectory(rtmidi EXCLUDE_FROM_ALL)
|
||||
+1
Submodule 3rdparty/rtmidi/rtmidi added at 84a99422a3
Vendored
+61
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="rtmidi\RtMidi.h" />
|
||||
<ClInclude Include="rtmidi\rtmidi_c.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="rtmidi\RtMidi.cpp" />
|
||||
<ClCompile Include="rtmidi\rtmidi_c.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{2C902C67-985C-4BE0-94A3-E0FE2EB929A3}</ProjectGuid>
|
||||
<RootNamespace>rtmidi</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_default.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_release.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<PreprocessorDefinitions>__WINDOWS_MM__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>./rtmidi/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Vendored
+1
-1
Submodule 3rdparty/wolfssl/wolfssl updated: 4fbd4fd36a...979707380c
+1
-1
@@ -111,7 +111,7 @@ git submodule update --init
|
||||
|
||||
Open `rpcs3.sln`. The recommended build configuration is `Release`. (On older revisions: `Release - LLVM`)
|
||||
|
||||
You may want to download the precompiled [LLVM libs](https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z) and extract them to the root rpcs3 folder (which contains `rpcs3.sln`), as well as download and extract the [additional libs](https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z) to `lib\%CONFIGURATION%-x64\` to speed up compilation time (unoptimised/debug libs are currently not available precompiled).
|
||||
You may want to download the precompiled [LLVM libs](https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win-16.0.1/llvmlibs_mt.7z) and extract them to `3rdparty\llvm\`, as well as download and extract the [additional libs](https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z) to `lib\%CONFIGURATION%-x64\` to speed up compilation time (unoptimised/debug libs are currently not available precompiled).
|
||||
|
||||
If you're not using the precompiled libs, build the following projects in *__BUILD_BEFORE* folder by right-clicking on a project > *Build*.:
|
||||
* glslang
|
||||
|
||||
+2
-1
@@ -14,7 +14,8 @@ endif()
|
||||
|
||||
option(USE_NATIVE_INSTRUCTIONS "USE_NATIVE_INSTRUCTIONS makes rpcs3 compile with -march=native, which is useful for local builds, but not good for packages." ON)
|
||||
option(WITH_LLVM "Enable usage of LLVM library" ON)
|
||||
option(BUILD_LLVM_SUBMODULE "Build LLVM from git submodule" ON)
|
||||
option(BUILD_LLVM "Build LLVM from git submodule" OFF)
|
||||
option(STATIC_LINK_LLVM "Link against LLVM statically. This will get set to ON if you build LLVM from the submodule." OFF)
|
||||
option(USE_FAUDIO "FAudio audio backend" ON)
|
||||
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
|
||||
option(USE_DISCORD_RPC "Discord rich presence integration" OFF)
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace cfg
|
||||
{
|
||||
for (const auto& node : owner->m_nodes)
|
||||
{
|
||||
if (node->get_name() == name)
|
||||
if (node->get_name() == m_name)
|
||||
{
|
||||
cfg_log.fatal("Node already exists: %s", name);
|
||||
cfg_log.fatal("Node already exists: %s", m_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_uint64(): called with an empty string");
|
||||
if (out) cfg_log.error("cfg::try_to_int64(): called with an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,6 +226,11 @@ namespace cfg
|
||||
return m_value;
|
||||
}
|
||||
|
||||
T get_default() const
|
||||
{
|
||||
return def;
|
||||
}
|
||||
|
||||
void set(T value)
|
||||
{
|
||||
m_value = value;
|
||||
|
||||
+2
-2
@@ -1783,7 +1783,7 @@ const std::string& fs::get_config_dir()
|
||||
if (GetEnvironmentVariable(L"RPCS3_CONFIG_DIR", buf, size) - 1 >= size - 1 &&
|
||||
GetModuleFileName(nullptr, buf, size) - 1 >= size - 1)
|
||||
{
|
||||
MessageBoxA(nullptr, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR);
|
||||
MessageBoxA(nullptr, fmt::format("GetModuleFileName() failed: error: %s", fmt::win_error{GetLastError(), nullptr}).c_str(), "fs::get_config_dir()", MB_ICONERROR);
|
||||
return dir; // empty
|
||||
}
|
||||
|
||||
@@ -1868,7 +1868,7 @@ const std::string& fs::get_temp_dir()
|
||||
wchar_t buf[MAX_PATH + 2]{};
|
||||
if (GetTempPathW(MAX_PATH + 1, buf) - 1 > MAX_PATH)
|
||||
{
|
||||
MessageBoxA(nullptr, fmt::format("GetTempPath() failed: error %u.", GetLastError()).c_str(), "fs::get_temp_dir()", MB_ICONERROR);
|
||||
MessageBoxA(nullptr, fmt::format("GetTempPath() failed: error: %s", fmt::win_error{GetLastError(), nullptr}).c_str(), "fs::get_temp_dir()", MB_ICONERROR);
|
||||
return dir; // empty
|
||||
}
|
||||
|
||||
|
||||
+66
-22
@@ -198,6 +198,9 @@ static u8* add_jit_memory(usz size, uint align)
|
||||
});
|
||||
}
|
||||
|
||||
ensure(pointer + pos >= get_jit_memory() + Off);
|
||||
ensure(pointer + pos < get_jit_memory() + Off + 0x40000000);
|
||||
|
||||
return pointer + pos;
|
||||
}
|
||||
|
||||
@@ -795,7 +798,7 @@ void asmjit::simd_builder::vec_cmp_eq(u32 esize, const Operand& dst, const Opera
|
||||
}
|
||||
else
|
||||
{
|
||||
_vec_binary_op(kIdPcmpeqw, kIdVpcmpeqw, kIdNone, dst, lhs, rhs);
|
||||
_vec_binary_op(kIdPcmpeqd, kIdVpcmpeqd, kIdNone, dst, lhs, rhs);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1304,7 +1307,7 @@ std::string jit_compiler::cpu(const std::string& _cpu)
|
||||
|
||||
if (m_cpu.empty())
|
||||
{
|
||||
m_cpu = llvm::sys::getHostCPUName().operator std::string();
|
||||
m_cpu = llvm::sys::getHostCPUName().str();
|
||||
|
||||
if (m_cpu == "sandybridge" ||
|
||||
m_cpu == "ivybridge" ||
|
||||
@@ -1319,7 +1322,10 @@ std::string jit_compiler::cpu(const std::string& _cpu)
|
||||
m_cpu == "icelake-client" ||
|
||||
m_cpu == "icelake-server" ||
|
||||
m_cpu == "tigerlake" ||
|
||||
m_cpu == "rocketlake")
|
||||
m_cpu == "rocketlake" ||
|
||||
m_cpu == "alderlake" ||
|
||||
m_cpu == "raptorlake" ||
|
||||
m_cpu == "meteorlake")
|
||||
{
|
||||
// Downgrade if AVX is not supported by some chips
|
||||
if (!utils::has_avx())
|
||||
@@ -1350,11 +1356,51 @@ std::string jit_compiler::cpu(const std::string& _cpu)
|
||||
// Upgrade
|
||||
m_cpu = "znver2";
|
||||
}
|
||||
|
||||
if ((m_cpu == "znver3" || m_cpu == "goldmont" || m_cpu == "alderlake" || m_cpu == "raptorlake" || m_cpu == "meteorlake") && utils::has_avx512_icl())
|
||||
{
|
||||
// Upgrade
|
||||
m_cpu = "icelake-client";
|
||||
}
|
||||
|
||||
if (m_cpu == "goldmont" && utils::has_avx2())
|
||||
{
|
||||
// Upgrade
|
||||
m_cpu = "alderlake";
|
||||
}
|
||||
}
|
||||
|
||||
return m_cpu;
|
||||
}
|
||||
|
||||
std::string jit_compiler::triple1()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
|
||||
#elif defined(__APPLE__) && defined(ARCH_X64)
|
||||
return llvm::Triple::normalize("x86_64-unknown-linux-gnu");
|
||||
#elif defined(__APPLE__) && defined(ARCH_ARM64)
|
||||
return llvm::Triple::normalize("aarch64-unknown-linux-gnu");
|
||||
#else
|
||||
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string jit_compiler::triple2()
|
||||
{
|
||||
#if defined(_WIN32) && defined(ARCH_X64)
|
||||
return llvm::Triple::normalize("x86_64-unknown-linux-gnu");
|
||||
#elif defined(_WIN32) && defined(ARCH_ARM64)
|
||||
return llvm::Triple::normalize("aarch64-unknown-linux-gnu");
|
||||
#elif defined(__APPLE__) && defined(ARCH_X64)
|
||||
return llvm::Triple::normalize("x86_64-unknown-linux-gnu");
|
||||
#elif defined(__APPLE__) && defined(ARCH_ARM64)
|
||||
return llvm::Triple::normalize("aarch64-unknown-linux-gnu");
|
||||
#else
|
||||
return llvm::Triple::normalize(llvm::sys::getProcessTriple());
|
||||
#endif
|
||||
}
|
||||
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, const std::string& _cpu, u32 flags)
|
||||
: m_context(new llvm::LLVMContext)
|
||||
, m_cpu(cpu(_cpu))
|
||||
@@ -1362,15 +1408,13 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
|
||||
std::string result;
|
||||
|
||||
auto null_mod = std::make_unique<llvm::Module> ("null_", *m_context);
|
||||
#if defined(__APPLE__) && defined(ARCH_ARM64)
|
||||
// Force override triple on Apple arm64 or we'll get linking errors.
|
||||
null_mod->setTargetTriple(llvm::Triple::normalize(utils::c_llvm_default_triple));
|
||||
#endif
|
||||
null_mod->setTargetTriple(jit_compiler::triple1());
|
||||
|
||||
std::unique_ptr<llvm::RTDyldMemoryManager> mem;
|
||||
|
||||
if (_link.empty())
|
||||
{
|
||||
std::unique_ptr<llvm::RTDyldMemoryManager> mem;
|
||||
|
||||
// Auxiliary JIT (does not use custom memory manager, only writes the objects)
|
||||
if (flags & 0x1)
|
||||
{
|
||||
mem = std::make_unique<MemoryManager1>();
|
||||
@@ -1378,31 +1422,31 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
|
||||
else
|
||||
{
|
||||
mem = std::make_unique<MemoryManager2>();
|
||||
null_mod->setTargetTriple(llvm::Triple::normalize(utils::c_llvm_default_triple));
|
||||
null_mod->setTargetTriple(jit_compiler::triple2());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mem = std::make_unique<MemoryManager1>();
|
||||
}
|
||||
|
||||
// Auxiliary JIT (does not use custom memory manager, only writes the objects)
|
||||
{
|
||||
m_engine.reset(llvm::EngineBuilder(std::move(null_mod))
|
||||
.setErrorStr(&result)
|
||||
.setEngineKind(llvm::EngineKind::JIT)
|
||||
.setMCJITMemoryManager(std::move(mem))
|
||||
.setOptLevel(llvm::CodeGenOpt::Aggressive)
|
||||
.setCodeModel(flags & 0x2 ? llvm::CodeModel::Large : llvm::CodeModel::Small)
|
||||
#ifdef __APPLE__
|
||||
//.setCodeModel(llvm::CodeModel::Large)
|
||||
#endif
|
||||
.setRelocationModel(llvm::Reloc::Model::PIC_)
|
||||
.setMCPU(m_cpu)
|
||||
.create());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Primary JIT
|
||||
m_engine.reset(llvm::EngineBuilder(std::move(null_mod))
|
||||
.setErrorStr(&result)
|
||||
.setEngineKind(llvm::EngineKind::JIT)
|
||||
.setMCJITMemoryManager(std::make_unique<MemoryManager1>())
|
||||
.setOptLevel(llvm::CodeGenOpt::Aggressive)
|
||||
.setCodeModel(flags & 0x2 ? llvm::CodeModel::Large : llvm::CodeModel::Small)
|
||||
.setMCPU(m_cpu)
|
||||
.create());
|
||||
|
||||
if (!_link.empty())
|
||||
{
|
||||
for (auto&& [name, addr] : _link)
|
||||
{
|
||||
m_engine->updateGlobalMapping(name, addr);
|
||||
|
||||
@@ -546,6 +546,12 @@ public:
|
||||
|
||||
// Get CPU info
|
||||
static std::string cpu(const std::string& _cpu);
|
||||
|
||||
// Get system triple (PPU)
|
||||
static std::string triple1();
|
||||
|
||||
// Get system triple (SPU)
|
||||
static std::string triple2();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+33
-2
@@ -79,6 +79,17 @@ std::string fmt::win_error_to_string(unsigned long error, void* module_handle)
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
std::string fmt::win_error_to_string(const fmt::win_error& error)
|
||||
{
|
||||
return fmt::win_error_to_string(error.error, error.module_handle);
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<fmt::win_error>::format(std::string& out, u64 arg)
|
||||
{
|
||||
fmt::append(out, "%s", fmt::win_error_to_string(get_object(arg)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <>
|
||||
@@ -203,6 +214,26 @@ void fmt_class_string<std::vector<char8_t>>::format(std::string& out, u64 arg)
|
||||
out.append(obj.cbegin(), obj.cend());
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<fmt::buf_to_hexstring>::format(std::string& out, u64 arg)
|
||||
{
|
||||
const auto& _arg = get_object(arg);
|
||||
const std::vector<u8> buf(_arg.buf, _arg.buf + _arg.len);
|
||||
out.reserve(out.size() + (buf.size() * 3));
|
||||
static constexpr char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
for (usz index = 0; index < buf.size(); index++)
|
||||
{
|
||||
out += hex[buf[index] >> 4];
|
||||
out += hex[buf[index] & 15];
|
||||
|
||||
if (((index + 1) % 16) == 0)
|
||||
out += '\n';
|
||||
else
|
||||
out += ' ';
|
||||
}
|
||||
}
|
||||
|
||||
void format_byte_array(std::string& out, const uchar* data, usz size)
|
||||
{
|
||||
if (!size)
|
||||
@@ -568,7 +599,7 @@ std::string fmt::trim(const std::string& source, const std::string& values)
|
||||
return source.substr(begin, source.find_last_not_of(values) + 1);
|
||||
}
|
||||
|
||||
std::string fmt::to_upper(const std::string& string)
|
||||
std::string fmt::to_upper(std::string_view string)
|
||||
{
|
||||
std::string result;
|
||||
result.resize(string.size());
|
||||
@@ -576,7 +607,7 @@ std::string fmt::to_upper(const std::string& string)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string fmt::to_lower(const std::string& string)
|
||||
std::string fmt::to_lower(std::string_view string)
|
||||
{
|
||||
std::string result;
|
||||
result.resize(string.size());
|
||||
|
||||
@@ -10,8 +10,15 @@ namespace fmt
|
||||
static std::string format(const CharT(&)[N], const Args&...);
|
||||
|
||||
#ifdef _WIN32
|
||||
struct win_error
|
||||
{
|
||||
unsigned long error{};
|
||||
void* module_handle{};
|
||||
};
|
||||
|
||||
// Get a string for a windows error (DWORD). Optionally a module HANDLE can be passed.
|
||||
std::string win_error_to_string(unsigned long error, void* module_handle = nullptr);
|
||||
std::string win_error_to_string(const win_error& error);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -15,7 +15,7 @@ std::u16string utf8_to_utf16(std::string_view src);
|
||||
|
||||
// Copy null-terminated string from a std::string or a char array to a char array with truncation
|
||||
template <typename D, typename T>
|
||||
inline void strcpy_trunc(D& dst, const T& src)
|
||||
inline void strcpy_trunc(D&& dst, const T& src)
|
||||
{
|
||||
const usz count = std::size(src) >= std::size(dst) ? std::max<usz>(std::size(dst), 1) - 1 : std::size(src);
|
||||
std::memcpy(std::data(dst), std::data(src), count);
|
||||
@@ -173,8 +173,17 @@ namespace fmt
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string to_upper(const std::string& string);
|
||||
std::string to_lower(const std::string& string);
|
||||
std::string to_upper(std::string_view string);
|
||||
std::string to_lower(std::string_view string);
|
||||
|
||||
bool match(const std::string& source, const std::string& mask);
|
||||
|
||||
struct buf_to_hexstring
|
||||
{
|
||||
buf_to_hexstring(const u8* buf, usz len)
|
||||
: buf(buf), len(len) {}
|
||||
|
||||
const u8* buf;
|
||||
usz len;
|
||||
};
|
||||
}
|
||||
|
||||
+110
-37
@@ -4,6 +4,7 @@
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_mmapper.h"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "Emu/Cell/lv2/sys_process.h"
|
||||
#include "Emu/RSX/RSXThread.h"
|
||||
#include "Thread.h"
|
||||
#include "Utilities/JIT.h"
|
||||
@@ -15,6 +16,11 @@
|
||||
#include <Psapi.h>
|
||||
#include <process.h>
|
||||
#include <sysinfoapi.h>
|
||||
|
||||
#include "util/dyn_lib.hpp"
|
||||
|
||||
DYNAMIC_IMPORT_RENAME("Kernel32.dll", SetThreadDescriptionImport, "SetThreadDescription", HRESULT(HANDLE hThread, PCWSTR lpThreadDescription));
|
||||
|
||||
#else
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
@@ -277,8 +283,11 @@ enum x64_op_t : u32
|
||||
X64OP_ADC, // lock adc [mem], ...
|
||||
X64OP_SUB, // lock sub [mem], ...
|
||||
X64OP_SBB, // lock sbb [mem], ...
|
||||
X64OP_BEXTR,
|
||||
};
|
||||
|
||||
static thread_local x64_reg_t s_tls_reg3{};
|
||||
|
||||
void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz& out_size, usz& out_length)
|
||||
{
|
||||
// simple analysis of x64 code allows to reinterpret MOV or other instructions in any desired way
|
||||
@@ -739,10 +748,12 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
|
||||
const u8 vopm = op1 == 0xc5 ? 1 : op2 & 0x1f;
|
||||
const u8 vop1 = op1 == 0xc5 ? op3 : code[2];
|
||||
const u8 vlen = (opx & 0x4) ? 32 : 16;
|
||||
//const u8 vreg = (~opx >> 3) & 0xf;
|
||||
const u8 vreg = (~opx >> 3) & 0xf;
|
||||
out_length += op1 == 0xc5 ? 2 : 3;
|
||||
code += op1 == 0xc5 ? 2 : 3;
|
||||
|
||||
s_tls_reg3 = x64_reg_t{vreg};
|
||||
|
||||
if (vopm == 0x1) switch (vop1) // Implied leading byte 0x0F
|
||||
{
|
||||
case 0x11:
|
||||
@@ -772,6 +783,22 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, usz
|
||||
}
|
||||
}
|
||||
|
||||
if (vopm == 0x2) switch (vop1) // Implied leading bytes 0x0F 0x38
|
||||
{
|
||||
case 0xf7:
|
||||
{
|
||||
if (!repe && !repne && vlen == 16) // BEXTR r32,mem,r32
|
||||
{
|
||||
out_op = X64OP_BEXTR;
|
||||
out_reg = get_modRM_reg_xmm(code, rex);
|
||||
out_size = opx & 0x80 ? 8 : 4;
|
||||
out_length += get_modRM_size(code);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0xc6:
|
||||
@@ -1367,6 +1394,37 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
|
||||
|
||||
break;
|
||||
}
|
||||
case X64OP_BEXTR:
|
||||
{
|
||||
u32 value;
|
||||
if (is_writing || !thread->read_reg(addr, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = stx::se_storage<u32>::swap(value);
|
||||
|
||||
u64 ctrl;
|
||||
if (!get_x64_reg_value(context, s_tls_reg3, d_size, i_size, ctrl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
u8 start = ctrl & 0xff;
|
||||
u8 _len = (ctrl & 0xff00) >> 8;
|
||||
if (_len > 32)
|
||||
_len = 32;
|
||||
if (start > 32)
|
||||
start = 32;
|
||||
value = (u64{value} >> start) & ~(u64{umax} << _len);
|
||||
|
||||
if (!put_x64_reg_value(context, reg, d_size, value) || !set_x64_cmp_flags(context, d_size, value, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case X64OP_STORE:
|
||||
case X64OP_STORE_BE:
|
||||
{
|
||||
@@ -1457,7 +1515,7 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
|
||||
}
|
||||
}
|
||||
|
||||
if (pf_port_id)
|
||||
if (auto pf_port = idm::get<lv2_obj, lv2_event_port>(pf_port_id); pf_port && pf_port->queue)
|
||||
{
|
||||
// We notify the game that a page fault occurred so it can rectify it.
|
||||
// Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed.
|
||||
@@ -1495,21 +1553,34 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
|
||||
}
|
||||
}
|
||||
|
||||
// Deschedule
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
lv2_obj::sleep(*cpu);
|
||||
}
|
||||
|
||||
// Now, place the page fault event onto table so that other functions [sys_mmapper_free_address and pagefault recovery funcs etc]
|
||||
// know that this thread is page faulted and where.
|
||||
|
||||
auto& pf_events = g_fxo->get<page_fault_event_entries>();
|
||||
|
||||
// De-schedule
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
std::lock_guard pf_lock(pf_events.pf_mutex);
|
||||
pf_events.events.emplace(cpu, addr);
|
||||
cpu->state -= cpu_flag::signal; // Cannot use check_state here and signal must be removed if exists
|
||||
lv2_obj::sleep(*cpu);
|
||||
}
|
||||
|
||||
auto send_event = [&]() -> error_code
|
||||
{
|
||||
lv2_obj::notify_all_t notify_later{};
|
||||
|
||||
std::lock_guard pf_lock(pf_events.pf_mutex);
|
||||
|
||||
if (auto error = pf_port->queue->send(pf_port->name ? pf_port->name : ((u64{process_getpid() + 0u} << 32) | u64{pf_port_id}), data1, data2, data3))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
pf_events.events.emplace(cpu, addr);
|
||||
return {};
|
||||
};
|
||||
|
||||
sig_log.warning("Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
|
||||
addr, data3 == SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY ? "writing read-only" : "using unmapped");
|
||||
|
||||
@@ -1521,13 +1592,12 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
|
||||
}
|
||||
}
|
||||
|
||||
error_code sending_error = sys_event_port_send(pf_port_id, data1, data2, data3);
|
||||
error_code sending_error = not_an_error(CELL_EBUSY);
|
||||
|
||||
// If we fail due to being busy, wait a bit and try again.
|
||||
while (static_cast<u32>(sending_error) == CELL_EBUSY)
|
||||
for (; static_cast<u32>(sending_error) == CELL_EBUSY; thread_ctrl::wait_for(1000))
|
||||
{
|
||||
thread_ctrl::wait_for(1000);
|
||||
sending_error = sys_event_port_send(pf_port_id, data1, data2, data3);
|
||||
sending_error = send_event();
|
||||
|
||||
if (cpu->is_stopped())
|
||||
{
|
||||
@@ -1761,7 +1831,11 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
|
||||
|
||||
const bool s_exception_handler_set = []() -> bool
|
||||
{
|
||||
#ifdef USE_ASAN
|
||||
if (!AddVectoredExceptionHandler(FALSE, (PVECTORED_EXCEPTION_HANDLER)exception_handler))
|
||||
#else
|
||||
if (!AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)exception_handler))
|
||||
#endif
|
||||
{
|
||||
report_fatal_error("AddVectoredExceptionHandler() failed.");
|
||||
}
|
||||
@@ -2018,6 +2092,13 @@ void thread_base::initialize(void (*error_cb)())
|
||||
|
||||
void thread_base::set_name(std::string name)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (SetThreadDescriptionImport)
|
||||
{
|
||||
SetThreadDescriptionImport(GetCurrentThread(), utf8_to_wchar(name).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
struct THREADNAME_INFO
|
||||
{
|
||||
@@ -2351,10 +2432,9 @@ void thread_ctrl::wait_for(u64 usec, [[maybe_unused]] bool alert /* true */)
|
||||
{
|
||||
struct itimerspec timeout;
|
||||
u64 missed;
|
||||
u64 nsec = usec * 1000ull;
|
||||
|
||||
timeout.it_value.tv_nsec = (nsec % 1000000000ull);
|
||||
timeout.it_value.tv_sec = nsec / 1000000000ull;
|
||||
timeout.it_value.tv_nsec = usec * 1'000ull;
|
||||
timeout.it_value.tv_sec = 0;
|
||||
timeout.it_interval.tv_sec = 0;
|
||||
timeout.it_interval.tv_nsec = 0;
|
||||
timerfd_settime(fd_timer, 0, &timeout, NULL);
|
||||
@@ -2580,26 +2660,24 @@ void thread_base::exec()
|
||||
while (shared_ptr<thread_future> head = m_taskq.exchange(null_ptr))
|
||||
{
|
||||
// TODO: check if adapting reverse algorithm is feasible here
|
||||
shared_ptr<thread_future>* prev{};
|
||||
thread_future* prev_head{head.get()};
|
||||
|
||||
for (auto ptr = head.get(); ptr; ptr = ptr->next.get())
|
||||
for (thread_future* prev{};;)
|
||||
{
|
||||
utils::prefetch_exec(ptr->exec.load());
|
||||
utils::prefetch_exec(prev_head->exec.load());
|
||||
|
||||
ptr->prev = prev;
|
||||
|
||||
if (ptr->next)
|
||||
if (auto next = prev_head->next.get())
|
||||
{
|
||||
prev = &ptr->next;
|
||||
prev = std::exchange(prev_head, next);
|
||||
prev_head->prev = prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!prev)
|
||||
{
|
||||
prev = &head;
|
||||
}
|
||||
|
||||
for (auto ptr = prev->get(); ptr; ptr = ptr->prev->get())
|
||||
for (auto ptr = prev_head; ptr; ptr = ptr->prev)
|
||||
{
|
||||
if (auto task = ptr->exec.load()) [[likely]]
|
||||
{
|
||||
@@ -2623,11 +2701,6 @@ void thread_base::exec()
|
||||
// Partial cleanup
|
||||
ptr->next.reset();
|
||||
}
|
||||
|
||||
if (!ptr->prev)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_taskq) [[likely]]
|
||||
@@ -2710,7 +2783,7 @@ void thread_ctrl::detect_cpu_layout()
|
||||
if (!GetLogicalProcessorInformationEx(relationship,
|
||||
reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *>(buffer.data()), &buffer_size))
|
||||
{
|
||||
sig_log.error("GetLogicalProcessorInformationEx failed (size=%u, error=%u)", buffer_size, GetLastError());
|
||||
sig_log.error("GetLogicalProcessorInformationEx failed (size=%u, error=%s)", buffer_size, fmt::win_error{GetLastError(), nullptr});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2957,7 +3030,7 @@ void thread_ctrl::set_native_priority(int priority)
|
||||
|
||||
if (!SetThreadPriority(_this_thread, native_priority))
|
||||
{
|
||||
sig_log.error("SetThreadPriority() failed: 0x%x", GetLastError());
|
||||
sig_log.error("SetThreadPriority() failed: %s", fmt::win_error{GetLastError(), nullptr});
|
||||
}
|
||||
#else
|
||||
int policy;
|
||||
@@ -3009,7 +3082,7 @@ void thread_ctrl::set_thread_affinity_mask(u64 mask)
|
||||
HANDLE _this_thread = GetCurrentThread();
|
||||
if (!SetThreadAffinityMask(_this_thread, !mask ? process_affinity_mask : mask))
|
||||
{
|
||||
sig_log.error("Failed to set thread affinity 0x%x: error 0x%x.", mask, GetLastError());
|
||||
sig_log.error("Failed to set thread affinity 0x%x: error: %s", mask, fmt::win_error{GetLastError(), nullptr});
|
||||
}
|
||||
#elif __APPLE__
|
||||
// Supports only one core
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ class thread_future
|
||||
|
||||
shared_ptr<thread_future> next{};
|
||||
|
||||
shared_ptr<thread_future>* prev{};
|
||||
thread_future* prev{};
|
||||
|
||||
protected:
|
||||
atomic_t<void(*)(thread_base*, thread_future*)> exec{};
|
||||
|
||||
+55
-4
@@ -4,6 +4,7 @@
|
||||
#include "version.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/VFS.h"
|
||||
|
||||
#include "util/types.hpp"
|
||||
#include "util/endian.hpp"
|
||||
@@ -76,6 +77,8 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
|
||||
case patch_type::lef32: return "lef32";
|
||||
case patch_type::lef64: return "lef64";
|
||||
case patch_type::utf8: return "utf8";
|
||||
case patch_type::move_file: return "move_file";
|
||||
case patch_type::hide_file: return "hide_file";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
@@ -682,16 +685,17 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!addr_node.Scalar().starts_with("0x"))
|
||||
if (patch_type_uses_hex_offset(type) && !addr_node.Scalar().starts_with("0x"))
|
||||
{
|
||||
append_log_message(log_messages, fmt::format("Skipping patch node %s. Address element has wrong format %s. (key: %s, location: %s)", info.description, addr_node.Scalar(), info.hash, get_yaml_node_location(node)), &patch_log.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct patch_data p_data{};
|
||||
p_data.type = type;
|
||||
p_data.offset = addr_node.as<u32>(0) + modifier;
|
||||
p_data.original_value = value_node.Scalar();
|
||||
p_data.type = type;
|
||||
p_data.offset = addr_node.as<u32>(0) + modifier;
|
||||
p_data.original_offset = addr_node.Scalar();
|
||||
p_data.original_value = value_node.Scalar();
|
||||
|
||||
const bool is_config_value = info.default_config_values.contains(p_data.original_value);
|
||||
const patch_config_value config_value = is_config_value ? ::at32(info.default_config_values, p_data.original_value) : patch_config_value{};
|
||||
@@ -702,6 +706,8 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie
|
||||
{
|
||||
case patch_type::utf8:
|
||||
case patch_type::jump_func:
|
||||
case patch_type::move_file:
|
||||
case patch_type::hide_file:
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1191,6 +1197,51 @@ static usz apply_modification(std::basic_string<u32>& applied, patch_engine::pat
|
||||
std::memcpy(ptr, p.original_value.data(), p.original_value.size());
|
||||
break;
|
||||
}
|
||||
case patch_type::move_file:
|
||||
case patch_type::hide_file:
|
||||
{
|
||||
const bool is_hide = p.type == patch_type::hide_file;
|
||||
std::string original_vfs_path = p.original_offset;
|
||||
std::string dest_vfs_path = p.original_value;
|
||||
|
||||
if (original_vfs_path.empty())
|
||||
{
|
||||
patch_log.error("Failed to patch file: original path is empty", original_vfs_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_hide && dest_vfs_path.empty())
|
||||
{
|
||||
patch_log.error("Failed to patch file: destination path is empty", dest_vfs_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!original_vfs_path.starts_with("/dev_"))
|
||||
{
|
||||
original_vfs_path.insert(0, "/dev_");
|
||||
}
|
||||
|
||||
if (!is_hide && !dest_vfs_path.starts_with("/dev_"))
|
||||
{
|
||||
dest_vfs_path.insert(0, "/dev_");
|
||||
}
|
||||
|
||||
const std::string dest_path = is_hide ? fs::get_config_dir() + "delete_this_dir.../delete_this..." : vfs::get(dest_vfs_path);
|
||||
|
||||
if (dest_path.empty())
|
||||
{
|
||||
patch_log.error("Failed to patch file path at '%s': destination is not mounted", original_vfs_path, dest_vfs_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!vfs::mount(original_vfs_path, dest_path))
|
||||
{
|
||||
patch_log.error("Failed to patch file path at '%s': vfs::mount(dest='%s') failed", original_vfs_path, dest_vfs_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly an executable instruction
|
||||
|
||||
@@ -52,8 +52,15 @@ enum class patch_type
|
||||
bef32,
|
||||
bef64,
|
||||
utf8, // Text of string (not null-terminated automatically)
|
||||
move_file, // Move file
|
||||
hide_file, // Hide file
|
||||
};
|
||||
|
||||
static constexpr bool patch_type_uses_hex_offset(patch_type type)
|
||||
{
|
||||
return type >= patch_type::alloc && type <= patch_type::utf8;
|
||||
}
|
||||
|
||||
enum class patch_configurable_type
|
||||
{
|
||||
double_range,
|
||||
@@ -69,6 +76,7 @@ public:
|
||||
{
|
||||
patch_type type = patch_type::load;
|
||||
u32 offset = 0;
|
||||
std::string original_offset{}; // Used for specifying paths
|
||||
std::string original_value{}; // Used for import consistency (avoid rounding etc.)
|
||||
union
|
||||
{
|
||||
|
||||
+7
-5
@@ -42,6 +42,8 @@ public:
|
||||
// Underlying type
|
||||
using under = std::underlying_type_t<T>;
|
||||
|
||||
ENABLE_BITWISE_SERIALIZATION;
|
||||
|
||||
private:
|
||||
// Underlying value
|
||||
under m_data;
|
||||
@@ -49,7 +51,7 @@ private:
|
||||
friend class atomic_bs_t<T>;
|
||||
|
||||
// Value constructor
|
||||
constexpr explicit bs_t(int, under data)
|
||||
constexpr explicit bs_t(int, under data) noexcept
|
||||
: m_data(data)
|
||||
{
|
||||
}
|
||||
@@ -71,19 +73,19 @@ public:
|
||||
bs_t() = default;
|
||||
|
||||
// Construct from a single bit
|
||||
constexpr bs_t(T bit)
|
||||
constexpr bs_t(T bit) noexcept
|
||||
: m_data(shift(bit))
|
||||
{
|
||||
}
|
||||
|
||||
// Test for empty bitset
|
||||
constexpr explicit operator bool() const
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return m_data != 0;
|
||||
}
|
||||
|
||||
// Extract underlying data
|
||||
constexpr explicit operator under() const
|
||||
constexpr explicit operator under() const noexcept
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
@@ -138,7 +140,7 @@ public:
|
||||
return bs_t(0, lhs.m_data ^ rhs.m_data);
|
||||
}
|
||||
|
||||
constexpr bool operator ==(bs_t rhs) const
|
||||
constexpr bool operator ==(bs_t rhs) const noexcept
|
||||
{
|
||||
return m_data == rhs.m_data;
|
||||
}
|
||||
|
||||
+63
-26
@@ -5,54 +5,81 @@ rXmlNode::rXmlNode()
|
||||
{
|
||||
}
|
||||
|
||||
rXmlNode::rXmlNode(const pugi::xml_node &node)
|
||||
rXmlNode::rXmlNode(const pugi::xml_node& node)
|
||||
{
|
||||
handle = node;
|
||||
}
|
||||
|
||||
std::shared_ptr<rXmlNode> rXmlNode::GetChildren()
|
||||
{
|
||||
// it.begin() returns node_iterator*, *it.begin() return node*.
|
||||
pugi::xml_object_range<pugi::xml_node_iterator> it = handle.children();
|
||||
pugi::xml_node begin = *it.begin();
|
||||
if (handle)
|
||||
{
|
||||
if (const pugi::xml_node child = handle.first_child())
|
||||
{
|
||||
return std::make_shared<rXmlNode>(child);
|
||||
}
|
||||
}
|
||||
|
||||
if (begin)
|
||||
{
|
||||
return std::make_shared<rXmlNode>(begin);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<rXmlNode> rXmlNode::GetNext()
|
||||
{
|
||||
pugi::xml_node result = handle.next_sibling();
|
||||
if (result)
|
||||
if (handle)
|
||||
{
|
||||
return std::make_shared<rXmlNode>(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
if (const pugi::xml_node result = handle.next_sibling())
|
||||
{
|
||||
return std::make_shared<rXmlNode>(result);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string rXmlNode::GetName()
|
||||
{
|
||||
return handle.name();
|
||||
if (handle)
|
||||
{
|
||||
if (const pugi::char_t* name = handle.name())
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string rXmlNode::GetAttribute(const std::string &name)
|
||||
std::string rXmlNode::GetAttribute(const std::string& name)
|
||||
{
|
||||
auto pred = [&name](pugi::xml_attribute attr) { return (name == attr.name()); };
|
||||
return handle.find_attribute(pred).value();
|
||||
if (handle)
|
||||
{
|
||||
const auto pred = [&name](const pugi::xml_attribute& attr) { return (name == attr.name()); };
|
||||
if (const pugi::xml_attribute attr = handle.find_attribute(pred))
|
||||
{
|
||||
if (const pugi::char_t* value = attr.value())
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string rXmlNode::GetNodeContent()
|
||||
{
|
||||
return handle.text().get();
|
||||
if (handle)
|
||||
{
|
||||
if (const pugi::xml_text text = handle.text())
|
||||
{
|
||||
if (const pugi::char_t* value = text.get())
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
rXmlDocument::rXmlDocument()
|
||||
@@ -61,10 +88,20 @@ rXmlDocument::rXmlDocument()
|
||||
|
||||
pugi::xml_parse_result rXmlDocument::Read(const std::string& data)
|
||||
{
|
||||
return handle.load_buffer(data.data(), data.size());
|
||||
if (handle)
|
||||
{
|
||||
return handle.load_buffer(data.data(), data.size());
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<rXmlNode> rXmlDocument::GetRoot()
|
||||
{
|
||||
return std::make_shared<rXmlNode>(handle.root());
|
||||
if (const pugi::xml_node root = handle.root())
|
||||
{
|
||||
return std::make_shared<rXmlNode>(root);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,11 +19,11 @@
|
||||
struct rXmlNode
|
||||
{
|
||||
rXmlNode();
|
||||
rXmlNode(const pugi::xml_node &);
|
||||
rXmlNode(const pugi::xml_node& node);
|
||||
std::shared_ptr<rXmlNode> GetChildren();
|
||||
std::shared_ptr<rXmlNode> GetNext();
|
||||
std::string GetName();
|
||||
std::string GetAttribute(const std::string &name);
|
||||
std::string GetAttribute(const std::string& name);
|
||||
std::string GetNodeContent();
|
||||
|
||||
pugi::xml_node handle{};
|
||||
|
||||
@@ -43,20 +43,6 @@ QLabel#gamelist_icon_background_color {
|
||||
color: rgba(209,209,209,255);
|
||||
}
|
||||
|
||||
/* game grid stylesheet */
|
||||
QTableWidget#game_grid {
|
||||
font-weight:600;
|
||||
font-size:8pt;
|
||||
font-family:Lucida Grande;
|
||||
color: rgba(51,51,51,255);
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:active {
|
||||
selection-background-color: #0078D7;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:!active {
|
||||
selection-background-color: #008cff;
|
||||
}
|
||||
|
||||
/* log stylesheet */
|
||||
QTextEdit#tty_frame {
|
||||
background-color:#ffffff;
|
||||
@@ -131,3 +117,33 @@ QLabel#rsx_debugger_display_buffer {
|
||||
QLabel#l_controller {
|
||||
color:#434343;
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #0078D7;
|
||||
}
|
||||
#game_list_grid_item:hover {
|
||||
background: #008cff;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #0078D7;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
#game_list_grid_item #game_list_grid_item_title_label {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: rgba(51,51,51,255);
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
color: #fff;
|
||||
}
|
||||
#game_list_grid_item[hover="true"] #game_list_grid_item_title_label {
|
||||
color: #fff;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -197,17 +197,6 @@ QLabel#l_controller {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
QTableWidget#game_grid {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: #FFF;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:!active {
|
||||
selection-background-color: #313f4e;
|
||||
}
|
||||
|
||||
/* Slider on toolbar */
|
||||
QWidget#sizeSliderContainer {
|
||||
background: transparent;
|
||||
@@ -344,24 +333,54 @@ QLabel#debugger_frame_pc {
|
||||
/* Tree view changes*/
|
||||
QTreeView::branch:has-children:!has-siblings:closed,
|
||||
QTreeView::branch:closed:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings,
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:has-children:!has-siblings:closed:hover,
|
||||
QTreeView::branch:closed:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings:hover,
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #313f4e;
|
||||
}
|
||||
#game_list_grid_item:hover {
|
||||
background: #313f4e;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #0078D7;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
#game_list_grid_item #game_list_grid_item_title_label {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
background-color: #313f4e;
|
||||
}
|
||||
#game_list_grid_item[hover="true"] #game_list_grid_item_title_label {
|
||||
background-color: #313f4e;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
background-color: #0078D7;
|
||||
}
|
||||
|
||||
+30
-12
@@ -454,7 +454,7 @@ QListWidget::item:selected {
|
||||
}
|
||||
|
||||
QListWidget::item:hover {
|
||||
background-color: #30333a;
|
||||
background-color: #30333a;
|
||||
color: #8cf944;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
@@ -565,7 +565,7 @@ QTableView {
|
||||
}
|
||||
|
||||
QTableView::item:hover {
|
||||
color: #8cf944;
|
||||
color: #8cf944;
|
||||
}
|
||||
|
||||
/* Game Icon Background */
|
||||
@@ -641,24 +641,42 @@ QLabel#debugger_frame_pc {
|
||||
/* Tree view changes*/
|
||||
QTreeView::branch:has-children:!has-siblings:closed,
|
||||
QTreeView::branch:closed:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings,
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:has-children:!has-siblings:closed:hover,
|
||||
QTreeView::branch:closed:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_green.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_green.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings:hover,
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_green.png");
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_green.png");
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #2d3038;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #2d3038;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
background-color: #2d3038;
|
||||
color: #8cf944;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
background-color: #2d3038;
|
||||
color: #8cf944;
|
||||
}
|
||||
|
||||
@@ -249,20 +249,6 @@ QWidget#trophy_notification_frame {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
QTableWidget#game_grid {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
selection-color: #e6e6e6;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:active {
|
||||
selection-background-color: #4c4b4b;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:!active {
|
||||
selection-background-color: #3d3d3d;
|
||||
}
|
||||
|
||||
/* Set Toolbar Slider Size */
|
||||
QSlider#sizeSlider::groove:horizontal {
|
||||
border: 0em solid transparent;
|
||||
@@ -347,24 +333,54 @@ QLabel#tty_text {
|
||||
/* Tree view changes*/
|
||||
QTreeView::branch:has-children:!has-siblings:closed,
|
||||
QTreeView::branch:closed:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings,
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:has-children:!has-siblings:closed:hover,
|
||||
QTreeView::branch:closed:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings:hover,
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #3d3d3d;
|
||||
}
|
||||
#game_list_grid_item:hover {
|
||||
background: #3d3d3d;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #4c4b4b;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
#game_list_grid_item #game_list_grid_item_title_label {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
background-color: #3d3d3d;
|
||||
}
|
||||
#game_list_grid_item[hover="true"] #game_list_grid_item_title_label {
|
||||
background-color: #3d3d3d;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
color: #e6e6e6;
|
||||
background-color: #4c4b4b;
|
||||
}
|
||||
|
||||
@@ -194,17 +194,6 @@ QLabel#l_controller {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
QTableWidget#game_grid {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: #fff;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:!active {
|
||||
selection-background-color: #354454;
|
||||
}
|
||||
|
||||
/* Slider on toolbar */
|
||||
QWidget#sizeSliderContainer {
|
||||
background: transparent;
|
||||
@@ -341,24 +330,54 @@ QLabel#debugger_frame_pc {
|
||||
/* Tree view changes*/
|
||||
QTreeView::branch:has-children:!has-siblings:closed,
|
||||
QTreeView::branch:closed:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings,
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:has-children:!has-siblings:closed:hover,
|
||||
QTreeView::branch:closed:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings:hover,
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #354454;
|
||||
}
|
||||
#game_list_grid_item:hover {
|
||||
background: #354454;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #0078D7;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
#game_list_grid_item #game_list_grid_item_title_label {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
background-color: #354454;
|
||||
}
|
||||
#game_list_grid_item[hover="true"] #game_list_grid_item_title_label {
|
||||
background-color: #354454;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
background-color: #0078D7;
|
||||
}
|
||||
|
||||
@@ -367,21 +367,6 @@ QLabel#l_controller {
|
||||
}
|
||||
|
||||
|
||||
/* Game Grid Font */
|
||||
QTableWidget#game_grid {
|
||||
font-weight: 600;
|
||||
color: #ffd785;
|
||||
text-transform: uppercase;
|
||||
selection-color: #ffd785;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:active {
|
||||
selection-background-color: #4d4940;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:!active {
|
||||
selection-background-color: #615c51;
|
||||
}
|
||||
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
@@ -489,3 +474,33 @@ QWidget#trophy_notification_frame {
|
||||
background-color: #b3ac98;
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #615c51;
|
||||
}
|
||||
#game_list_grid_item:hover {
|
||||
background: #615c51;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #4d4940;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
#game_list_grid_item #game_list_grid_item_title_label {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
color: #ffd785;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
background-color: #615c51;
|
||||
}
|
||||
#game_list_grid_item[hover="true"] #game_list_grid_item_title_label {
|
||||
background-color: #615c51;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
background-color: #4d4940;
|
||||
color: #ffd785;
|
||||
}
|
||||
|
||||
@@ -220,6 +220,17 @@ QScrollBar::up-arrow, QScrollBar::down-arrow, QScrollBar::up-button:vertical, QS
|
||||
border: none;
|
||||
}
|
||||
|
||||
#game_list_grid QScrollBar {
|
||||
width: 10px;
|
||||
height: 3px;
|
||||
}
|
||||
#game_list_grid QScrollBar::handle {
|
||||
background: #1c273d;
|
||||
}
|
||||
#game_list_grid QScrollBar::handle:hover, QScrollBar::handle:pressed {
|
||||
background: #0074e7;
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border: 0.0625em solid #455971;
|
||||
@@ -663,24 +674,49 @@ QLabel#debugger_frame_pc {
|
||||
/* Tree view changes*/
|
||||
QTreeView::branch:has-children:!has-siblings:closed,
|
||||
QTreeView::branch:closed:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings,
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
QTreeView::branch:open:has-children:has-siblings {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_white.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:has-children:!has-siblings:closed:hover,
|
||||
QTreeView::branch:closed:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_blue.png");
|
||||
}
|
||||
|
||||
QTreeView::branch:open:has-children:!has-siblings:hover,
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
QTreeView::branch:open:has-children:has-siblings:hover {
|
||||
border-image: none;
|
||||
image: url("GuiConfigs/list_arrow_down_blue.png");
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #0f1d36;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #0f1d36;
|
||||
}
|
||||
|
||||
#game_list_grid_item #game_list_grid_item_title_label {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
background-color: #0f1d36;
|
||||
color: #2397ff;
|
||||
}
|
||||
#game_list_grid_item[hover="true"] #game_list_grid_item_title_label {
|
||||
color: #2397ff;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
background-color: #0f1d36;
|
||||
color: #2397ff;
|
||||
}
|
||||
|
||||
@@ -678,3 +678,24 @@ QLabel#debugger_frame_pc {
|
||||
color: #000; /* Font Color: Black */
|
||||
background-color: #00ff00; /* Green */
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #4343c1;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #4343c1;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
background-color: #4343c1;
|
||||
color: #FFF;
|
||||
}
|
||||
#game_list_grid_item[hover="true"] #game_list_grid_item_title_label {
|
||||
color: #4343c1;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
background-color: #4343c1;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
@@ -358,14 +358,6 @@ QLabel#l_controller {
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
QTableWidget#game_grid {
|
||||
font-weight: 600;
|
||||
color: #4d4940;
|
||||
text-transform: uppercase;
|
||||
selection-color: #aea993;
|
||||
}
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
@@ -463,3 +455,26 @@ QSlider#sizeSlider::groove:horizontal {
|
||||
QLabel#validLabel {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Game Grid */
|
||||
#game_list_grid_item[selected="true"] {
|
||||
background: #4d4940;
|
||||
}
|
||||
#game_list_grid_item:focus {
|
||||
background: #4d4940;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
#game_list_grid_item #game_list_grid_item_title_label {
|
||||
font-weight: 600;
|
||||
color: #4d4940;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Game Grid hover and focus: we need to handle properties differently when using descendants */
|
||||
#game_list_grid_item[selected="true"] #game_list_grid_item_title_label {
|
||||
color: #aea993;
|
||||
}
|
||||
#game_list_grid_item[focus="true"] #game_list_grid_item_title_label {
|
||||
color: #aea993;
|
||||
}
|
||||
|
||||
@@ -14,56 +14,99 @@
|
||||
<PreprocessorDefinitions>LLVM_AVAILABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Debug'">%(AdditionalLibraryDirectories);..\llvm_build\Debug\lib</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Debug'">%(AdditionalLibraryDirectories);..\3rdparty\llvm\llvm_build\Debug\lib</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);
|
||||
LLVMProfileData.lib;
|
||||
LLVMDebugInfoCodeView.lib;
|
||||
LLVMDebugInfoMSF.lib;
|
||||
LLVMInstrumentation.lib;
|
||||
LLVMMCJIT.lib;
|
||||
LLVMRuntimeDyld.lib;
|
||||
LLVMVectorize.lib;
|
||||
LLVMX86CodeGen.lib;
|
||||
LLVMGlobalISel.lib;
|
||||
LLVMX86Disassembler.lib;
|
||||
LLVMExecutionEngine.lib;
|
||||
LLVMAsmPrinter.lib;
|
||||
LLVMSelectionDAG.lib;
|
||||
LLVMCodeGen.lib;
|
||||
LLVMScalarOpts.lib;
|
||||
LLVMInstCombine.lib;
|
||||
LLVMTransformUtils.lib;
|
||||
LLVMAnalysis.lib;
|
||||
LLVMTarget.lib;
|
||||
LLVMX86Desc.lib;
|
||||
LLVMObject.lib;
|
||||
LLVMMCParser.lib;
|
||||
LLVMBitReader.lib;
|
||||
LLVMCore.lib;
|
||||
LLVMMC.lib;
|
||||
LLVMX86Info.lib;
|
||||
LLVMSupport.lib;
|
||||
LLVMMCDisassembler.lib;
|
||||
LLVMipo.lib;
|
||||
LLVMBinaryFormat.lib;
|
||||
LLVMPasses.lib;
|
||||
LLVMIRReader.lib;
|
||||
LLVMLinker.lib;
|
||||
LLVMAsmParser.lib;
|
||||
LLVMX86AsmParser.lib;
|
||||
LLVMDemangle.lib;
|
||||
LLVMDebugInfoDWARF.lib;
|
||||
LLVMRemarks.lib;
|
||||
LLVMBitstreamReader.lib;
|
||||
LLVMTextAPI.lib;
|
||||
LLVMCFGuard.lib;
|
||||
LLVMAggressiveInstCombine.lib;
|
||||
LLVMBitWriter.lib;
|
||||
LLVMCoroutines.lib;
|
||||
LLVMObjCARCOpts.lib;
|
||||
LLVMIntelJITEvents.lib;
|
||||
LLVMAggressiveInstCombine.lib;
|
||||
LLVMAnalysis.lib;
|
||||
LLVMAsmParser.lib;
|
||||
LLVMAsmPrinter.lib;
|
||||
LLVMBinaryFormat.lib;
|
||||
LLVMBitReader.lib;
|
||||
LLVMBitstreamReader.lib;
|
||||
LLVMBitWriter.lib;
|
||||
LLVMCFGuard.lib;
|
||||
LLVMCFIVerify.lib;
|
||||
LLVMCodeGen.lib;
|
||||
LLVMCore.lib;
|
||||
LLVMCoroutines.lib;
|
||||
LLVMCoverage.lib;
|
||||
LLVMDebugInfoCodeView.lib;
|
||||
LLVMDebuginfod.lib;
|
||||
LLVMDebugInfoDWARF.lib;
|
||||
LLVMDebugInfoGSYM.lib;
|
||||
LLVMDebugInfoLogicalView.lib;
|
||||
LLVMDebugInfoMSF.lib;
|
||||
LLVMDebugInfoPDB.lib;
|
||||
LLVMDemangle.lib;
|
||||
LLVMDiff.lib;
|
||||
LLVMDlltoolDriver.lib;
|
||||
LLVMDWARFLinker.lib;
|
||||
LLVMDWARFLinkerParallel.lib;
|
||||
LLVMDWP.lib;
|
||||
LLVMExecutionEngine.lib;
|
||||
LLVMExegesis.lib;
|
||||
LLVMExegesisX86.lib;
|
||||
LLVMExtensions.lib;
|
||||
LLVMFileCheck.lib;
|
||||
LLVMFrontendHLSL.lib;
|
||||
LLVMFrontendOpenACC.lib;
|
||||
LLVMFrontendOpenMP.lib;
|
||||
LLVMFuzzerCLI.lib;
|
||||
LLVMFuzzMutate.lib;
|
||||
LLVMGlobalISel.lib;
|
||||
LLVMInstCombine.lib;
|
||||
LLVMInstrumentation.lib;
|
||||
LLVMIntelJITEvents.lib;
|
||||
LLVMInterfaceStub.lib;
|
||||
LLVMInterpreter.lib;
|
||||
LLVMipo.lib;
|
||||
LLVMIRPrinter.lib;
|
||||
LLVMIRReader.lib;
|
||||
LLVMJITLink.lib;
|
||||
LLVMLibDriver.lib;
|
||||
LLVMLineEditor.lib;
|
||||
LLVMLinker.lib;
|
||||
LLVMLTO.lib;
|
||||
LLVMMCA.lib;
|
||||
LLVMMCDisassembler.lib;
|
||||
LLVMMCJIT.lib;
|
||||
LLVMMC.lib;
|
||||
LLVMMCParser.lib;
|
||||
LLVMMIRParser.lib;
|
||||
LLVMObjCARCOpts.lib;
|
||||
LLVMObjCopy.lib;
|
||||
LLVMObject.lib;
|
||||
LLVMObjectYAML.lib;
|
||||
LLVMOption.lib;
|
||||
LLVMOrcJIT.lib;
|
||||
LLVMOrcShared.lib;
|
||||
LLVMOrcTargetProcess.lib;
|
||||
LLVMPasses.lib;
|
||||
LLVMProfileData.lib;
|
||||
LLVMRemarks.lib;
|
||||
LLVMRuntimeDyld.lib;
|
||||
LLVMScalarOpts.lib;
|
||||
LLVMSelectionDAG.lib;
|
||||
LLVMSupport.lib;
|
||||
LLVMSymbolize.lib;
|
||||
LLVMTableGenGlobalISel.lib;
|
||||
LLVMTableGen.lib;
|
||||
LLVMTarget.lib;
|
||||
LLVMTargetParser.lib;
|
||||
LLVMTextAPI.lib;
|
||||
LLVMTransformUtils.lib;
|
||||
LLVMVectorize.lib;
|
||||
LLVMWindowsDriver.lib;
|
||||
LLVMWindowsManifest.lib;
|
||||
LLVMX86AsmParser.lib;
|
||||
LLVMX86CodeGen.lib;
|
||||
LLVMX86Desc.lib;
|
||||
LLVMX86Disassembler.lib;
|
||||
LLVMX86Info.lib;
|
||||
LLVMX86TargetMCA.lib;
|
||||
LLVMXRay.lib;
|
||||
</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -15,56 +15,99 @@
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Release'">%(AdditionalLibraryDirectories);..\llvm_build\Release\lib</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)'=='Release'">%(AdditionalLibraryDirectories);..\3rdparty\llvm\llvm_build\Release\lib</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);
|
||||
LLVMProfileData.lib;
|
||||
LLVMDebugInfoCodeView.lib;
|
||||
LLVMDebugInfoMSF.lib;
|
||||
LLVMInstrumentation.lib;
|
||||
LLVMMCJIT.lib;
|
||||
LLVMRuntimeDyld.lib;
|
||||
LLVMVectorize.lib;
|
||||
LLVMX86CodeGen.lib;
|
||||
LLVMGlobalISel.lib;
|
||||
LLVMX86Disassembler.lib;
|
||||
LLVMExecutionEngine.lib;
|
||||
LLVMAsmPrinter.lib;
|
||||
LLVMSelectionDAG.lib;
|
||||
LLVMCodeGen.lib;
|
||||
LLVMScalarOpts.lib;
|
||||
LLVMInstCombine.lib;
|
||||
LLVMTransformUtils.lib;
|
||||
LLVMAnalysis.lib;
|
||||
LLVMTarget.lib;
|
||||
LLVMX86Desc.lib;
|
||||
LLVMObject.lib;
|
||||
LLVMMCParser.lib;
|
||||
LLVMBitReader.lib;
|
||||
LLVMCore.lib;
|
||||
LLVMMC.lib;
|
||||
LLVMX86Info.lib;
|
||||
LLVMSupport.lib;
|
||||
LLVMMCDisassembler.lib;
|
||||
LLVMipo.lib;
|
||||
LLVMBinaryFormat.lib;
|
||||
LLVMPasses.lib;
|
||||
LLVMIRReader.lib;
|
||||
LLVMLinker.lib;
|
||||
LLVMAsmParser.lib;
|
||||
LLVMX86AsmParser.lib;
|
||||
LLVMDemangle.lib;
|
||||
LLVMDebugInfoDWARF.lib;
|
||||
LLVMRemarks.lib;
|
||||
LLVMBitstreamReader.lib;
|
||||
LLVMTextAPI.lib;
|
||||
LLVMCFGuard.lib;
|
||||
LLVMAggressiveInstCombine.lib;
|
||||
LLVMBitWriter.lib;
|
||||
LLVMCoroutines.lib;
|
||||
LLVMObjCARCOpts.lib;
|
||||
LLVMIntelJITEvents.lib;
|
||||
LLVMAggressiveInstCombine.lib;
|
||||
LLVMAnalysis.lib;
|
||||
LLVMAsmParser.lib;
|
||||
LLVMAsmPrinter.lib;
|
||||
LLVMBinaryFormat.lib;
|
||||
LLVMBitReader.lib;
|
||||
LLVMBitstreamReader.lib;
|
||||
LLVMBitWriter.lib;
|
||||
LLVMCFGuard.lib;
|
||||
LLVMCFIVerify.lib;
|
||||
LLVMCodeGen.lib;
|
||||
LLVMCore.lib;
|
||||
LLVMCoroutines.lib;
|
||||
LLVMCoverage.lib;
|
||||
LLVMDebugInfoCodeView.lib;
|
||||
LLVMDebuginfod.lib;
|
||||
LLVMDebugInfoDWARF.lib;
|
||||
LLVMDebugInfoGSYM.lib;
|
||||
LLVMDebugInfoLogicalView.lib;
|
||||
LLVMDebugInfoMSF.lib;
|
||||
LLVMDebugInfoPDB.lib;
|
||||
LLVMDemangle.lib;
|
||||
LLVMDiff.lib;
|
||||
LLVMDlltoolDriver.lib;
|
||||
LLVMDWARFLinker.lib;
|
||||
LLVMDWARFLinkerParallel.lib;
|
||||
LLVMDWP.lib;
|
||||
LLVMExecutionEngine.lib;
|
||||
LLVMExegesis.lib;
|
||||
LLVMExegesisX86.lib;
|
||||
LLVMExtensions.lib;
|
||||
LLVMFileCheck.lib;
|
||||
LLVMFrontendHLSL.lib;
|
||||
LLVMFrontendOpenACC.lib;
|
||||
LLVMFrontendOpenMP.lib;
|
||||
LLVMFuzzerCLI.lib;
|
||||
LLVMFuzzMutate.lib;
|
||||
LLVMGlobalISel.lib;
|
||||
LLVMInstCombine.lib;
|
||||
LLVMInstrumentation.lib;
|
||||
LLVMIntelJITEvents.lib;
|
||||
LLVMInterfaceStub.lib;
|
||||
LLVMInterpreter.lib;
|
||||
LLVMipo.lib;
|
||||
LLVMIRPrinter.lib;
|
||||
LLVMIRReader.lib;
|
||||
LLVMJITLink.lib;
|
||||
LLVMLibDriver.lib;
|
||||
LLVMLineEditor.lib;
|
||||
LLVMLinker.lib;
|
||||
LLVMLTO.lib;
|
||||
LLVMMCA.lib;
|
||||
LLVMMCDisassembler.lib;
|
||||
LLVMMCJIT.lib;
|
||||
LLVMMC.lib;
|
||||
LLVMMCParser.lib;
|
||||
LLVMMIRParser.lib;
|
||||
LLVMObjCARCOpts.lib;
|
||||
LLVMObjCopy.lib;
|
||||
LLVMObject.lib;
|
||||
LLVMObjectYAML.lib;
|
||||
LLVMOption.lib;
|
||||
LLVMOrcJIT.lib;
|
||||
LLVMOrcShared.lib;
|
||||
LLVMOrcTargetProcess.lib;
|
||||
LLVMPasses.lib;
|
||||
LLVMProfileData.lib;
|
||||
LLVMRemarks.lib;
|
||||
LLVMRuntimeDyld.lib;
|
||||
LLVMScalarOpts.lib;
|
||||
LLVMSelectionDAG.lib;
|
||||
LLVMSupport.lib;
|
||||
LLVMSymbolize.lib;
|
||||
LLVMTableGenGlobalISel.lib;
|
||||
LLVMTableGen.lib;
|
||||
LLVMTarget.lib;
|
||||
LLVMTargetParser.lib;
|
||||
LLVMTextAPI.lib;
|
||||
LLVMTransformUtils.lib;
|
||||
LLVMVectorize.lib;
|
||||
LLVMWindowsDriver.lib;
|
||||
LLVMWindowsManifest.lib;
|
||||
LLVMX86AsmParser.lib;
|
||||
LLVMX86CodeGen.lib;
|
||||
LLVMX86Desc.lib;
|
||||
LLVMX86Disassembler.lib;
|
||||
LLVMX86Info.lib;
|
||||
LLVMX86TargetMCA.lib;
|
||||
LLVMXRay.lib;
|
||||
</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
-1
Submodule llvm deleted from 9b52b6c39a
@@ -6,11 +6,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "3rdparty\asmjit\a
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emucore", "rpcs3\emucore.vcxproj", "{C4A10229-4712-4BD2-B63E-50D93C67A038}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3} = {2C902C67-985C-4BE0-94A3-E0FE2EB929A3}
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}
|
||||
{939FE206-1182-ABC3-1234-FEAB88E98404} = {939FE206-1182-ABC3-1234-FEAB88E98404}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm_build", "llvm_build\llvm_build.vcxproj", "{8BC303AB-25BE-4276-8E57-73F171B2D672}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm_build", "3rdparty\llvm\llvm_build\llvm_build.vcxproj", "{8BC303AB-25BE-4276-8E57-73F171B2D672}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLGSRender", "rpcs3\GLGSRender.vcxproj", "{3384223A-6D97-4799-9862-359F85312892}"
|
||||
EndProject
|
||||
@@ -41,6 +42,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml-cpp", "3rdparty\yaml-c
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxproj", "{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3} = {2C902C67-985C-4BE0-94A3-E0FE2EB929A3}
|
||||
{3384223A-6D97-4799-9862-359F85312892} = {3384223A-6D97-4799-9862-359F85312892}
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187} = {349EE8F9-7D25-4909-AAF5-FF3FADE72187}
|
||||
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D} = {3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}
|
||||
@@ -79,7 +81,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spirv", "3rdparty\SPIRV\spi
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdParty", "3rdParty", "{6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm_build_clang_cl", "llvm_build\llvm_build_clang_cl.vcxproj", "{A37E4273-85DB-4217-B775-CE971B87D9DF}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm_build_clang_cl", "3rdparty\llvm\llvm_build\llvm_build_clang_cl.vcxproj", "{A37E4273-85DB-4217-B775-CE971B87D9DF}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cubeb", "rpcs3\Cubeb.vcxproj", "{9610627D-20FE-4B07-8CE3-9FF68A5F1EC2}"
|
||||
EndProject
|
||||
@@ -96,6 +98,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pine", "pine", "{A55DA1B5-C
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc_static", "3rdparty\miniupnp\miniupnpc_static.vcxproj", "{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rtmidi", "3rdparty\rtmidi\rtmidi.vcxproj", "{2C902C67-985C-4BE0-94A3-E0FE2EB929A3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -194,6 +198,10 @@ Global
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Debug|x64.Build.0 = Debug|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.ActiveCfg = Release|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.Build.0 = Release|x64
|
||||
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3}.Debug|x64.Build.0 = Debug|x64
|
||||
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3}.Release|x64.ActiveCfg = Release|x64
|
||||
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -224,6 +232,7 @@ Global
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{A55DA1B5-CC17-4525-BE7F-1659CE17BB56} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{2C902C67-985C-4BE0-94A3-E0FE2EB929A3} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06CC7920-E085-4B81-9582-8DE8AAD42510}
|
||||
|
||||
+39
-27
@@ -1032,8 +1032,8 @@ package_error package_reader::extract_data(std::deque<package_reader>& readers,
|
||||
if (!reader.set_install_path())
|
||||
{
|
||||
error = package_error::other;
|
||||
reader.m_result = result::error;
|
||||
break;
|
||||
reader.m_result = result::error; // We don't know if it's dirty yet.
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1042,41 +1042,52 @@ package_error package_reader::extract_data(std::deque<package_reader>& readers,
|
||||
// Use a seperate map for each reader. We need to check if the target app version exists for each package in sequence.
|
||||
std::map<std::string, install_entry*> all_install_entries;
|
||||
|
||||
if (error == package_error::no_error)
|
||||
if (error != package_error::no_error || num_failures > 0)
|
||||
{
|
||||
// Check if this package is allowed to be installed on top of the existing data
|
||||
error = reader.check_target_app_version();
|
||||
ensure(reader.m_result == result::error || reader.m_result == result::error_dirty);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error == package_error::no_error)
|
||||
{
|
||||
reader.m_result = result::started;
|
||||
// Check if this package is allowed to be installed on top of the existing data
|
||||
error = reader.check_target_app_version();
|
||||
|
||||
// Parse the files to be installed and create all paths.
|
||||
if (!reader.fill_data(all_install_entries))
|
||||
{
|
||||
error = package_error::other;
|
||||
}
|
||||
if (error != package_error::no_error)
|
||||
{
|
||||
reader.m_result = result::error; // We don't know if it's dirty yet.
|
||||
return error;
|
||||
}
|
||||
|
||||
reader.m_result = result::started;
|
||||
|
||||
// Parse the files to be installed and create all paths.
|
||||
if (!reader.fill_data(all_install_entries))
|
||||
{
|
||||
error = package_error::other;
|
||||
// Do not return yet. We may need to clean up down below.
|
||||
}
|
||||
|
||||
reader.m_bufs.resize(std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size()));
|
||||
reader.m_num_failures = error == package_error::no_error ? 0 : 1;
|
||||
|
||||
atomic_t<usz> thread_indexer = 0;
|
||||
|
||||
named_thread_group workers("PKG Installer "sv, std::max<u32>(::narrow<u32>(reader.m_bufs.size()), 1) - 1, [&]()
|
||||
if (reader.m_num_failures == 0)
|
||||
{
|
||||
reader.extract_worker(thread_key{thread_indexer++});
|
||||
});
|
||||
reader.m_bufs.resize(std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size()));
|
||||
|
||||
reader.extract_worker(thread_key{thread_indexer++});
|
||||
workers.join();
|
||||
atomic_t<usz> thread_indexer = 0;
|
||||
|
||||
named_thread_group workers("PKG Installer "sv, std::max<u32>(::narrow<u32>(reader.m_bufs.size()), 1) - 1, [&]()
|
||||
{
|
||||
reader.extract_worker(thread_key{thread_indexer++});
|
||||
});
|
||||
|
||||
reader.extract_worker(thread_key{thread_indexer++});
|
||||
workers.join();
|
||||
|
||||
reader.m_bufs.clear();
|
||||
reader.m_bufs.shrink_to_fit();
|
||||
}
|
||||
|
||||
num_failures += reader.m_num_failures;
|
||||
|
||||
reader.m_bufs.clear();
|
||||
reader.m_bufs.shrink_to_fit();
|
||||
|
||||
// We don't count this package as aborted if all entries were processed.
|
||||
if (reader.m_num_failures || (reader.m_aborted && reader.m_entry_indexer < reader.m_install_entries.size()))
|
||||
{
|
||||
@@ -1099,13 +1110,14 @@ package_error package_reader::extract_data(std::deque<package_reader>& readers,
|
||||
if (reader.m_num_failures)
|
||||
{
|
||||
pkg_log.error("Package failed to install ('%s')", reader.m_install_path);
|
||||
reader.m_result = cleaned ? result::error_cleaned : result::error;
|
||||
reader.m_result = cleaned ? result::error : result::error_dirty;
|
||||
}
|
||||
else
|
||||
{
|
||||
pkg_log.warning("Package installation aborted ('%s')", reader.m_install_path);
|
||||
reader.m_result = cleaned ? result::aborted_cleaned : result::aborted;
|
||||
reader.m_result = cleaned ? result::aborted : result::aborted_dirty;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1121,7 +1133,7 @@ package_error package_reader::extract_data(std::deque<package_reader>& readers,
|
||||
bootable_paths.emplace_back(std::move(reader.m_bootable_file_path));
|
||||
}
|
||||
|
||||
if (num_failures > 0)
|
||||
if (error == package_error::no_error && num_failures > 0)
|
||||
{
|
||||
error = package_error::other;
|
||||
}
|
||||
|
||||
@@ -338,9 +338,9 @@ public:
|
||||
started,
|
||||
success,
|
||||
aborted,
|
||||
aborted_cleaned,
|
||||
aborted_dirty,
|
||||
error,
|
||||
error_cleaned
|
||||
error_dirty
|
||||
};
|
||||
|
||||
bool is_valid() const { return m_is_valid; }
|
||||
|
||||
+121
-123
@@ -192,60 +192,58 @@ void WriteShdr(const fs::file& f, Elf32_Shdr& shdr)
|
||||
}
|
||||
|
||||
|
||||
void AppInfo::Load(const fs::file& f)
|
||||
void program_identification_header::Load(const fs::file& f)
|
||||
{
|
||||
authid = Read64(f);
|
||||
vendor_id = Read32(f);
|
||||
self_type = Read32(f);
|
||||
version = Read64(f);
|
||||
padding = Read64(f);
|
||||
program_authority_id = Read64(f);
|
||||
program_vendor_id = Read32(f);
|
||||
program_type = Read32(f);
|
||||
program_sceversion = Read64(f);
|
||||
padding = Read64(f);
|
||||
}
|
||||
|
||||
void AppInfo::Show() const
|
||||
void program_identification_header::Show() const
|
||||
{
|
||||
self_log.notice("AuthID: 0x%llx", authid);
|
||||
self_log.notice("VendorID: 0x%08x", vendor_id);
|
||||
self_log.notice("SELF type: 0x%08x", self_type);
|
||||
self_log.notice("Version: 0x%llx", version);
|
||||
self_log.notice("AuthID: 0x%llx", program_authority_id);
|
||||
self_log.notice("VendorID: 0x%08x", program_vendor_id);
|
||||
self_log.notice("SELF type: 0x%08x", program_type);
|
||||
self_log.notice("Version: 0x%llx", program_sceversion);
|
||||
}
|
||||
|
||||
void SectionInfo::Load(const fs::file& f)
|
||||
void segment_ext_header::Load(const fs::file& f)
|
||||
{
|
||||
offset = Read64(f);
|
||||
size = Read64(f);
|
||||
compressed = Read32(f);
|
||||
unknown1 = Read32(f);
|
||||
unknown2 = Read32(f);
|
||||
encrypted = Read32(f);
|
||||
offset = Read64(f);
|
||||
size = Read64(f);
|
||||
compression = Read32(f);
|
||||
unknown = Read32(f);
|
||||
encryption = Read64(f);
|
||||
}
|
||||
|
||||
void SectionInfo::Show() const
|
||||
void segment_ext_header::Show() const
|
||||
{
|
||||
self_log.notice("Offset: 0x%llx", offset);
|
||||
self_log.notice("Size: 0x%llx", size);
|
||||
self_log.notice("Compressed: 0x%08x", compressed);
|
||||
self_log.notice("Unknown1: 0x%08x", unknown1);
|
||||
self_log.notice("Unknown2: 0x%08x", unknown2);
|
||||
self_log.notice("Encrypted: 0x%08x", encrypted);
|
||||
self_log.notice("Compression: 0x%08x", compression);
|
||||
self_log.notice("Unknown: 0x%08x", unknown);
|
||||
self_log.notice("Encryption: 0x%08x", encryption);
|
||||
}
|
||||
|
||||
void SCEVersionInfo::Load(const fs::file& f)
|
||||
void version_header::Load(const fs::file& f)
|
||||
{
|
||||
subheader_type = Read32(f);
|
||||
present = Read32(f);
|
||||
size = Read32(f);
|
||||
unknown = Read32(f);
|
||||
unknown4 = Read32(f);
|
||||
}
|
||||
|
||||
void SCEVersionInfo::Show() const
|
||||
void version_header::Show() const
|
||||
{
|
||||
self_log.notice("Sub-header type: 0x%08x", subheader_type);
|
||||
self_log.notice("Present: 0x%08x", present);
|
||||
self_log.notice("Size: 0x%08x", size);
|
||||
self_log.notice("Unknown: 0x%08x", unknown);
|
||||
self_log.notice("Unknown: 0x%08x", unknown4);
|
||||
}
|
||||
|
||||
void ControlInfo::Load(const fs::file& f)
|
||||
void supplemental_header::Load(const fs::file& f)
|
||||
{
|
||||
type = Read32(f);
|
||||
size = Read32(f);
|
||||
@@ -253,45 +251,45 @@ void ControlInfo::Load(const fs::file& f)
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
control_flags.ctrl_flag1 = Read32(f);
|
||||
control_flags.unknown1 = Read32(f);
|
||||
control_flags.unknown2 = Read32(f);
|
||||
control_flags.unknown3 = Read32(f);
|
||||
control_flags.unknown4 = Read32(f);
|
||||
control_flags.unknown5 = Read32(f);
|
||||
control_flags.unknown6 = Read32(f);
|
||||
control_flags.unknown7 = Read32(f);
|
||||
PS3_plaintext_capability_header.ctrl_flag1 = Read32(f);
|
||||
PS3_plaintext_capability_header.unknown1 = Read32(f);
|
||||
PS3_plaintext_capability_header.unknown2 = Read32(f);
|
||||
PS3_plaintext_capability_header.unknown3 = Read32(f);
|
||||
PS3_plaintext_capability_header.unknown4 = Read32(f);
|
||||
PS3_plaintext_capability_header.unknown5 = Read32(f);
|
||||
PS3_plaintext_capability_header.unknown6 = Read32(f);
|
||||
PS3_plaintext_capability_header.unknown7 = Read32(f);
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
if (size == 0x30)
|
||||
{
|
||||
f.read(file_digest_30.digest, 20);
|
||||
file_digest_30.unknown = Read64(f);
|
||||
f.read(PS3_elf_digest_header_30.constant_or_elf_digest, sizeof(PS3_elf_digest_header_30.constant_or_elf_digest));
|
||||
f.read(PS3_elf_digest_header_30.padding, sizeof(PS3_elf_digest_header_30.padding));
|
||||
}
|
||||
else if (size == 0x40)
|
||||
{
|
||||
f.read(file_digest_40.digest1, 20);
|
||||
f.read(file_digest_40.digest2, 20);
|
||||
file_digest_40.unknown = Read64(f);
|
||||
f.read(PS3_elf_digest_header_40.constant, sizeof(PS3_elf_digest_header_40.constant));
|
||||
f.read(PS3_elf_digest_header_40.elf_digest, sizeof(PS3_elf_digest_header_40.elf_digest));
|
||||
PS3_elf_digest_header_40.required_system_version = Read64(f);
|
||||
}
|
||||
}
|
||||
else if (type == 3)
|
||||
{
|
||||
npdrm.magic = Read32(f);
|
||||
npdrm.version = Read32(f);
|
||||
npdrm.license = Read32(f);
|
||||
npdrm.type = Read32(f);
|
||||
f.read(npdrm.content_id, 48);
|
||||
f.read(npdrm.digest, 16);
|
||||
f.read(npdrm.title_hash, 16);
|
||||
f.read(npdrm.dev_hash, 16);
|
||||
npdrm.activate_time = Read64(f);
|
||||
npdrm.expire_time = Read64(f);
|
||||
PS3_npdrm_header.npd.magic = Read32(f);
|
||||
PS3_npdrm_header.npd.version = Read32(f);
|
||||
PS3_npdrm_header.npd.license = Read32(f);
|
||||
PS3_npdrm_header.npd.type = Read32(f);
|
||||
f.read(PS3_npdrm_header.npd.content_id, 48);
|
||||
f.read(PS3_npdrm_header.npd.digest, 16);
|
||||
f.read(PS3_npdrm_header.npd.title_hash, 16);
|
||||
f.read(PS3_npdrm_header.npd.dev_hash, 16);
|
||||
PS3_npdrm_header.npd.activate_time = Read64(f);
|
||||
PS3_npdrm_header.npd.expire_time = Read64(f);
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInfo::Show() const
|
||||
void supplemental_header::Show() const
|
||||
{
|
||||
self_log.notice("Type: 0x%08x", type);
|
||||
self_log.notice("Size: 0x%08x", size);
|
||||
@@ -299,41 +297,41 @@ void ControlInfo::Show() const
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
self_log.notice("Control flag 1: 0x%08x", control_flags.ctrl_flag1);
|
||||
self_log.notice("Unknown1: 0x%08x", control_flags.unknown1);
|
||||
self_log.notice("Unknown2: 0x%08x", control_flags.unknown2);
|
||||
self_log.notice("Unknown3: 0x%08x", control_flags.unknown3);
|
||||
self_log.notice("Unknown4: 0x%08x", control_flags.unknown4);
|
||||
self_log.notice("Unknown5: 0x%08x", control_flags.unknown5);
|
||||
self_log.notice("Unknown6: 0x%08x", control_flags.unknown6);
|
||||
self_log.notice("Unknown7: 0x%08x", control_flags.unknown7);
|
||||
self_log.notice("Control flag 1: 0x%08x", PS3_plaintext_capability_header.ctrl_flag1);
|
||||
self_log.notice("Unknown1: 0x%08x", PS3_plaintext_capability_header.unknown1);
|
||||
self_log.notice("Unknown2: 0x%08x", PS3_plaintext_capability_header.unknown2);
|
||||
self_log.notice("Unknown3: 0x%08x", PS3_plaintext_capability_header.unknown3);
|
||||
self_log.notice("Unknown4: 0x%08x", PS3_plaintext_capability_header.unknown4);
|
||||
self_log.notice("Unknown5: 0x%08x", PS3_plaintext_capability_header.unknown5);
|
||||
self_log.notice("Unknown6: 0x%08x", PS3_plaintext_capability_header.unknown6);
|
||||
self_log.notice("Unknown7: 0x%08x", PS3_plaintext_capability_header.unknown7);
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
if (size == 0x30)
|
||||
{
|
||||
self_log.notice("Digest: %s", file_digest_30.digest);
|
||||
self_log.notice("Unknown: 0x%llx", file_digest_30.unknown);
|
||||
self_log.notice("Digest: %s", PS3_elf_digest_header_30.constant_or_elf_digest);
|
||||
self_log.notice("Unknown: 0x%llx", PS3_elf_digest_header_30.padding);
|
||||
}
|
||||
else if (size == 0x40)
|
||||
{
|
||||
self_log.notice("Digest1: %s", file_digest_40.digest1);
|
||||
self_log.notice("Digest2: %s", file_digest_40.digest2);
|
||||
self_log.notice("Unknown: 0x%llx", file_digest_40.unknown);
|
||||
self_log.notice("Digest1: %s", PS3_elf_digest_header_40.constant);
|
||||
self_log.notice("Digest2: %s", PS3_elf_digest_header_40.elf_digest);
|
||||
self_log.notice("Unknown: 0x%llx", PS3_elf_digest_header_40.required_system_version);
|
||||
}
|
||||
}
|
||||
else if (type == 3)
|
||||
{
|
||||
self_log.notice("Magic: 0x%08x", npdrm.magic);
|
||||
self_log.notice("Version: 0x%08x", npdrm.version);
|
||||
self_log.notice("License: 0x%08x", npdrm.license);
|
||||
self_log.notice("Type: 0x%08x", npdrm.type);
|
||||
self_log.notice("ContentID: %s", npdrm.content_id);
|
||||
self_log.notice("Digest: %s", npdrm.digest);
|
||||
self_log.notice("Inverse digest: %s", npdrm.title_hash);
|
||||
self_log.notice("XOR digest: %s", npdrm.dev_hash);
|
||||
self_log.notice("Activation time: 0x%llx", npdrm.activate_time);
|
||||
self_log.notice("Expiration time: 0x%llx", npdrm.expire_time);
|
||||
self_log.notice("Magic: 0x%08x", PS3_npdrm_header.npd.magic);
|
||||
self_log.notice("Version: 0x%08x", PS3_npdrm_header.npd.version);
|
||||
self_log.notice("License: 0x%08x", PS3_npdrm_header.npd.license);
|
||||
self_log.notice("Type: 0x%08x", PS3_npdrm_header.npd.type);
|
||||
self_log.notice("ContentID: %s", PS3_npdrm_header.npd.content_id);
|
||||
self_log.notice("Digest: %s", PS3_npdrm_header.npd.digest);
|
||||
self_log.notice("Inverse digest: %s", PS3_npdrm_header.npd.title_hash);
|
||||
self_log.notice("XOR digest: %s", PS3_npdrm_header.npd.dev_hash);
|
||||
self_log.notice("Activation time: 0x%llx", PS3_npdrm_header.npd.activate_time);
|
||||
self_log.notice("Expiration time: 0x%llx", PS3_npdrm_header.npd.expire_time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,18 +608,18 @@ void SceHeader::Load(const fs::file& f)
|
||||
se_esize = Read64(f);
|
||||
}
|
||||
|
||||
void SelfHeader::Load(const fs::file& f)
|
||||
void ext_hdr::Load(const fs::file& f)
|
||||
{
|
||||
se_htype = Read64(f);
|
||||
se_appinfooff = Read64(f);
|
||||
se_elfoff = Read64(f);
|
||||
se_phdroff = Read64(f);
|
||||
se_shdroff = Read64(f);
|
||||
se_secinfoff = Read64(f);
|
||||
se_sceveroff = Read64(f);
|
||||
se_controloff = Read64(f);
|
||||
se_controlsize = Read64(f);
|
||||
pad = Read64(f);
|
||||
ext_hdr_version = Read64(f);
|
||||
program_identification_hdr_offset = Read64(f);
|
||||
ehdr_offset = Read64(f);
|
||||
phdr_offset = Read64(f);
|
||||
shdr_offset = Read64(f);
|
||||
segment_ext_hdr_offset = Read64(f);
|
||||
version_hdr_offset = Read64(f);
|
||||
supplemental_hdr_offset = Read64(f);
|
||||
supplemental_hdr_size = Read64(f);
|
||||
padding = Read64(f);
|
||||
}
|
||||
|
||||
SCEDecrypter::SCEDecrypter(const fs::file& s)
|
||||
@@ -683,7 +681,7 @@ bool SCEDecrypter::LoadMetadata(const u8 erk[32], const u8 riv[16])
|
||||
if ((meta_info.key_pad[0] != 0x00) ||
|
||||
(meta_info.iv_pad[0] != 0x00))
|
||||
{
|
||||
self_log.error("Failed to decrypt metadata info!");
|
||||
self_log.error("Failed to decrypt SCE metadata info!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -884,19 +882,19 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
|
||||
}
|
||||
|
||||
// Read SELF header.
|
||||
self_hdr.Load(self_f);
|
||||
m_ext_hdr.Load(self_f);
|
||||
|
||||
// Read the APP INFO.
|
||||
self_f.seek(self_hdr.se_appinfooff);
|
||||
app_info.Load(self_f);
|
||||
self_f.seek(m_ext_hdr.program_identification_hdr_offset);
|
||||
m_prog_id_hdr.Load(self_f);
|
||||
|
||||
if (out_info)
|
||||
{
|
||||
out_info->app_info = app_info;
|
||||
out_info->prog_id_hdr = m_prog_id_hdr;
|
||||
}
|
||||
|
||||
// Read ELF header.
|
||||
self_f.seek(self_hdr.se_elfoff);
|
||||
self_f.seek(m_ext_hdr.ehdr_offset);
|
||||
|
||||
if (isElf32)
|
||||
elf32_hdr.Load(self_f);
|
||||
@@ -912,7 +910,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
|
||||
self_log.error("ELF program header offset is null!");
|
||||
return false;
|
||||
}
|
||||
self_f.seek(self_hdr.se_phdroff);
|
||||
self_f.seek(m_ext_hdr.phdr_offset);
|
||||
for(u32 i = 0; i < elf32_hdr.e_phnum; ++i)
|
||||
{
|
||||
phdr32_arr.emplace_back();
|
||||
@@ -929,7 +927,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
|
||||
return false;
|
||||
}
|
||||
|
||||
self_f.seek(self_hdr.se_phdroff);
|
||||
self_f.seek(m_ext_hdr.phdr_offset);
|
||||
|
||||
for (u32 i = 0; i < elf64_hdr.e_phnum; ++i)
|
||||
{
|
||||
@@ -940,34 +938,34 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
|
||||
|
||||
|
||||
// Read section info.
|
||||
secinfo_arr.clear();
|
||||
self_f.seek(self_hdr.se_secinfoff);
|
||||
m_seg_ext_hdr.clear();
|
||||
self_f.seek(m_ext_hdr.segment_ext_hdr_offset);
|
||||
|
||||
for(u32 i = 0; i < ((isElf32) ? elf32_hdr.e_phnum : elf64_hdr.e_phnum); ++i)
|
||||
{
|
||||
secinfo_arr.emplace_back();
|
||||
secinfo_arr.back().Load(self_f);
|
||||
m_seg_ext_hdr.emplace_back();
|
||||
m_seg_ext_hdr.back().Load(self_f);
|
||||
}
|
||||
|
||||
// Read SCE version info.
|
||||
self_f.seek(self_hdr.se_sceveroff);
|
||||
scev_info.Load(self_f);
|
||||
self_f.seek(m_ext_hdr.version_hdr_offset);
|
||||
m_version_hdr.Load(self_f);
|
||||
|
||||
// Read control info.
|
||||
ctrlinfo_arr.clear();
|
||||
self_f.seek(self_hdr.se_controloff);
|
||||
m_supplemental_hdr_arr.clear();
|
||||
self_f.seek(m_ext_hdr.supplemental_hdr_offset);
|
||||
|
||||
for (u64 i = 0; i < self_hdr.se_controlsize;)
|
||||
for (u64 i = 0; i < m_ext_hdr.supplemental_hdr_size;)
|
||||
{
|
||||
ctrlinfo_arr.emplace_back();
|
||||
ControlInfo &cinfo = ctrlinfo_arr.back();
|
||||
m_supplemental_hdr_arr.emplace_back();
|
||||
supplemental_header& cinfo = m_supplemental_hdr_arr.back();
|
||||
cinfo.Load(self_f);
|
||||
i += cinfo.size;
|
||||
}
|
||||
|
||||
if (out_info)
|
||||
{
|
||||
out_info->ctrl_info = ctrlinfo_arr;
|
||||
out_info->supplemental_hdr = m_supplemental_hdr_arr;
|
||||
}
|
||||
|
||||
// Read ELF section headers.
|
||||
@@ -981,7 +979,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
|
||||
return true;
|
||||
}
|
||||
|
||||
self_f.seek(self_hdr.se_shdroff);
|
||||
self_f.seek(m_ext_hdr.shdr_offset);
|
||||
|
||||
for(u32 i = 0; i < elf32_hdr.e_shnum; ++i)
|
||||
{
|
||||
@@ -998,7 +996,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
|
||||
return true;
|
||||
}
|
||||
|
||||
self_f.seek(self_hdr.se_shdroff);
|
||||
self_f.seek(m_ext_hdr.shdr_offset);
|
||||
|
||||
for(u32 i = 0; i < elf64_hdr.e_shnum; ++i)
|
||||
{
|
||||
@@ -1023,11 +1021,11 @@ void SELFDecrypter::ShowHeaders(bool isElf32)
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_log.notice("SELF header");
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_hdr.Show();
|
||||
m_ext_hdr.Show();
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_log.notice("APP INFO");
|
||||
self_log.notice("----------------------------------------------------");
|
||||
app_info.Show();
|
||||
m_prog_id_hdr.Show();
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_log.notice("ELF header");
|
||||
self_log.notice("----------------------------------------------------");
|
||||
@@ -1040,17 +1038,17 @@ void SELFDecrypter::ShowHeaders(bool isElf32)
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_log.notice("Section info");
|
||||
self_log.notice("----------------------------------------------------");
|
||||
for(unsigned int i = 0; i < secinfo_arr.size(); i++)
|
||||
secinfo_arr[i].Show();
|
||||
for(unsigned int i = 0; i < m_seg_ext_hdr.size(); i++)
|
||||
m_seg_ext_hdr[i].Show();
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_log.notice("SCE version info");
|
||||
self_log.notice("----------------------------------------------------");
|
||||
scev_info.Show();
|
||||
m_version_hdr.Show();
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_log.notice("Control info");
|
||||
self_log.notice("----------------------------------------------------");
|
||||
for(unsigned int i = 0; i < ctrlinfo_arr.size(); i++)
|
||||
ctrlinfo_arr[i].Show();
|
||||
for(unsigned int i = 0; i < m_supplemental_hdr_arr.size(); i++)
|
||||
m_supplemental_hdr_arr[i].Show();
|
||||
self_log.notice("----------------------------------------------------");
|
||||
self_log.notice("ELF section headers");
|
||||
self_log.notice("----------------------------------------------------");
|
||||
@@ -1095,7 +1093,7 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
|
||||
else if (npd->license == 3) // Free license.
|
||||
{
|
||||
// Use klicensee if available.
|
||||
if (key_v.GetKlicenseeKey() != nullptr)
|
||||
if (key_v.GetKlicenseeKey())
|
||||
memcpy(npdrm_key, key_v.GetKlicenseeKey(), 0x10);
|
||||
else
|
||||
memcpy(npdrm_key, NP_KLIC_FREE, 0x10);
|
||||
@@ -1123,11 +1121,11 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
|
||||
const NPD_HEADER* SELFDecrypter::GetNPDHeader() const
|
||||
{
|
||||
// Parse the control info structures to find the NPDRM control info.
|
||||
for (const ControlInfo& info : ctrlinfo_arr)
|
||||
for (const supplemental_header& info : m_supplemental_hdr_arr)
|
||||
{
|
||||
if (info.type == 3)
|
||||
{
|
||||
return &info.npdrm;
|
||||
return &info.PS3_npdrm_header.npd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1150,7 +1148,7 @@ bool SELFDecrypter::LoadMetadata(u8* klic_key)
|
||||
self_f.read(metadata_headers.get(), metadata_headers_size);
|
||||
|
||||
// Find the right keyset from the key vault.
|
||||
SELF_KEY keyset = key_v.FindSelfKey(app_info.self_type, sce_hdr.se_flags, app_info.version);
|
||||
SELF_KEY keyset = key_v.FindSelfKey(m_prog_id_hdr.program_type, sce_hdr.se_flags, m_prog_id_hdr.program_sceversion);
|
||||
|
||||
// Set klic if given
|
||||
if (klic_key)
|
||||
@@ -1182,7 +1180,7 @@ bool SELFDecrypter::LoadMetadata(u8* klic_key)
|
||||
if ((meta_info.key_pad[0] != 0x00) ||
|
||||
(meta_info.iv_pad[0] != 0x00))
|
||||
{
|
||||
self_log.error("Failed to decrypt metadata info!");
|
||||
self_log.error("Failed to decrypt SELF metadata info!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1333,15 +1331,15 @@ static bool IsSelfElf32(const fs::file& f)
|
||||
|
||||
f.seek(0);
|
||||
|
||||
SceHeader hdr;
|
||||
SelfHeader sh;
|
||||
SceHeader hdr{};
|
||||
ext_hdr sh{};
|
||||
hdr.Load(f);
|
||||
sh.Load(f);
|
||||
|
||||
// Locate the class byte and check it.
|
||||
u8 elf_class[0x8];
|
||||
|
||||
f.seek(sh.se_elfoff);
|
||||
f.seek(sh.ehdr_offset);
|
||||
f.read(elf_class, 0x8);
|
||||
|
||||
return (elf_class[4] == 1);
|
||||
|
||||
+184
-121
@@ -11,52 +11,113 @@
|
||||
|
||||
LOG_CHANNEL(self_log, "SELF");
|
||||
|
||||
struct AppInfo
|
||||
// SCE-specific definitions for e_type:
|
||||
enum
|
||||
{
|
||||
u64 authid;
|
||||
u32 vendor_id;
|
||||
u32 self_type;
|
||||
u64 version;
|
||||
ET_SCE_EXEC = 0xFE00, // SCE Executable - PRX2
|
||||
ET_SCE_RELEXEC = 0xFE04, // SCE Relocatable Executable - PRX2
|
||||
ET_SCE_STUBLIB = 0xFE0C, // SCE SDK Stubs
|
||||
ET_SCE_DYNEXEC = 0xFE10, // SCE EXEC_ASLR (PS4 Executable with ASLR)
|
||||
ET_SCE_DYNAMIC = 0xFE18, // ?
|
||||
ET_SCE_IOPRELEXEC = 0xFF80, // SCE IOP Relocatable Executable
|
||||
ET_SCE_IOPRELEXEC2 = 0xFF81, // SCE IOP Relocatable Executable Version 2
|
||||
ET_SCE_EERELEXEC = 0xFF90, // SCE EE Relocatable Executable
|
||||
ET_SCE_EERELEXEC2 = 0xFF91, // SCE EE Relocatable Executable Version 2
|
||||
ET_SCE_PSPRELEXEC = 0xFFA0, // SCE PSP Relocatable Executable
|
||||
ET_SCE_PPURELEXEC = 0xFFA4, // SCE PPU Relocatable Executable
|
||||
ET_SCE_ARMRELEXEC = 0xFFA5, // ?SCE ARM Relocatable Executable (PS Vita System Software earlier or equal 0.931.010)
|
||||
ET_SCE_PSPOVERLAY = 0xFFA8, // ?
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ELFOSABI_CELL_LV2 = 102 // CELL LV2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PT_SCE_RELA = 0x60000000,
|
||||
PT_SCE_LICINFO_1 = 0x60000001,
|
||||
PT_SCE_LICINFO_2 = 0x60000002,
|
||||
PT_SCE_DYNLIBDATA = 0x61000000,
|
||||
PT_SCE_PROCPARAM = 0x61000001,
|
||||
PT_SCE_UNK_61000010 = 0x61000010,
|
||||
PT_SCE_COMMENT = 0x6FFFFF00,
|
||||
PT_SCE_LIBVERSION = 0x6FFFFF01,
|
||||
PT_SCE_UNK_70000001 = 0x70000001,
|
||||
PT_SCE_IOPMOD = 0x70000080,
|
||||
PT_SCE_EEMOD = 0x70000090,
|
||||
PT_SCE_PSPRELA = 0x700000A0,
|
||||
PT_SCE_PSPRELA2 = 0x700000A1,
|
||||
PT_SCE_PPURELA = 0x700000A4,
|
||||
PT_SCE_SEGSYM = 0x700000A8,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PF_SPU_X = 0x00100000,
|
||||
PF_SPU_W = 0x00200000,
|
||||
PF_SPU_R = 0x00400000,
|
||||
PF_RSX_X = 0x01000000,
|
||||
PF_RSX_W = 0x02000000,
|
||||
PF_RSX_R = 0x04000000,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SHT_SCE_RELA = 0x60000000,
|
||||
SHT_SCE_NID = 0x61000001,
|
||||
SHT_SCE_IOPMOD = 0x70000080,
|
||||
SHT_SCE_EEMOD = 0x70000090,
|
||||
SHT_SCE_PSPRELA = 0x700000A0,
|
||||
SHT_SCE_PPURELA = 0x700000A4,
|
||||
};
|
||||
|
||||
struct program_identification_header
|
||||
{
|
||||
u64 program_authority_id;
|
||||
u32 program_vendor_id;
|
||||
u32 program_type;
|
||||
u64 program_sceversion;
|
||||
u64 padding;
|
||||
|
||||
void Load(const fs::file& f);
|
||||
void Show() const;
|
||||
};
|
||||
|
||||
struct SectionInfo
|
||||
struct segment_ext_header
|
||||
{
|
||||
u64 offset;
|
||||
u64 size;
|
||||
u32 compressed;
|
||||
u32 unknown1;
|
||||
u32 unknown2;
|
||||
u32 encrypted;
|
||||
u64 offset; // Offset to data
|
||||
u64 size; // Size of data
|
||||
u32 compression; // 1 = plain, 2 = zlib
|
||||
u32 unknown; // Always 0, as far as I know.
|
||||
u64 encryption; // 0 = unrequested, 1 = completed, 2 = requested
|
||||
|
||||
void Load(const fs::file& f);
|
||||
void Show() const;
|
||||
};
|
||||
|
||||
struct SCEVersionInfo
|
||||
struct version_header
|
||||
{
|
||||
u32 subheader_type;
|
||||
u32 present;
|
||||
u32 size;
|
||||
u32 unknown;
|
||||
u32 subheader_type; // 1 - sceversion
|
||||
u32 present; // 0 = false, 1 = true
|
||||
u32 size; // usually 0x10
|
||||
u32 unknown4;
|
||||
|
||||
void Load(const fs::file& f);
|
||||
void Show() const;
|
||||
};
|
||||
|
||||
struct ControlInfo
|
||||
struct supplemental_header
|
||||
{
|
||||
u32 type;
|
||||
u32 type; // 1=PS3 plaintext_capability; 2=PS3 ELF digest; 3=PS3 NPDRM, 4=PS Vita ELF digest; 5=PS Vita NPDRM; 6=PS Vita boot param; 7=PS Vita shared secret
|
||||
u32 size;
|
||||
u64 next;
|
||||
u64 next; // 1 if another Supplemental Header element follows else 0
|
||||
|
||||
union
|
||||
{
|
||||
// type 1 0x30 bytes
|
||||
struct
|
||||
// type 1, 0x30 bytes
|
||||
struct // 0x20 bytes of data
|
||||
{
|
||||
u32 ctrl_flag1;
|
||||
u32 unknown1;
|
||||
@@ -66,28 +127,28 @@ struct ControlInfo
|
||||
u32 unknown5;
|
||||
u32 unknown6;
|
||||
u32 unknown7;
|
||||
} PS3_plaintext_capability_header;
|
||||
|
||||
} control_flags;
|
||||
|
||||
// type 2 0x30 bytes
|
||||
struct
|
||||
// type 2, 0x40 bytes
|
||||
struct // 0x30 bytes of data
|
||||
{
|
||||
u8 digest[20];
|
||||
u64 unknown;
|
||||
u8 constant[0x14]; // same for every PS3/PS Vita SELF, hardcoded in make_fself.exe: 627CB1808AB938E32C8C091708726A579E2586E4
|
||||
u8 elf_digest[0x14]; // SHA-1. Hash F2C552BF716ED24759CBE8A0A9A6DB9965F3811C is blacklisted by appldr
|
||||
u64 required_system_version; // filled on Sony authentication server, contains decimal PS3_SYSTEM_VER value from PARAM.SFO
|
||||
} PS3_elf_digest_header_40;
|
||||
|
||||
} file_digest_30;
|
||||
|
||||
// type 2 0x40 bytes
|
||||
struct
|
||||
// type 2, 0x30 bytes
|
||||
struct // 0x20 bytes of data
|
||||
{
|
||||
u8 digest1[20];
|
||||
u8 digest2[20];
|
||||
u64 unknown;
|
||||
u8 constant_or_elf_digest[0x14];
|
||||
u8 padding[0xC];
|
||||
} PS3_elf_digest_header_30;
|
||||
|
||||
} file_digest_40;
|
||||
|
||||
// type 3 0x90 bytes
|
||||
NPD_HEADER npdrm;
|
||||
// type 3, 0x90 bytes
|
||||
struct // 0x80 bytes of data
|
||||
{
|
||||
NPD_HEADER npd;
|
||||
} PS3_npdrm_header;
|
||||
};
|
||||
|
||||
void Load(const fs::file& f);
|
||||
@@ -172,7 +233,7 @@ struct Signature
|
||||
|
||||
struct SelfSection
|
||||
{
|
||||
u8 *data;
|
||||
u8* data;
|
||||
u64 size;
|
||||
u64 offset;
|
||||
|
||||
@@ -181,25 +242,26 @@ struct SelfSection
|
||||
|
||||
struct Elf32_Ehdr
|
||||
{
|
||||
//u8 e_ident[16]; // ELF identification
|
||||
u32 e_magic;
|
||||
u8 e_class;
|
||||
u8 e_data;
|
||||
u8 e_curver;
|
||||
u8 e_os_abi;
|
||||
u64 e_abi_ver;
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u32 e_entry;
|
||||
u32 e_phoff;
|
||||
u32 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
u16 e_type; // object file type
|
||||
u16 e_machine; // machine type
|
||||
u32 e_version; // object file version
|
||||
u32 e_entry; // entry point address
|
||||
u32 e_phoff; // program header offset
|
||||
u32 e_shoff; // section header offset
|
||||
u32 e_flags; // processor-specific flags
|
||||
u16 e_ehsize; // ELF header size
|
||||
u16 e_phentsize; // size of program header entry
|
||||
u16 e_phnum; // number of program header entries
|
||||
u16 e_shentsize; // size of section header entry
|
||||
u16 e_shnum; // number of section header entries
|
||||
u16 e_shstrndx; // section name string table index
|
||||
|
||||
void Load(const fs::file& f);
|
||||
static void Show() {}
|
||||
@@ -210,16 +272,16 @@ struct Elf32_Ehdr
|
||||
|
||||
struct Elf32_Shdr
|
||||
{
|
||||
u32 sh_name;
|
||||
u32 sh_type;
|
||||
u32 sh_flags;
|
||||
u32 sh_addr;
|
||||
u32 sh_offset;
|
||||
u32 sh_size;
|
||||
u32 sh_link;
|
||||
u32 sh_info;
|
||||
u32 sh_addralign;
|
||||
u32 sh_entsize;
|
||||
u32 sh_name; // section name
|
||||
u32 sh_type; // section type
|
||||
u32 sh_flags; // section attributes
|
||||
u32 sh_addr; // virtual address in memory
|
||||
u32 sh_offset; // offset in file
|
||||
u32 sh_size; // size of section
|
||||
u32 sh_link; // link to other section
|
||||
u32 sh_info; // miscellaneous information
|
||||
u32 sh_addralign; // address alignment boundary
|
||||
u32 sh_entsize; // size of entries, if section has table
|
||||
|
||||
void Load(const fs::file& f);
|
||||
void LoadLE(const fs::file& f);
|
||||
@@ -228,14 +290,14 @@ struct Elf32_Shdr
|
||||
|
||||
struct Elf32_Phdr
|
||||
{
|
||||
u32 p_type;
|
||||
u32 p_offset;
|
||||
u32 p_vaddr;
|
||||
u32 p_paddr;
|
||||
u32 p_filesz;
|
||||
u32 p_memsz;
|
||||
u32 p_flags;
|
||||
u32 p_align;
|
||||
u32 p_type; // Segment type
|
||||
u32 p_offset; // Segment file offset
|
||||
u32 p_vaddr; // Segment virtual address
|
||||
u32 p_paddr; // Segment physical address
|
||||
u32 p_filesz; // Segment size in file
|
||||
u32 p_memsz; // Segment size in memory
|
||||
u32 p_flags; // Segment flags
|
||||
u32 p_align; // Segment alignment
|
||||
|
||||
void Load(const fs::file& f);
|
||||
void LoadLE(const fs::file& f);
|
||||
@@ -244,25 +306,26 @@ struct Elf32_Phdr
|
||||
|
||||
struct Elf64_Ehdr
|
||||
{
|
||||
//u8 e_ident[16]; // ELF identification
|
||||
u32 e_magic;
|
||||
u8 e_class;
|
||||
u8 e_data;
|
||||
u8 e_curver;
|
||||
u8 e_os_abi;
|
||||
u64 e_abi_ver;
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u64 e_entry;
|
||||
u64 e_phoff;
|
||||
u64 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
u16 e_type; // object file type
|
||||
u16 e_machine; // machine type
|
||||
u32 e_version; // object file version
|
||||
u64 e_entry; // entry point address
|
||||
u64 e_phoff; // program header offset
|
||||
u64 e_shoff; // section header offset
|
||||
u32 e_flags; // processor-specific flags
|
||||
u16 e_ehsize; // ELF header size
|
||||
u16 e_phentsize; // size of program header entry
|
||||
u16 e_phnum; // number of program header entries
|
||||
u16 e_shentsize; // size of section header entry
|
||||
u16 e_shnum; // number of section header entries
|
||||
u16 e_shstrndx; // section name string table index
|
||||
|
||||
void Load(const fs::file& f);
|
||||
static void Show() {}
|
||||
@@ -272,16 +335,16 @@ struct Elf64_Ehdr
|
||||
|
||||
struct Elf64_Shdr
|
||||
{
|
||||
u32 sh_name;
|
||||
u32 sh_type;
|
||||
u64 sh_flags;
|
||||
u64 sh_addr;
|
||||
u64 sh_offset;
|
||||
u64 sh_size;
|
||||
u32 sh_link;
|
||||
u32 sh_info;
|
||||
u64 sh_addralign;
|
||||
u64 sh_entsize;
|
||||
u32 sh_name; // section name
|
||||
u32 sh_type; // section type
|
||||
u64 sh_flags; // section attributes
|
||||
u64 sh_addr; // virtual address in memory
|
||||
u64 sh_offset; // offset in file
|
||||
u64 sh_size; // size of section
|
||||
u32 sh_link; // link to other section
|
||||
u32 sh_info; // miscellaneous information
|
||||
u64 sh_addralign; // address alignment boundary
|
||||
u64 sh_entsize; // size of entries, if section has table
|
||||
|
||||
void Load(const fs::file& f);
|
||||
static void Show(){}
|
||||
@@ -289,14 +352,14 @@ struct Elf64_Shdr
|
||||
|
||||
struct Elf64_Phdr
|
||||
{
|
||||
u32 p_type;
|
||||
u32 p_flags;
|
||||
u64 p_offset;
|
||||
u64 p_vaddr;
|
||||
u64 p_paddr;
|
||||
u64 p_filesz;
|
||||
u64 p_memsz;
|
||||
u64 p_align;
|
||||
u32 p_type; // Segment type
|
||||
u32 p_flags; // Segment flags
|
||||
u64 p_offset; // Segment file offset
|
||||
u64 p_vaddr; // Segment virtual address
|
||||
u64 p_paddr; // Segment physical address
|
||||
u64 p_filesz; // Segment size in file
|
||||
u64 p_memsz; // Segment size in memory
|
||||
u64 p_align; // Segment alignment
|
||||
|
||||
void Load(const fs::file& f);
|
||||
static void Show(){}
|
||||
@@ -317,18 +380,18 @@ struct SceHeader
|
||||
bool CheckMagic() const { return se_magic == 0x53434500; }
|
||||
};
|
||||
|
||||
struct SelfHeader
|
||||
struct ext_hdr
|
||||
{
|
||||
u64 se_htype;
|
||||
u64 se_appinfooff;
|
||||
u64 se_elfoff;
|
||||
u64 se_phdroff;
|
||||
u64 se_shdroff;
|
||||
u64 se_secinfoff;
|
||||
u64 se_sceveroff;
|
||||
u64 se_controloff;
|
||||
u64 se_controlsize;
|
||||
u64 pad;
|
||||
u64 ext_hdr_version;
|
||||
u64 program_identification_hdr_offset;
|
||||
u64 ehdr_offset;
|
||||
u64 phdr_offset;
|
||||
u64 shdr_offset;
|
||||
u64 segment_ext_hdr_offset;
|
||||
u64 version_hdr_offset;
|
||||
u64 supplemental_hdr_offset;
|
||||
u64 supplemental_hdr_size;
|
||||
u64 padding;
|
||||
|
||||
void Load(const fs::file& f);
|
||||
static void Show(){}
|
||||
@@ -337,8 +400,8 @@ struct SelfHeader
|
||||
struct SelfAdditionalInfo
|
||||
{
|
||||
bool valid = false;
|
||||
std::vector<ControlInfo> ctrl_info;
|
||||
AppInfo app_info;
|
||||
std::vector<supplemental_header> supplemental_hdr;
|
||||
program_identification_header prog_id_hdr;
|
||||
};
|
||||
|
||||
class SCEDecrypter
|
||||
@@ -376,8 +439,8 @@ class SELFDecrypter
|
||||
|
||||
// SCE, SELF and APP headers.
|
||||
SceHeader sce_hdr{};
|
||||
SelfHeader self_hdr{};
|
||||
AppInfo app_info{};
|
||||
ext_hdr m_ext_hdr{};
|
||||
program_identification_header m_prog_id_hdr{};
|
||||
|
||||
// ELF64 header and program header/section header arrays.
|
||||
Elf64_Ehdr elf64_hdr{};
|
||||
@@ -390,9 +453,9 @@ class SELFDecrypter
|
||||
std::vector<Elf32_Phdr> phdr32_arr{};
|
||||
|
||||
// Decryption info structs.
|
||||
std::vector<SectionInfo> secinfo_arr{};
|
||||
SCEVersionInfo scev_info{};
|
||||
std::vector<ControlInfo> ctrlinfo_arr{};
|
||||
std::vector<segment_ext_header> m_seg_ext_hdr{};
|
||||
version_header m_version_hdr{};
|
||||
std::vector<supplemental_header> m_supplemental_hdr_arr{};
|
||||
|
||||
// Metadata structs.
|
||||
MetadataInfo meta_info{};
|
||||
@@ -484,7 +547,7 @@ private:
|
||||
}
|
||||
|
||||
// Write section headers.
|
||||
if (self_hdr.se_shdroff != 0)
|
||||
if (m_ext_hdr.shdr_offset != 0)
|
||||
{
|
||||
e.seek(ehdr.e_shoff);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
add_library(rpcs3_emu
|
||||
cache_utils.cpp
|
||||
games_config.cpp
|
||||
IdManager.cpp
|
||||
localized_string.cpp
|
||||
savestate_utils.cpp
|
||||
@@ -392,15 +393,24 @@ target_sources(rpcs3_emu PRIVATE
|
||||
Io/pad_config.cpp
|
||||
Io/pad_config_types.cpp
|
||||
Io/PadHandler.cpp
|
||||
Io/pad_types.cpp
|
||||
Io/usb_device.cpp
|
||||
Io/usb_vfs.cpp
|
||||
Io/Infinity.cpp
|
||||
Io/Skylander.cpp
|
||||
Io/GHLtar.cpp
|
||||
Io/midi_config_types.cpp
|
||||
Io/RB3MidiKeyboard.cpp
|
||||
Io/RB3MidiGuitar.cpp
|
||||
Io/Buzz.cpp
|
||||
Io/Turntable.cpp
|
||||
Io/usio.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(rpcs3_emu PRIVATE
|
||||
3rdparty::rtmidi
|
||||
)
|
||||
|
||||
# Np
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
NP/fb_helpers.cpp
|
||||
@@ -465,7 +475,7 @@ target_sources(rpcs3_emu PRIVATE
|
||||
RSX/Overlays/overlay_perf_metrics.cpp
|
||||
RSX/Overlays/overlay_progress_bar.cpp
|
||||
RSX/Overlays/overlay_save_dialog.cpp
|
||||
RSX/Overlays/overlay_shader_compile_notification.cpp
|
||||
RSX/Overlays/overlay_compile_notification.cpp
|
||||
RSX/Overlays/overlay_user_list_dialog.cpp
|
||||
RSX/Overlays/overlay_utils.cpp
|
||||
RSX/Overlays/overlays.cpp
|
||||
|
||||
@@ -35,6 +35,7 @@ static thread_local u32 s_tls_thread_slot = -1;
|
||||
static thread_local u64 s_tls_sctr = -1;
|
||||
|
||||
extern thread_local void(*g_tls_log_control)(const char* fmt, u64 progress);
|
||||
extern thread_local std::string(*g_tls_log_prefix)();
|
||||
|
||||
template <>
|
||||
void fmt_class_string<cpu_flag>::format(std::string& out, u64 arg)
|
||||
@@ -478,6 +479,8 @@ namespace cpu_counter
|
||||
|
||||
void cpu_thread::operator()()
|
||||
{
|
||||
const auto old_prefix = g_tls_log_prefix;
|
||||
|
||||
g_tls_this_thread = this;
|
||||
|
||||
if (g_cfg.core.thread_scheduler != thread_scheduler_mode::os)
|
||||
@@ -545,6 +548,7 @@ void cpu_thread::operator()()
|
||||
{
|
||||
cpu_thread* _this = nullptr;
|
||||
std::string name;
|
||||
std::string(*log_prefix)() = nullptr;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
@@ -571,6 +575,8 @@ void cpu_thread::operator()()
|
||||
|
||||
s_cpu_counter--;
|
||||
|
||||
g_tls_log_prefix = log_prefix;
|
||||
|
||||
g_tls_this_thread = nullptr;
|
||||
|
||||
g_threads_deleted++;
|
||||
@@ -590,6 +596,7 @@ void cpu_thread::operator()()
|
||||
|
||||
cleanup._this = this;
|
||||
cleanup.name = thread_ctrl::get_name();
|
||||
cleanup.log_prefix = old_prefix;
|
||||
|
||||
// Check thread status
|
||||
while (!(state & cpu_flag::exit) && thread_ctrl::state() != thread_state::aborting)
|
||||
|
||||
@@ -75,6 +75,14 @@ cpu_translator::cpu_translator(llvm::Module* _module, bool is_be)
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
register_intrinsic("any_select_by_bit4", [&](llvm::CallInst* ci) -> llvm::Value*
|
||||
{
|
||||
const auto s = bitcast<s8[16]>(m_ir->CreateShl(bitcast<u64[2]>(ci->getOperand(0)), 3));;
|
||||
const auto a = bitcast<u8[16]>(ci->getOperand(1));
|
||||
const auto b = bitcast<u8[16]>(ci->getOperand(2));
|
||||
return m_ir->CreateSelect(m_ir->CreateICmpSLT(s, llvm::ConstantAggregateZero::get(get_type<s8[16]>())), b, a);
|
||||
});
|
||||
}
|
||||
|
||||
void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngine& engine)
|
||||
@@ -112,10 +120,14 @@ void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngin
|
||||
cpu == "broadwell" ||
|
||||
cpu == "skylake" ||
|
||||
cpu == "alderlake" ||
|
||||
cpu == "raptorlake" ||
|
||||
cpu == "meteorlake" ||
|
||||
cpu == "bdver2" ||
|
||||
cpu == "bdver3" ||
|
||||
cpu == "bdver4" ||
|
||||
cpu.startswith("znver"))
|
||||
cpu == "znver1" ||
|
||||
cpu == "znver2" ||
|
||||
cpu == "znver3")
|
||||
{
|
||||
m_use_fma = true;
|
||||
m_use_avx = true;
|
||||
@@ -135,7 +147,9 @@ void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngin
|
||||
// Test VNNI feature (TODO)
|
||||
if (cpu == "cascadelake" ||
|
||||
cpu == "cooperlake" ||
|
||||
cpu == "alderlake")
|
||||
cpu == "alderlake" ||
|
||||
cpu == "raptorlake" ||
|
||||
cpu == "meteorlake")
|
||||
{
|
||||
m_use_vnni = true;
|
||||
}
|
||||
@@ -146,7 +160,8 @@ void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngin
|
||||
cpu == "icelake-server" ||
|
||||
cpu == "tigerlake" ||
|
||||
cpu == "rocketlake" ||
|
||||
cpu == "sapphirerapids")
|
||||
cpu == "sapphirerapids" ||
|
||||
(cpu.startswith("znver") && cpu != "znver1" && cpu != "znver2" && cpu != "znver3"))
|
||||
{
|
||||
m_use_avx = true;
|
||||
m_use_fma = true;
|
||||
@@ -299,7 +314,7 @@ llvm::Constant* cpu_translator::make_const_vector<v128>(v128 v, llvm::Type* t, u
|
||||
{
|
||||
if (const auto ct = llvm::dyn_cast<llvm::IntegerType>(t); ct && ct->getBitWidth() == 128)
|
||||
{
|
||||
return llvm::ConstantInt::get(t, llvm::APInt(128, llvm::makeArrayRef(reinterpret_cast<const u64*>(v._bytes), 2)));
|
||||
return llvm::ConstantInt::get(t, llvm::APInt(128, llvm::ArrayRef(reinterpret_cast<const u64*>(v._bytes), 2)));
|
||||
}
|
||||
|
||||
ensure(t->isVectorTy());
|
||||
@@ -309,27 +324,27 @@ llvm::Constant* cpu_translator::make_const_vector<v128>(v128 v, llvm::Type* t, u
|
||||
|
||||
if (sct->isIntegerTy(8))
|
||||
{
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u8*>(v._bytes), 16));
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u8*>(v._bytes), 16));
|
||||
}
|
||||
if (sct->isIntegerTy(16))
|
||||
{
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u16*>(v._bytes), 8));
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u16*>(v._bytes), 8));
|
||||
}
|
||||
if (sct->isIntegerTy(32))
|
||||
{
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u32*>(v._bytes), 4));
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u32*>(v._bytes), 4));
|
||||
}
|
||||
if (sct->isIntegerTy(64))
|
||||
{
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u64*>(v._bytes), 2));
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u64*>(v._bytes), 2));
|
||||
}
|
||||
if (sct->isFloatTy())
|
||||
{
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const f32*>(v._bytes), 4));
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const f32*>(v._bytes), 4));
|
||||
}
|
||||
if (sct->isDoubleTy())
|
||||
{
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const f64*>(v._bytes), 2));
|
||||
return llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const f64*>(v._bytes), 2));
|
||||
}
|
||||
|
||||
fmt::throw_exception("[line %u] No supported constant type", _line);
|
||||
|
||||
@@ -13,13 +13,17 @@
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
|
||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||
#endif
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Support/KnownBits.h"
|
||||
#include "llvm/Support/ModRef.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/IR/IntrinsicsX86.h"
|
||||
#include "llvm/IR/IntrinsicsAArch64.h"
|
||||
|
||||
@@ -59,6 +63,62 @@ concept DSLValue = requires (T& v)
|
||||
{ v.eval(std::declval<llvm::IRBuilder<>*>()) } -> LLVMValue;
|
||||
};
|
||||
|
||||
template <usz N>
|
||||
struct get_int_bits
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<1>
|
||||
{
|
||||
using utype = bool;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<2>
|
||||
{
|
||||
using utype = i2;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<4>
|
||||
{
|
||||
using utype = i4;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<8>
|
||||
{
|
||||
using utype = u8;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<16>
|
||||
{
|
||||
using utype = u16;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<32>
|
||||
{
|
||||
using utype = u32;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<64>
|
||||
{
|
||||
using utype = u64;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_bits<128>
|
||||
{
|
||||
using utype = u128;
|
||||
};
|
||||
|
||||
template <usz Bits>
|
||||
using get_int_vt = typename get_int_bits<Bits>::utype;
|
||||
|
||||
template <typename T = void>
|
||||
struct llvm_value_t
|
||||
{
|
||||
@@ -2992,7 +3052,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename RT, DSLValue... Args>
|
||||
auto call(llvm::Function* func, Args&&... args)
|
||||
auto callf(llvm::Function* func, Args&&... args)
|
||||
{
|
||||
llvm_value_t<RT> r;
|
||||
r.value = m_ir->CreateCall(func, {std::forward<Args>(args).eval(m_ir)...});
|
||||
@@ -3292,7 +3352,7 @@ public:
|
||||
|
||||
// Infinite-precision shift left
|
||||
template <typename T, typename U, typename CT = llvm_common_t<T, U>>
|
||||
static auto inf_shl(T&& a, U&& b)
|
||||
auto inf_shl(T&& a, U&& b)
|
||||
{
|
||||
static constexpr u32 esz = llvm_value_t<CT>::esize;
|
||||
|
||||
@@ -3318,7 +3378,7 @@ public:
|
||||
|
||||
// Infinite-precision logical shift right (unsigned)
|
||||
template <typename T, typename U, typename CT = llvm_common_t<T, U>>
|
||||
static auto inf_lshr(T&& a, U&& b)
|
||||
auto inf_lshr(T&& a, U&& b)
|
||||
{
|
||||
static constexpr u32 esz = llvm_value_t<CT>::esize;
|
||||
|
||||
@@ -3344,7 +3404,7 @@ public:
|
||||
|
||||
// Infinite-precision arithmetic shift right (signed)
|
||||
template <typename T, typename U, typename CT = llvm_common_t<T, U>>
|
||||
static auto inf_ashr(T&& a, U&& b)
|
||||
auto inf_ashr(T&& a, U&& b)
|
||||
{
|
||||
static constexpr u32 esz = llvm_value_t<CT>::esize;
|
||||
|
||||
@@ -3429,7 +3489,7 @@ public:
|
||||
|
||||
if (cv || llvm::isa<llvm::ConstantAggregateZero>(c))
|
||||
{
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
result.value = m_ir->CreateZExt(result.value, get_type<u32[16]>());
|
||||
result.value = m_ir->CreateShuffleVector(data0, zeros, result.value);
|
||||
return result;
|
||||
@@ -3472,7 +3532,7 @@ public:
|
||||
|
||||
if (cv || llvm::isa<llvm::ConstantAggregateZero>(c))
|
||||
{
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
result.value = m_ir->CreateZExt(result.value, get_type<u32[16]>());
|
||||
result.value = m_ir->CreateShuffleVector(data0, data1, result.value);
|
||||
return result;
|
||||
@@ -3512,7 +3572,7 @@ public:
|
||||
|
||||
if (cv || llvm::isa<llvm::ConstantAggregateZero>(c))
|
||||
{
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
result.value = m_ir->CreateZExt(result.value, get_type<u32[16]>());
|
||||
result.value = m_ir->CreateShuffleVector(data0, data1, result.value);
|
||||
return result;
|
||||
@@ -3530,7 +3590,7 @@ public:
|
||||
u8 mask16[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
|
||||
// insert the second source operand into the same vector as the first source operand and expand to 256 bit width
|
||||
shuffle.value = llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u8*>(&mask32), 32));
|
||||
shuffle.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u8*>(&mask32), 32));
|
||||
shuffle.value = m_ir->CreateZExt(shuffle.value, get_type<u32[32]>());
|
||||
intermediate.value = m_ir->CreateShuffleVector(data0, data1, shuffle.value);
|
||||
|
||||
@@ -3541,22 +3601,23 @@ public:
|
||||
intermediate.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_avx512_permvar_qi_256), {intermediate.value, shuffleindex.value});
|
||||
|
||||
// convert the 256 bit vector back to 128 bits
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const u8*>(&mask16), 16));
|
||||
result.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(reinterpret_cast<const u8*>(&mask16), 16));
|
||||
result.value = m_ir->CreateZExt(result.value, get_type<u32[16]>());
|
||||
result.value = m_ir->CreateShuffleVector(intermediate.value, zeroes32, result.value);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
llvm::Value* load_const(llvm::GlobalVariable* g, llvm::Value* i)
|
||||
{
|
||||
return m_ir->CreateLoad(m_ir->CreateGEP(g, {m_ir->getInt64(0), m_ir->CreateZExtOrTrunc(i, get_type<u64>())}));
|
||||
return m_ir->CreateLoad(get_type<T>(), m_ir->CreateGEP(g->getValueType(), g, {m_ir->getInt64(0), m_ir->CreateZExtOrTrunc(i, get_type<u64>())}));
|
||||
}
|
||||
|
||||
template <typename T, typename I>
|
||||
value_t<T> load_const(llvm::GlobalVariable* g, I i)
|
||||
{
|
||||
value_t<T> result;
|
||||
result.value = load_const(g, i.eval(m_ir));
|
||||
result.value = load_const<T>(g, i.eval(m_ir));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3566,6 +3627,18 @@ public:
|
||||
template <typename T = v128>
|
||||
llvm::Constant* make_const_vector(T, llvm::Type*, u32 = __builtin_LINE());
|
||||
|
||||
template <typename T>
|
||||
llvm::KnownBits get_known_bits(T a)
|
||||
{
|
||||
return llvm::computeKnownBits(a.eval(m_ir), m_module->getDataLayout());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
llvm::KnownBits kbc(T value)
|
||||
{
|
||||
return llvm::KnownBits::makeConstant(llvm::APInt(sizeof(T) * 8, u64(value)));
|
||||
}
|
||||
|
||||
private:
|
||||
// Custom intrinsic table
|
||||
std::unordered_map<std::string_view, std::function<llvm::Value*(llvm::CallInst*)>> m_intrinsics;
|
||||
@@ -3635,7 +3708,7 @@ public:
|
||||
if (cv || llvm::isa<llvm::ConstantAggregateZero>(c))
|
||||
{
|
||||
llvm::Value* r = nullptr;
|
||||
r = llvm::ConstantDataVector::get(ir->getContext(), llvm::makeArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
r = llvm::ConstantDataVector::get(ir->getContext(), llvm::ArrayRef(reinterpret_cast<const u8*>(&mask), 16));
|
||||
r = ir->CreateZExt(r, llvm_value_t<u32[16]>::get_type(ir->getContext()));
|
||||
r = ir->CreateShuffleVector(args[0], zeros, r);
|
||||
return r;
|
||||
@@ -3646,6 +3719,13 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
// (m << 3) >= 0 ? a : b
|
||||
template <typename T, typename U, typename V>
|
||||
static auto select_by_bit4(T&& m, U&& a, V&& b)
|
||||
{
|
||||
return llvm_calli<u8[16], T, U, V>{"any_select_by_bit4", {std::forward<T>(m), std::forward<U>(a), std::forward<V>(b)}};
|
||||
}
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_same_v<llvm_common_t<T>, f32[4]>>>
|
||||
static auto fre(T&& a)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_process.h"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "cellAudio.h"
|
||||
@@ -274,8 +274,8 @@ void audio_ringbuffer::process_resampled_data()
|
||||
{
|
||||
if (!cfg.time_stretching_enabled) return;
|
||||
|
||||
const auto samples = resampler.get_samples(static_cast<u32>(cb_ringbuf.get_free_size() / (cfg.audio_sample_size * static_cast<u32>(cfg.backend_ch_cnt))));
|
||||
commit_data(samples.first, samples.second);
|
||||
const auto [buffer, samples] = resampler.get_samples(static_cast<u32>(cb_ringbuf.get_free_size() / (cfg.audio_sample_size * static_cast<u32>(cfg.backend_ch_cnt))));
|
||||
commit_data(buffer, samples);
|
||||
}
|
||||
|
||||
void audio_ringbuffer::commit_data(f32* buf, u32 sample_cnt)
|
||||
@@ -455,7 +455,7 @@ std::tuple<u32, u32, u32, u32> cell_audio_thread::count_port_buffer_tags()
|
||||
u32 untouched = 0;
|
||||
u32 incomplete = 0;
|
||||
|
||||
for (auto& port : ports)
|
||||
for (audio_port& port : ports)
|
||||
{
|
||||
if (port.state != audio_port_state::started) continue;
|
||||
active++;
|
||||
@@ -526,7 +526,7 @@ std::tuple<u32, u32, u32, u32> cell_audio_thread::count_port_buffer_tags()
|
||||
void cell_audio_thread::reset_ports(s32 offset)
|
||||
{
|
||||
// Memset buffer to 0 and tag
|
||||
for (auto& port : ports)
|
||||
for (audio_port& port : ports)
|
||||
{
|
||||
if (port.state != audio_port_state::started) continue;
|
||||
|
||||
@@ -548,7 +548,7 @@ void cell_audio_thread::advance(u64 timestamp)
|
||||
// update ports
|
||||
reset_ports(0);
|
||||
|
||||
for (auto& port : ports)
|
||||
for (audio_port& port : ports)
|
||||
{
|
||||
if (port.state != audio_port_state::started) continue;
|
||||
|
||||
@@ -572,12 +572,11 @@ void cell_audio_thread::advance(u64 timestamp)
|
||||
|
||||
// send aftermix event (normal audio event)
|
||||
std::array<std::shared_ptr<lv2_event_queue>, MAX_AUDIO_EVENT_QUEUES> queues;
|
||||
std::array<u64, MAX_AUDIO_EVENT_QUEUES> event_sources;
|
||||
u32 queue_count = 0;
|
||||
|
||||
event_period++;
|
||||
|
||||
for (const auto& key_inf : keys)
|
||||
for (const key_info& key_inf : keys)
|
||||
{
|
||||
if (key_inf.flags & CELL_AUDIO_EVENTFLAG_NOMIX)
|
||||
{
|
||||
@@ -607,6 +606,7 @@ void cell_audio_thread::advance(u64 timestamp)
|
||||
}
|
||||
|
||||
event_sources[queue_count] = key_inf.source;
|
||||
event_data3[queue_count] = (key_inf.flags & CELL_AUDIO_EVENTFLAG_BEFOREMIX) ? key_inf.source : 0;
|
||||
queue_count++;
|
||||
}
|
||||
}
|
||||
@@ -616,7 +616,7 @@ void cell_audio_thread::advance(u64 timestamp)
|
||||
for (u32 i = 0; i < queue_count; i++)
|
||||
{
|
||||
lv2_obj::notify_all_t notify;
|
||||
queues[i]->send(event_sources[i], 0, 0, 0);
|
||||
queues[i]->send(event_sources[i], CELL_AUDIO_EVENT_MIX, 0, event_data3[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,9 +648,9 @@ namespace audio
|
||||
if (auto& g_audio = g_fxo->get<cell_audio>(); g_fxo->is_init<cell_audio>())
|
||||
{
|
||||
// Only reboot the audio renderer if a relevant setting changed
|
||||
const auto new_raw = get_raw_config();
|
||||
const cell_audio_config::raw_config new_raw = get_raw_config();
|
||||
|
||||
if (const auto raw = g_audio.cfg.raw;
|
||||
if (const cell_audio_config::raw_config raw = g_audio.cfg.raw;
|
||||
force_reset ||
|
||||
raw.audio_device != new_raw.audio_device ||
|
||||
raw.desired_buffer_duration != new_raw.desired_buffer_duration ||
|
||||
@@ -735,7 +735,7 @@ void cell_audio_thread::operator()()
|
||||
{
|
||||
loop_count++;
|
||||
|
||||
const auto update_req = m_update_configuration.observe();
|
||||
const audio_backend_update update_req = m_update_configuration.observe();
|
||||
if (update_req != audio_backend_update::NONE)
|
||||
{
|
||||
cellAudio.warning("Updating cell_audio_thread configuration");
|
||||
@@ -758,7 +758,15 @@ void cell_audio_thread::operator()()
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: send beforemix event (in ~2,6 ms before mixing)
|
||||
// TODO: (no idea how much of this is already implemented)
|
||||
// The hardware heartbeat interval of libaudio is ~5.3ms.
|
||||
// As soon as one interval starts, libaudio waits for ~2.6ms (half of the interval) before it mixes the audio.
|
||||
// There are 2 different types of games:
|
||||
// - Normal games:
|
||||
// Once the audio was mixed, we send the CELL_AUDIO_EVENT_MIX event and the game can process audio.
|
||||
// - Latency sensitive games:
|
||||
// If CELL_AUDIO_EVENTFLAG_BEFOREMIX is specified, we immediately send the CELL_AUDIO_EVENT_MIX event and the game can process audio.
|
||||
// We then have to wait for a maximum of ~2.6ms for cellAudioSendAck and then mix immediately.
|
||||
|
||||
const u64 time_since_last_period = timestamp - m_last_period_end;
|
||||
|
||||
@@ -1057,7 +1065,7 @@ void cell_audio_thread::mix(float* out_buffer, s32 offset)
|
||||
std::memset(out_buffer, 0, out_buffer_sz * sizeof(float));
|
||||
|
||||
// mixing
|
||||
for (auto& port : ports)
|
||||
for (audio_port& port : ports)
|
||||
{
|
||||
if (port.state != audio_port_state::started) continue;
|
||||
|
||||
@@ -1070,7 +1078,7 @@ void cell_audio_thread::mix(float* out_buffer, s32 offset)
|
||||
// spread port volume changes over 13ms
|
||||
auto step_volume = [master_volume, &m](audio_port& port)
|
||||
{
|
||||
const auto param = port.level_set.load();
|
||||
const audio_port::level_set_t param = port.level_set.load();
|
||||
|
||||
if (param.inc != 0.0f)
|
||||
{
|
||||
@@ -1180,11 +1188,11 @@ void cell_audio_thread::mix(float* out_buffer, s32 offset)
|
||||
void cell_audio_thread::finish_port_volume_stepping()
|
||||
{
|
||||
// part of cellAudioSetPortLevel functionality
|
||||
for (auto& port : ports)
|
||||
for (audio_port& port : ports)
|
||||
{
|
||||
if (port.state != audio_port_state::started) continue;
|
||||
|
||||
const auto param = port.level_set.load();
|
||||
const audio_port::level_set_t param = port.level_set.load();
|
||||
port.level = param.value;
|
||||
port.level_set.compare_and_swap(param, { param.value, 0.0f });
|
||||
}
|
||||
@@ -1312,7 +1320,7 @@ error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32
|
||||
}
|
||||
|
||||
// Open audio port
|
||||
const auto port = g_audio.open_port();
|
||||
audio_port* port = g_audio.open_port();
|
||||
|
||||
if (!port)
|
||||
{
|
||||
@@ -1373,7 +1381,7 @@ error_code cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> port
|
||||
|
||||
portConfig->readIndexAddr = port.index;
|
||||
|
||||
switch (auto state = port.state.load())
|
||||
switch (audio_port_state state = port.state.load())
|
||||
{
|
||||
case audio_port_state::closed:
|
||||
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
|
||||
@@ -1414,7 +1422,7 @@ error_code cellAudioPortStart(u32 portNum)
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
switch (auto state = g_audio.ports[portNum].state.compare_and_swap(audio_port_state::opened, audio_port_state::started))
|
||||
switch (audio_port_state state = g_audio.ports[portNum].state.compare_and_swap(audio_port_state::opened, audio_port_state::started))
|
||||
{
|
||||
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||
case audio_port_state::started: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
|
||||
@@ -1441,7 +1449,7 @@ error_code cellAudioPortClose(u32 portNum)
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
switch (auto state = g_audio.ports[portNum].state.exchange(audio_port_state::closed))
|
||||
switch (audio_port_state state = g_audio.ports[portNum].state.exchange(audio_port_state::closed))
|
||||
{
|
||||
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||
case audio_port_state::started: return CELL_OK;
|
||||
@@ -1468,7 +1476,7 @@ error_code cellAudioPortStop(u32 portNum)
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
switch (auto state = g_audio.ports[portNum].state.compare_and_swap(audio_port_state::started, audio_port_state::opened))
|
||||
switch (audio_port_state state = g_audio.ports[portNum].state.compare_and_swap(audio_port_state::started, audio_port_state::opened))
|
||||
{
|
||||
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_RUN;
|
||||
case audio_port_state::started: return CELL_OK;
|
||||
@@ -1679,7 +1687,13 @@ error_code AudioSetNotifyEventQueue(u64 key, u32 iFlags)
|
||||
}
|
||||
|
||||
// Set unique source associated with the key
|
||||
g_audio.keys.push_back({g_audio.event_period, iFlags, ((process_getpid() + u64{}) << 32) + lv2_event_port::id_base + (g_audio.key_count++ * lv2_event_port::id_step), std::move(q)});
|
||||
g_audio.keys.push_back({
|
||||
.start_period = g_audio.event_period,
|
||||
.flags = iFlags,
|
||||
.source = ((process_getpid() + u64{}) << 32) + lv2_event_port::id_base + (g_audio.key_count++ * lv2_event_port::id_step),
|
||||
.ack_timestamp = 0,
|
||||
.port = std::move(q)
|
||||
});
|
||||
g_audio.key_count %= lv2_event_port::id_count;
|
||||
|
||||
return CELL_OK;
|
||||
@@ -1911,7 +1925,28 @@ error_code cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
|
||||
|
||||
error_code cellAudioSendAck(u64 data3)
|
||||
{
|
||||
cellAudio.todo("cellAudioSendAck(data3=0x%llx)", data3);
|
||||
cellAudio.trace("cellAudioSendAck(data3=0x%llx)", data3);
|
||||
|
||||
auto& g_audio = g_fxo->get<cell_audio>();
|
||||
|
||||
std::unique_lock lock(g_audio.mutex);
|
||||
|
||||
if (!g_audio.init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// TODO: error checks
|
||||
|
||||
for (cell_audio_thread::key_info& k : g_audio.keys)
|
||||
{
|
||||
if (k.source == data3)
|
||||
{
|
||||
k.ack_timestamp = get_system_time();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -389,12 +389,15 @@ public:
|
||||
|
||||
u32 key_count = 0;
|
||||
u8 event_period = 0;
|
||||
std::array<u64, MAX_AUDIO_EVENT_QUEUES> event_sources{};
|
||||
std::array<u64, MAX_AUDIO_EVENT_QUEUES> event_data3{};
|
||||
|
||||
struct key_info
|
||||
{
|
||||
u8 start_period = 0; // Starting event_period
|
||||
u32 flags = 0; // iFlags
|
||||
u64 source = 0; // Event source
|
||||
u64 ack_timestamp = 0; // timestamp of last call of cellAudioSendAck
|
||||
std::shared_ptr<lv2_event_queue> port{}; // Underlying event port
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Emu/Cell/lv2/sys_rsxaudio.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
#include "cellAudioOut.h"
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
#include "Emu/RSX/rsx_utils.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#include "cellMic.h"
|
||||
#include "cellAudioIn.h"
|
||||
#include "cellAudioOut.h"
|
||||
#include "cellVideoOut.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
LOG_CHANNEL(cellAvconfExt);
|
||||
|
||||
template<>
|
||||
@@ -34,9 +37,12 @@ void fmt_class_string<CellAudioInError>::format(std::string& out, u64 arg)
|
||||
|
||||
struct avconf_manager
|
||||
{
|
||||
shared_mutex mutex;
|
||||
std::vector<CellAudioInDeviceInfo> devices;
|
||||
CellAudioInDeviceMode inDeviceMode = CELL_AUDIO_IN_SINGLE_DEVICE_MODE; // TODO: use somewhere
|
||||
|
||||
void copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info);
|
||||
void copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info) const;
|
||||
std::optional<CellAudioInDeviceInfo> get_device_info(vm::cptr<char> name) const;
|
||||
|
||||
avconf_manager();
|
||||
|
||||
@@ -49,7 +55,8 @@ avconf_manager::avconf_manager()
|
||||
{
|
||||
u32 curindex = 0;
|
||||
|
||||
auto mic_list = fmt::split(g_cfg.audio.microphone_devices.to_string(), {"@@@"});
|
||||
const std::vector<std::string> mic_list = fmt::split(g_cfg.audio.microphone_devices.to_string(), {"@@@"});
|
||||
|
||||
if (!mic_list.empty())
|
||||
{
|
||||
switch (g_cfg.audio.microphone_type)
|
||||
@@ -131,20 +138,24 @@ avconf_manager::avconf_manager()
|
||||
}
|
||||
}
|
||||
|
||||
void avconf_manager::copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info)
|
||||
void avconf_manager::copy_device_info(u32 num, vm::ptr<CellAudioInDeviceInfo> info) const
|
||||
{
|
||||
memset(info.get_ptr(), 0, sizeof(CellAudioInDeviceInfo));
|
||||
ensure(num < devices.size());
|
||||
*info = devices[num];
|
||||
}
|
||||
|
||||
info->portType = devices[num].portType;
|
||||
info->availableModeCount = devices[num].availableModeCount;
|
||||
info->state = devices[num].state;
|
||||
info->deviceId = devices[num].deviceId;
|
||||
info->type = devices[num].type;
|
||||
info->availableModes[0].type = devices[num].availableModes[0].type;
|
||||
info->availableModes[0].channel = devices[num].availableModes[0].channel;
|
||||
info->availableModes[0].fs = devices[num].availableModes[0].fs;
|
||||
info->deviceNumber = devices[num].deviceNumber;
|
||||
strcpy_trunc(info->name, devices[num].name);
|
||||
std::optional<CellAudioInDeviceInfo> avconf_manager::get_device_info(vm::cptr<char> name) const
|
||||
{
|
||||
for (const CellAudioInDeviceInfo& device : devices)
|
||||
{
|
||||
if (strncmp(device.name, name.get_ptr(), sizeof(device.name)) == 0)
|
||||
{
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
error_code cellAudioOutUnregisterDevice(u32 deviceNumber)
|
||||
@@ -199,6 +210,7 @@ error_code cellAudioInGetDeviceInfo(u32 deviceNumber, u32 deviceIndex, vm::ptr<C
|
||||
}
|
||||
|
||||
auto& av_manager = g_fxo->get<avconf_manager>();
|
||||
std::lock_guard lock(av_manager.mutex);
|
||||
|
||||
if (deviceNumber >= av_manager.devices.size())
|
||||
return CELL_AUDIO_OUT_ERROR_DEVICE_NOT_FOUND;
|
||||
@@ -273,6 +285,7 @@ error_code cellAudioInGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioInDevic
|
||||
}
|
||||
|
||||
auto& av_manager = g_fxo->get<avconf_manager>();
|
||||
std::lock_guard lock(av_manager.mutex);
|
||||
|
||||
u32 num_devices_returned = std::min<u32>(count, ::size32(av_manager.devices));
|
||||
|
||||
@@ -281,6 +294,15 @@ error_code cellAudioInGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioInDevic
|
||||
av_manager.copy_device_info(index, device_info + index);
|
||||
}
|
||||
|
||||
CellAudioInDeviceInfo disconnected_device{};
|
||||
disconnected_device.state = CELL_AUDIO_OUT_DEVICE_STATE_UNAVAILABLE;
|
||||
disconnected_device.deviceNumber = 0xff;
|
||||
|
||||
for (u32 index = num_devices_returned; index < count; index++)
|
||||
{
|
||||
device_info[index] = disconnected_device;
|
||||
}
|
||||
|
||||
return not_an_error(num_devices_returned);
|
||||
}
|
||||
|
||||
@@ -355,6 +377,11 @@ error_code cellAudioInSetDeviceMode(u32 deviceMode)
|
||||
return CELL_AUDIO_IN_ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
auto& av_manager = g_fxo->get<avconf_manager>();
|
||||
std::lock_guard lock(av_manager.mutex);
|
||||
|
||||
av_manager.inDeviceMode = static_cast<CellAudioInDeviceMode>(deviceMode);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -368,12 +395,31 @@ error_code cellAudioInRegisterDevice(u64 deviceType, vm::cptr<char> name, vm::pt
|
||||
return CELL_AUDIO_IN_ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
return not_an_error(0); // device number
|
||||
auto& av_manager = g_fxo->get<avconf_manager>();
|
||||
const std::lock_guard lock(av_manager.mutex);
|
||||
|
||||
std::optional<CellAudioInDeviceInfo> info = av_manager.get_device_info(name);
|
||||
if (!info || !memchr(info->name, '\0', sizeof(info->name)))
|
||||
{
|
||||
// TODO
|
||||
return CELL_AUDIO_IN_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
auto& mic_thr = g_fxo->get<mic_thread>();
|
||||
const std::lock_guard mic_lock(mic_thr.mutex);
|
||||
const u32 device_number = mic_thr.register_device(info->name);
|
||||
|
||||
return not_an_error(device_number);
|
||||
}
|
||||
|
||||
error_code cellAudioInUnregisterDevice(u32 deviceNumber)
|
||||
{
|
||||
cellAvconfExt.todo("cellAudioInUnregisterDevice(deviceNumber=0x%x)", deviceNumber);
|
||||
|
||||
auto& mic_thr = g_fxo->get<mic_thread>();
|
||||
const std::lock_guard lock(mic_thr.mutex);
|
||||
mic_thr.unregister_device(deviceNumber);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -391,7 +437,7 @@ error_code cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<f32> screenSize)
|
||||
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
|
||||
}
|
||||
|
||||
if (g_cfg.video.enable_3d)
|
||||
if (g_cfg.video.stereo_render_mode != stereo_render_mode_options::disabled)
|
||||
{
|
||||
// Return Playstation 3D display value
|
||||
// Some games call this function when 3D is enabled
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "cellCamera.h"
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "Emu/IdManager.h"
|
||||
@@ -1646,11 +1647,7 @@ void camera_context::operator()()
|
||||
else
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
send_frame_update_event = handler ? on_handler_state(handler->get_state()) : true;
|
||||
});
|
||||
send_frame_update_event = !handler || on_handler_state(handler->get_state());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1714,26 +1711,21 @@ void camera_context::operator()()
|
||||
|
||||
bool camera_context::open_camera()
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
Emu.BlockingCallFromMainThread([&result, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
handler.reset();
|
||||
handler = Emu.GetCallbacks().get_camera_handler();
|
||||
if (handler)
|
||||
{
|
||||
handler->open_camera();
|
||||
result = on_handler_state(handler->get_state());
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
return !handler || on_handler_state(handler->get_state());
|
||||
}
|
||||
|
||||
bool camera_context::start_camera()
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (handler)
|
||||
{
|
||||
handler->set_mirrored(!!attr[CELL_CAMERA_MIRRORFLAG].v1);
|
||||
@@ -1741,29 +1733,25 @@ bool camera_context::start_camera()
|
||||
handler->set_resolution(info.width, info.height);
|
||||
handler->set_format(info.format, info.bytesize);
|
||||
|
||||
Emu.BlockingCallFromMainThread([&result, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
handler->start_camera();
|
||||
result = on_handler_state(handler->get_state());
|
||||
});
|
||||
|
||||
return on_handler_state(handler->get_state());
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool camera_context::get_camera_frame(u8* dst, u32& width, u32& height, u64& frame_number, u64& bytes_read)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (handler)
|
||||
{
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
result = on_handler_state(handler->get_image(dst, info.bytesize, width, height, frame_number, bytes_read));
|
||||
});
|
||||
return on_handler_state(handler->get_image(dst, info.bytesize, width, height, frame_number, bytes_read));
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
void camera_context::stop_camera()
|
||||
@@ -1915,13 +1903,19 @@ bool camera_context::on_handler_state(camera_handler_base::camera_handler_state
|
||||
if (is_streaming)
|
||||
{
|
||||
cellCamera.warning("Camera closed or disconnected (state=%d). Trying to start camera...", static_cast<int>(state));
|
||||
handler->open_camera();
|
||||
handler->start_camera();
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
handler->open_camera();
|
||||
handler->start_camera();
|
||||
});
|
||||
}
|
||||
else if (is_open)
|
||||
{
|
||||
cellCamera.warning("Camera closed or disconnected (state=%d). Trying to open camera...", static_cast<int>(state));
|
||||
handler->open_camera();
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
handler->open_camera();
|
||||
});
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -1931,7 +1925,10 @@ bool camera_context::on_handler_state(camera_handler_base::camera_handler_state
|
||||
if (handler && is_streaming)
|
||||
{
|
||||
cellCamera.warning("Camera handler not running (state=%d). Trying to start camera...", static_cast<int>(state));
|
||||
handler->start_camera();
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
handler->start_camera();
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1056,7 +1056,7 @@ error_code cellGcmMapEaIoAddressWithFlags(ppu_thread& ppu, u32 ea, u32 io, u32 s
|
||||
{
|
||||
cellGcmSys.warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags);
|
||||
|
||||
ensure(flags == 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/);
|
||||
ensure(flags == CELL_GCM_IOMAP_FLAG_STRICT_ORDERING);
|
||||
|
||||
auto& gcm_cfg = g_fxo->get<gcm_config>();
|
||||
std::lock_guard lock(gcm_cfg.gcmio_mutex);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/timers.hpp"
|
||||
#include "Emu/Io/MouseHandler.h"
|
||||
#include "Emu/Io/gem_config.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
@@ -21,6 +22,30 @@
|
||||
|
||||
LOG_CHANNEL(cellGem);
|
||||
|
||||
template <>
|
||||
void fmt_class_string<gem_btn>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](gem_btn value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case gem_btn::start: return "Start";
|
||||
case gem_btn::select: return "Select";
|
||||
case gem_btn::triangle: return "Triangle";
|
||||
case gem_btn::circle: return "Circle";
|
||||
case gem_btn::cross: return "Cross";
|
||||
case gem_btn::square: return "Square";
|
||||
case gem_btn::move: return "Move";
|
||||
case gem_btn::t: return "T";
|
||||
case gem_btn::count: return "Count";
|
||||
case gem_btn::x_axis: return "X-Axis";
|
||||
case gem_btn::y_axis: return "Y-Axis";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<CellGemError>::format(std::string& out, u64 arg)
|
||||
{
|
||||
@@ -133,6 +158,8 @@ using gun_thread = named_thread<gun_handler>;
|
||||
|
||||
#endif
|
||||
|
||||
cfg_gems g_cfg_gem;
|
||||
|
||||
struct gem_config_data
|
||||
{
|
||||
public:
|
||||
@@ -286,7 +313,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
gem_config_data() = default;
|
||||
gem_config_data()
|
||||
{
|
||||
if (!g_cfg_gem.load())
|
||||
{
|
||||
cellGem.notice("Could not load gem config. Using defaults.");
|
||||
}
|
||||
};
|
||||
|
||||
SAVESTATE_INIT_POS(15);
|
||||
|
||||
@@ -318,6 +351,11 @@ public:
|
||||
gem_config_data(utils::serial& ar)
|
||||
{
|
||||
save(ar);
|
||||
|
||||
if (!ar.is_writing() && !g_cfg_gem.load())
|
||||
{
|
||||
cellGem.notice("Could not load gem config. Using defaults.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -635,80 +673,73 @@ static void ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t
|
||||
return;
|
||||
}
|
||||
|
||||
for (const Button& button : pad->m_buttons)
|
||||
{
|
||||
if (!button.m_pressed)
|
||||
const auto& cfg = ::at32(g_cfg_gem.players, port_no);
|
||||
cfg->handle_input(pad, true, [&](gem_btn btn, u16 value, bool pressed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!pressed)
|
||||
return;
|
||||
|
||||
// here we check btns, and set pad accordingly
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||
{
|
||||
switch (button.m_outKeyCode)
|
||||
switch (btn)
|
||||
{
|
||||
case CELL_PAD_CTRL_START:
|
||||
case gem_btn::start:
|
||||
digital_buttons |= CELL_GEM_CTRL_START;
|
||||
break;
|
||||
case CELL_PAD_CTRL_SELECT:
|
||||
case gem_btn::select:
|
||||
digital_buttons |= CELL_GEM_CTRL_SELECT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
|
||||
{
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_SQUARE:
|
||||
case gem_btn::square:
|
||||
digital_buttons |= CELL_GEM_CTRL_SQUARE;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CROSS:
|
||||
case gem_btn::cross:
|
||||
digital_buttons |= CELL_GEM_CTRL_CROSS;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CIRCLE:
|
||||
case gem_btn::circle:
|
||||
digital_buttons |= CELL_GEM_CTRL_CIRCLE;
|
||||
break;
|
||||
case CELL_PAD_CTRL_TRIANGLE:
|
||||
case gem_btn::triangle:
|
||||
digital_buttons |= CELL_GEM_CTRL_TRIANGLE;
|
||||
break;
|
||||
case CELL_PAD_CTRL_R1:
|
||||
case gem_btn::move:
|
||||
digital_buttons |= CELL_GEM_CTRL_MOVE;
|
||||
break;
|
||||
case CELL_PAD_CTRL_R2:
|
||||
case gem_btn::t:
|
||||
digital_buttons |= CELL_GEM_CTRL_T;
|
||||
analog_t = std::max<u16>(analog_t, button.m_value);
|
||||
analog_t = std::max<u16>(analog_t, value);
|
||||
break;
|
||||
default:
|
||||
case gem_btn::x_axis:
|
||||
case gem_btn::y_axis:
|
||||
case gem_btn::count:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
constexpr u16 ds3_max_x = 255;
|
||||
constexpr u16 ds3_max_y = 255;
|
||||
|
||||
static inline void ds3_get_stick_values(const std::shared_ptr<Pad>& pad, s32& x_pos, s32& y_pos)
|
||||
static inline void ds3_get_stick_values(u32 port_no, const std::shared_ptr<Pad>& pad, s32& x_pos, s32& y_pos)
|
||||
{
|
||||
x_pos = 0;
|
||||
y_pos = 0;
|
||||
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
{
|
||||
switch (stick.m_offset)
|
||||
const auto& cfg = ::at32(g_cfg_gem.players, port_no);
|
||||
cfg->handle_input(pad, true, [&](gem_btn btn, u16 value, bool pressed)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
||||
x_pos = stick.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
|
||||
y_pos = stick.m_value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pressed)
|
||||
return;
|
||||
|
||||
switch (btn)
|
||||
{
|
||||
case gem_btn::x_axis:
|
||||
x_pos = value;
|
||||
break;
|
||||
case gem_btn::y_axis:
|
||||
y_pos = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -730,7 +761,7 @@ static void ds3_pos_to_gem_state(const u32 port_no, const gem_config::gem_contro
|
||||
}
|
||||
|
||||
s32 ds3_pos_x, ds3_pos_y;
|
||||
ds3_get_stick_values(pad, ds3_pos_x, ds3_pos_y);
|
||||
ds3_get_stick_values(port_no, pad, ds3_pos_x, ds3_pos_y);
|
||||
|
||||
if constexpr (std::is_same<T, vm::ptr<CellGemState>>::value)
|
||||
{
|
||||
|
||||
+508
-251
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/Thread.h"
|
||||
#include "Emu/Cell/timers.hpp"
|
||||
|
||||
#include "3rdparty/OpenAL/include/alext.h"
|
||||
|
||||
@@ -266,20 +267,25 @@ protected:
|
||||
class microphone_device
|
||||
{
|
||||
public:
|
||||
microphone_device(microphone_handler type);
|
||||
microphone_device(microphone_handler type = microphone_handler::null);
|
||||
|
||||
void add_device(const std::string& name);
|
||||
|
||||
void set_registered(bool registered) { mic_registered = registered; };
|
||||
|
||||
error_code open_microphone(const u8 type, const u32 dsp_r, const u32 raw_r, const u8 channels = 2);
|
||||
error_code close_microphone();
|
||||
|
||||
error_code start_microphone();
|
||||
error_code stop_microphone();
|
||||
|
||||
std::string get_device_name() const { return device_name.empty() ? "" : device_name.front(); }
|
||||
|
||||
void update_audio();
|
||||
bool has_data() const;
|
||||
|
||||
bool is_opened() const { return mic_opened; }
|
||||
bool is_registered() const { return mic_registered; }
|
||||
bool is_opened() const { return mic_opened; }
|
||||
bool is_started() const { return mic_started; }
|
||||
u8 get_signal_types() const { return signal_types; }
|
||||
u8 get_bit_resolution() const { return bit_resolution; }
|
||||
@@ -304,7 +310,7 @@ public:
|
||||
u32 attr_gain = 3;
|
||||
u32 attr_volume = 145;
|
||||
u32 attr_agc = 0;
|
||||
u32 attr_chanvol[2] = {145, 145};
|
||||
std::array<u32, 2> attr_chanvol = {145, 145};
|
||||
u32 attr_led = 0;
|
||||
u32 attr_dsptype = 0;
|
||||
|
||||
@@ -316,10 +322,10 @@ private:
|
||||
void get_raw(const u32 num_samples);
|
||||
void get_dsp(const u32 num_samples);
|
||||
|
||||
private:
|
||||
microphone_handler device_type;
|
||||
microphone_handler device_type = microphone_handler::null;
|
||||
std::vector<std::string> device_name;
|
||||
|
||||
bool mic_registered = false;
|
||||
bool mic_opened = false;
|
||||
bool mic_started = false;
|
||||
|
||||
@@ -350,10 +356,17 @@ class mic_context
|
||||
public:
|
||||
void operator()();
|
||||
void load_config_and_init();
|
||||
void wake_up();
|
||||
|
||||
// Returns index of registered device
|
||||
u32 register_device(const std::string& name);
|
||||
void unregister_device(u32 dev_num);
|
||||
bool check_device(u32 dev_num);
|
||||
|
||||
u64 event_queue_key = 0;
|
||||
u64 event_queue_source = 0;
|
||||
|
||||
std::unordered_map<s32, microphone_device> mic_list;
|
||||
std::array<microphone_device, CELL_MAX_MICS> mic_list{};
|
||||
|
||||
shared_mutex mutex;
|
||||
atomic_t<u8> init = 0;
|
||||
@@ -361,8 +374,7 @@ public:
|
||||
static constexpr auto thread_name = "Microphone Thread"sv;
|
||||
|
||||
protected:
|
||||
const u64 start_time = get_guest_system_time();
|
||||
u64 m_counter = 0;
|
||||
atomic_t<u64> wakey = 0;
|
||||
|
||||
// u32 signalStateLocalTalk = 9; // value is in range 0-10. 10 indicates talking, 0 indicating none.
|
||||
// u32 signalStateFarTalk = 0; // value is in range 0-10. 10 indicates talking from far away, 0 indicating none.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
#include "cellSysutil.h"
|
||||
|
||||
|
||||
|
||||
LOG_CHANNEL(cellMusicExport);
|
||||
|
||||
// Return Codes
|
||||
@@ -44,6 +45,15 @@ void fmt_class_string<CellMusicExportError>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_MUSIC_EXPORT_UTIL_VERSION_CURRENT = 0,
|
||||
CELL_MUSIC_EXPORT_UTIL_HDD_PATH_MAX = 1055,
|
||||
CELL_MUSIC_EXPORT_UTIL_MUSIC_TITLE_MAX_LENGTH = 64,
|
||||
CELL_MUSIC_EXPORT_UTIL_GAME_TITLE_MAX_LENGTH = 64,
|
||||
CELL_MUSIC_EXPORT_UTIL_GAME_COMMENT_MAX_SIZE = 1024,
|
||||
};
|
||||
|
||||
struct CellMusicExportSetParam
|
||||
{
|
||||
vm::bptr<char> title;
|
||||
@@ -51,15 +61,100 @@ struct CellMusicExportSetParam
|
||||
vm::bptr<char> artist;
|
||||
vm::bptr<char> genre;
|
||||
vm::bptr<char> game_comment;
|
||||
vm::bptr<void> reserved1;
|
||||
vm::bptr<char> reserved1;
|
||||
vm::bptr<void> reserved2;
|
||||
};
|
||||
|
||||
using CellMusicExportUtilFinishCallback = void(s32 result, vm::ptr<void> userdata);
|
||||
|
||||
struct music_export
|
||||
{
|
||||
atomic_t<s32> progress = 0; // 0x0-0xFFFF for 0-100%
|
||||
};
|
||||
|
||||
|
||||
bool check_music_path(const std::string& file_path)
|
||||
{
|
||||
if (file_path.size() >= CELL_MUSIC_EXPORT_UTIL_HDD_PATH_MAX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (char c : file_path)
|
||||
{
|
||||
if (!((c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') ||
|
||||
c == '-' || c == '_' ||
|
||||
c == '/' || c == '.'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_path.starts_with("/dev_hdd0"sv) &&
|
||||
!file_path.starts_with("/dev_bdvd"sv) &&
|
||||
!file_path.starts_with("/dev_hdd1"sv))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file_path.find(".."sv) != umax)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string get_available_music_path(const std::string& filename)
|
||||
{
|
||||
const std::string music_dir = "/dev_hdd0/music/";
|
||||
std::string dst_path = vfs::get(music_dir + filename);
|
||||
|
||||
// Do not overwrite existing files. Add a suffix instead.
|
||||
for (u32 i = 0; fs::exists(dst_path); i++)
|
||||
{
|
||||
const std::string suffix = fmt::format("_%d", i);
|
||||
std::string new_filename = filename;
|
||||
|
||||
if (const usz pos = new_filename.find_last_of('.'); pos != std::string::npos)
|
||||
{
|
||||
new_filename.insert(pos, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_filename.append(suffix);
|
||||
}
|
||||
|
||||
dst_path = vfs::get(music_dir + new_filename);
|
||||
}
|
||||
|
||||
return dst_path;
|
||||
}
|
||||
|
||||
|
||||
error_code cellMusicExportInitialize(u32 version, u32 container, vm::ptr<CellMusicExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
|
||||
{
|
||||
cellMusicExport.todo("cellMusicExportInitialize(version=0x%x, container=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, container, funcFinish, userdata);
|
||||
cellMusicExport.warning("cellMusicExportInitialize(version=0x%x, container=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, container, funcFinish, userdata);
|
||||
|
||||
if (version != CELL_MUSIC_EXPORT_UTIL_VERSION_CURRENT)
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (container != 0xfffffffe)
|
||||
{
|
||||
if (false) // TODO: Check if memory container size >= 0x300000
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
if (!funcFinish)
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
@@ -72,7 +167,17 @@ error_code cellMusicExportInitialize(u32 version, u32 container, vm::ptr<CellMus
|
||||
|
||||
error_code cellMusicExportInitialize2(u32 version, vm::ptr<CellMusicExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
|
||||
{
|
||||
cellMusicExport.todo("cellMusicExportInitialize2(version=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, funcFinish, userdata);
|
||||
cellMusicExport.notice("cellMusicExportInitialize2(version=0x%x, funcFinish=*0x%x, userdata=*0x%x)", version, funcFinish, userdata);
|
||||
|
||||
if (version != CELL_MUSIC_EXPORT_UTIL_VERSION_CURRENT)
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (!funcFinish)
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
@@ -85,7 +190,12 @@ error_code cellMusicExportInitialize2(u32 version, vm::ptr<CellMusicExportUtilFi
|
||||
|
||||
error_code cellMusicExportFinalize(vm::ptr<CellMusicExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
|
||||
{
|
||||
cellMusicExport.todo("cellMusicExportFinalize(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
|
||||
cellMusicExport.notice("cellMusicExportFinalize(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
|
||||
|
||||
if (!funcFinish)
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
@@ -100,8 +210,69 @@ error_code cellMusicExportFromFile(vm::cptr<char> srcHddDir, vm::cptr<char> srcH
|
||||
{
|
||||
cellMusicExport.todo("cellMusicExportFromFile(srcHddDir=%s, srcHddFile=%s, param=*0x%x, funcFinish=*0x%x, userdata=*0x%x)", srcHddDir, srcHddFile, param, funcFinish, userdata);
|
||||
|
||||
if (!param || !funcFinish)
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// TODO: check param members ?
|
||||
|
||||
cellMusicExport.notice("cellMusicExportFromFile: param: title=%s, game_title=%s, artist=%s, genre=%s, game_comment=%s", param->title, param->game_title, param->artist, param->genre, param->game_comment);
|
||||
|
||||
const std::string file_path = fmt::format("%s/%s", srcHddDir.get_ptr(), srcHddFile.get_ptr());
|
||||
|
||||
if (!check_music_path(file_path))
|
||||
{
|
||||
return { CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM, file_path };
|
||||
}
|
||||
|
||||
std::string filename = param->title.get_ptr();
|
||||
|
||||
if (filename.empty())
|
||||
{
|
||||
return { CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM, "title empty" };
|
||||
}
|
||||
|
||||
if (const std::string extension = get_file_extension(file_path); !extension.empty())
|
||||
{
|
||||
fmt::append(filename, ".%s", extension);
|
||||
}
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
auto& mexp = g_fxo->get<music_export>();
|
||||
mexp.progress = 0; // 0%
|
||||
|
||||
const std::string src_path = vfs::get(file_path);
|
||||
const std::string dst_path = get_available_music_path(filename);
|
||||
|
||||
cellMusicExport.notice("Copying file from '%s' to '%s'", file_path, dst_path);
|
||||
|
||||
// TODO: We ignore metadata for now
|
||||
|
||||
if (!fs::create_path(fs::get_parent_dir(dst_path)) || !fs::copy_file(src_path, dst_path, false))
|
||||
{
|
||||
// TODO: find out which error is used
|
||||
cellMusicExport.error("Failed to copy file from '%s' to '%s' (%s)", src_path, dst_path, fs::g_tls_error);
|
||||
funcFinish(ppu, CELL_MUSIC_EXPORT_UTIL_ERROR_MOVE, userdata);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!file_path.starts_with("/dev_bdvd"sv))
|
||||
{
|
||||
cellMusicExport.notice("Removing file '%s'", src_path);
|
||||
|
||||
if (!fs::remove_file(src_path))
|
||||
{
|
||||
// TODO: find out if an error is used here
|
||||
cellMusicExport.error("Failed to remove file '%s' (%s)", src_path, fs::g_tls_error);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: track progress during file copy
|
||||
|
||||
mexp.progress = 0xFFFF; // 100%
|
||||
|
||||
funcFinish(ppu, CELL_OK, userdata);
|
||||
return CELL_OK;
|
||||
});
|
||||
@@ -113,9 +284,18 @@ error_code cellMusicExportProgress(vm::ptr<CellMusicExportUtilFinishCallback> fu
|
||||
{
|
||||
cellMusicExport.todo("cellMusicExportProgress(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
|
||||
|
||||
if (!funcFinish)
|
||||
{
|
||||
return CELL_MUSIC_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
funcFinish(ppu, 0xFFFF, userdata);
|
||||
// Set the status as 0x0-0xFFFF (0-100%) depending on the copy status.
|
||||
// Only the copy or move of the movie and metadata files is considered for the progress.
|
||||
const auto& mexp = g_fxo->get<music_export>();
|
||||
|
||||
funcFinish(ppu, mexp.progress, userdata);
|
||||
return CELL_OK;
|
||||
});
|
||||
|
||||
|
||||
@@ -506,7 +506,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
||||
// Prepare callback variables
|
||||
vm::var<CellOskDialogKeyMessage> keyMessage(key_message);
|
||||
vm::var<u32> action(CELL_OSKDIALOG_CHANGE_NO_EVENT);
|
||||
vm::var<u16[], vm::page_allocator<>> pActionInfo(string_to_send.size(), string_to_send.data());
|
||||
vm::var<u16[], vm::page_allocator<>> pActionInfo(::narrow<u32>(string_to_send.size()), string_to_send.data());
|
||||
|
||||
// Create helpers for logging
|
||||
std::u16string utf16_string(reinterpret_cast<const char16_t*>(string_to_send.data()), string_to_send.size());
|
||||
|
||||
@@ -28,6 +28,7 @@ void fmt_class_string<CellPamfError>::format(std::string& out, u64 arg)
|
||||
STR_CASE(CELL_PAMF_ERROR_UNSUPPORTED_VERSION);
|
||||
STR_CASE(CELL_PAMF_ERROR_UNKNOWN_STREAM);
|
||||
STR_CASE(CELL_PAMF_ERROR_EP_NOT_FOUND);
|
||||
STR_CASE(CELL_PAMF_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
|
||||
@@ -12,6 +12,7 @@ enum CellPamfError : u32
|
||||
CELL_PAMF_ERROR_UNSUPPORTED_VERSION = 0x80610505,
|
||||
CELL_PAMF_ERROR_UNKNOWN_STREAM = 0x80610506,
|
||||
CELL_PAMF_ERROR_EP_NOT_FOUND = 0x80610507,
|
||||
CELL_PAMF_ERROR_NOT_AVAILABLE = 0x80610508,
|
||||
};
|
||||
|
||||
// PamfReaderInitialize Attribute Flags
|
||||
|
||||
@@ -288,6 +288,11 @@ error_code cellPhotoExportInitialize2(u32 version, vm::ptr<CellPhotoExportUtilFi
|
||||
return CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (!funcFinish)
|
||||
{
|
||||
return CELL_PHOTO_EXPORT_UTIL_ERROR_PARAM;
|
||||
}
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
{
|
||||
funcFinish(ppu, CELL_OK, userdata);
|
||||
@@ -454,7 +459,7 @@ error_code cellPhotoExportFromFileWithCopy(vm::cptr<char> srcHddDir, vm::cptr<ch
|
||||
|
||||
error_code cellPhotoExportProgress(vm::ptr<CellPhotoExportUtilFinishCallback> funcFinish, vm::ptr<void> userdata)
|
||||
{
|
||||
cellPhotoExport.todo("cellPhotoExportProgress(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
|
||||
cellPhotoExport.notice("cellPhotoExportProgress(funcFinish=*0x%x, userdata=*0x%x)", funcFinish, userdata);
|
||||
|
||||
if (!funcFinish)
|
||||
{
|
||||
|
||||
@@ -786,20 +786,8 @@ error_code cellRtcGetTick(vm::cptr<CellRtcDateTime> pTime, vm::ptr<CellRtcTick>
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellRtcSetTick(vm::ptr<CellRtcDateTime> pTime, vm::cptr<CellRtcTick> pTick)
|
||||
CellRtcDateTime tick_to_date_time(u64 tick)
|
||||
{
|
||||
cellRtc.todo("cellRtcSetTick(pTime=*0x%x, pTick=*0x%x)", pTime, pTick);
|
||||
|
||||
if (!vm::check_addr(pTime.addr()))
|
||||
{
|
||||
return CELL_RTC_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
if (!vm::check_addr(pTick.addr()))
|
||||
{
|
||||
return CELL_RTC_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
/*
|
||||
u32 microseconds = round((pTick->tick % 1000000ULL));
|
||||
u16 seconds = round((pTick->tick / (1000000ULL)) % 60);
|
||||
@@ -807,11 +795,11 @@ error_code cellRtcSetTick(vm::ptr<CellRtcDateTime> pTime, vm::cptr<CellRtcTick>
|
||||
u16 hours = round((pTick->tick / (60ULL * 60ULL * 1000000ULL)) % 24);
|
||||
u64 days_tmp = round((pTick->tick / (24ULL * 60ULL * 60ULL * 1000000ULL)));*/
|
||||
|
||||
u32 microseconds = (pTick->tick % 1000000ULL);
|
||||
u16 seconds = (pTick->tick / (1000000ULL)) % 60;
|
||||
u16 minutes = (pTick->tick / (60ULL * 1000000ULL)) % 60;
|
||||
u16 hours = (pTick->tick / (60ULL * 60ULL * 1000000ULL)) % 24;
|
||||
u64 days_tmp = (pTick->tick / (24ULL * 60ULL * 60ULL * 1000000ULL));
|
||||
const u32 microseconds = (tick % 1000000ULL);
|
||||
const u16 seconds = (tick / (1000000ULL)) % 60;
|
||||
const u16 minutes = (tick / (60ULL * 1000000ULL)) % 60;
|
||||
const u16 hours = (tick / (60ULL * 60ULL * 1000000ULL)) % 24;
|
||||
u64 days_tmp = (tick / (24ULL * 60ULL * 60ULL * 1000000ULL));
|
||||
|
||||
u16 months = 1;
|
||||
u16 years = 1;
|
||||
@@ -842,13 +830,33 @@ error_code cellRtcSetTick(vm::ptr<CellRtcDateTime> pTime, vm::cptr<CellRtcTick>
|
||||
|
||||
} while (!exit_while);
|
||||
|
||||
pTime->microsecond = microseconds;
|
||||
pTime->second = seconds;
|
||||
pTime->minute = minutes;
|
||||
pTime->hour = hours;
|
||||
pTime->day = ::narrow<u16>(days_tmp + 1);
|
||||
pTime->month = months;
|
||||
pTime->year = years;
|
||||
CellRtcDateTime date_time{
|
||||
.year = years,
|
||||
.month = months,
|
||||
.day = ::narrow<u16>(days_tmp + 1),
|
||||
.hour = hours,
|
||||
.minute = minutes,
|
||||
.second = seconds,
|
||||
.microsecond = microseconds
|
||||
};
|
||||
return date_time;
|
||||
}
|
||||
|
||||
error_code cellRtcSetTick(vm::ptr<CellRtcDateTime> pTime, vm::cptr<CellRtcTick> pTick)
|
||||
{
|
||||
cellRtc.todo("cellRtcSetTick(pTime=*0x%x, pTick=*0x%x)", pTime, pTick);
|
||||
|
||||
if (!vm::check_addr(pTime.addr()))
|
||||
{
|
||||
return CELL_RTC_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
if (!vm::check_addr(pTick.addr()))
|
||||
{
|
||||
return CELL_RTC_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
*pTime = tick_to_date_time(pTick->tick);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -50,3 +50,6 @@ u32 cellRtcGetTickResolution();
|
||||
error_code cellRtcCheckValid(vm::cptr<CellRtcDateTime> pTime);
|
||||
error_code cellRtcGetDayOfWeek(s32 year, s32 month, s32 day);
|
||||
error_code cellRtcGetTick(vm::cptr<CellRtcDateTime> pTime, vm::ptr<CellRtcTick> pTick);
|
||||
error_code cellRtcGetCurrentTick(vm::ptr<CellRtcTick> pTick);
|
||||
|
||||
CellRtcDateTime tick_to_date_time(u64 tick);
|
||||
|
||||
@@ -1678,8 +1678,12 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
|
||||
error_code savedata_result = CELL_OK;
|
||||
|
||||
u64 delay_save_until = 0;
|
||||
|
||||
while (funcFile)
|
||||
{
|
||||
lv2_sleep(ppu, 2000);
|
||||
|
||||
std::memset(fileSet.get_ptr(), 0, fileSet.size());
|
||||
std::memset(fileGet->reserved, 0, sizeof(fileGet->reserved));
|
||||
std::memset(result.get_ptr(), 0, ::offset32(&CellSaveDataCBResult::userdata));
|
||||
@@ -1691,6 +1695,10 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
if (res == CELL_SAVEDATA_CBRESULT_OK_LAST || res == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
|
||||
{
|
||||
// TODO: display user prompt
|
||||
|
||||
// Some games (Jak II [NPUA80707]) rely on this delay
|
||||
lv2_obj::sleep(ppu);
|
||||
delay_save_until = get_guest_system_time() + (has_modified ? 500'000 : 100'000);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1833,7 +1841,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
|
||||
if (file == all_files.cend() || file->second.size() <= fileSet->fileOffset)
|
||||
{
|
||||
cellSaveData.error("Failed to open file %s%s (size=%d, fileOffset=%d)", dir_path, file_path, file->second.size(), fileSet->fileOffset);
|
||||
cellSaveData.error("Failed to open file %s%s (size=%d, fileOffset=%d)", dir_path, file_path, file == all_files.cend() ? -1 : file->second.size(), fileSet->fileOffset);
|
||||
savedata_result = CELL_SAVEDATA_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
@@ -2020,6 +2028,11 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
return display_callback_result_error_message(ppu, *result, errDialog);
|
||||
}
|
||||
|
||||
if (u64 current_time = get_guest_system_time(); current_time < delay_save_until)
|
||||
{
|
||||
lv2_sleep(ppu, delay_save_until - current_time);
|
||||
}
|
||||
|
||||
return savedata_result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Memory/vm_reservation.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
@@ -798,7 +798,7 @@ struct alignas(128) CellSpurs
|
||||
|
||||
atomic_t<u8>& readyCount(u32 wid)
|
||||
{
|
||||
if (wid & 0x10)
|
||||
if (wid < 0x10)
|
||||
{
|
||||
return wklReadyCount1[wid & 0xf];
|
||||
}
|
||||
|
||||
@@ -163,6 +163,13 @@ extern u64 get_sysutil_cb_manager_read_count()
|
||||
|
||||
extern bool send_open_home_menu_cmds()
|
||||
{
|
||||
auto status = g_fxo->try_get<SysutilMenuOpenStatus>();
|
||||
|
||||
if (!status || status->active)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: handle CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE
|
||||
if (sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_BEGIN, 0) < 0 ||
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_SYSTEM_MENU_OPEN, 0) < 0 ||
|
||||
@@ -171,15 +178,25 @@ extern bool send_open_home_menu_cmds()
|
||||
return false;
|
||||
}
|
||||
|
||||
status->active = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
extern void send_close_home_menu_cmds()
|
||||
{
|
||||
auto status = g_fxo->try_get<SysutilMenuOpenStatus>();
|
||||
|
||||
if (!status || !status->active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: handle CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_BGMPLAYBACK_STOP, 0);
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_SYSTEM_MENU_CLOSE, 0);
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
||||
status->active = false;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
||||
@@ -317,6 +317,14 @@ struct CellSysCacheParam
|
||||
vm::bptr<void> reserved;
|
||||
};
|
||||
|
||||
template <u32 BaseEvent>
|
||||
struct SysutilEventStatus
|
||||
{
|
||||
atomic_t<bool> active = false;
|
||||
};
|
||||
|
||||
using SysutilMenuOpenStatus = SysutilEventStatus<CELL_SYSUTIL_SYSTEM_MENU_OPEN>;
|
||||
|
||||
extern void sysutil_register_cb(std::function<s32(ppu_thread&)>&&);
|
||||
extern s32 sysutil_send_system_cmd(u64 status, u64 param);
|
||||
s32 sysutil_check_name_string(const char* src, s32 minlen, s32 maxlen);
|
||||
|
||||
@@ -1298,7 +1298,11 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
|
||||
u8* in_data[4] = { frame->data[0], frame->data[1], frame->data[2], alpha_plane.get() };
|
||||
int in_line[4] = { frame->linesize[0], frame->linesize[1], frame->linesize[2], w * 1 };
|
||||
u8* out_data[4] = { outBuff.get_ptr() };
|
||||
int out_line[4] = { static_cast<int>(utils::align(w * 4u, 128)) }; // RGBA32 or ARGB32
|
||||
int out_line[4] = { w * 4 }; // RGBA32 or ARGB32
|
||||
|
||||
// TODO:
|
||||
// It's possible that we need to align the pitch to 128 here.
|
||||
// PS HOME seems to rely on this somehow in certain cases.
|
||||
|
||||
if (!alpha_plane)
|
||||
{
|
||||
@@ -1310,10 +1314,6 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
|
||||
{
|
||||
fmt::throw_exception("cellVdecGetPictureExt: av_image_fill_linesizes failed (handle=0x%x, seq_id=%d, cmd_id=%d, ret=0x%x): %s", handle, frame.seq_id, frame.cmd_id, ret, utils::av_error_to_string(ret));
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// It's possible that we need to align the pitch to 128 here as well.
|
||||
// But I'd wait for a game with broken images before tackling this.
|
||||
}
|
||||
|
||||
sws_scale(vdec->sws, in_data, in_line, 0, h, out_data, out_line);
|
||||
|
||||
@@ -181,7 +181,7 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration
|
||||
|
||||
CellVideoOutResolution res;
|
||||
if (_IntGetResolutionInfo(config->resolutionId, &res) != CELL_OK ||
|
||||
(config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING && !g_cfg.video.enable_3d))
|
||||
(config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING && g_cfg.video.stereo_render_mode == stereo_render_mode_options::disabled))
|
||||
{
|
||||
// Resolution not supported
|
||||
cellSysutil.error("Unusual resolution requested: 0x%x", config->resolutionId);
|
||||
@@ -190,7 +190,7 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration
|
||||
|
||||
auto& conf = g_fxo->get<rsx::avconf>();
|
||||
conf.resolution_id = config->resolutionId;
|
||||
conf._3d = config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING;
|
||||
conf.stereo_mode = (config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING) ? g_cfg.video.stereo_render_mode.get() : stereo_render_mode_options::disabled;
|
||||
conf.aspect = config->aspect;
|
||||
conf.format = config->format;
|
||||
conf.scanline_pitch = config->pitch;
|
||||
@@ -301,7 +301,7 @@ error_code cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr<Cell
|
||||
info->availableModes[0].resolutionId = ::at32(g_video_out_resolution_id, g_cfg.video.resolution);
|
||||
info->availableModes[0].scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE;
|
||||
|
||||
if (g_cfg.video.enable_3d && g_cfg.video.resolution == video_resolution::_720)
|
||||
if (g_cfg.video.stereo_render_mode != stereo_render_mode_options::disabled && g_cfg.video.resolution == video_resolution::_720)
|
||||
{
|
||||
// Register 3D-capable display mode
|
||||
info->availableModes[1] = info->availableModes[0];
|
||||
@@ -346,7 +346,7 @@ error_code cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId,
|
||||
return not_an_error(1);
|
||||
}
|
||||
|
||||
if (g_cfg.video.enable_3d && g_cfg.video.resolution == video_resolution::_720)
|
||||
if ((g_cfg.video.stereo_render_mode != stereo_render_mode_options::disabled) && g_cfg.video.resolution == video_resolution::_720)
|
||||
{
|
||||
switch (resolutionId)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Emu/system_utils.hpp"
|
||||
#include "Emu/VFS.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/Modules/cellUserInfo.h"
|
||||
#include "Emu/Io/interception.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
@@ -19,6 +20,7 @@
|
||||
#include "Emu/NP/np_handler.h"
|
||||
#include "Emu/NP/np_contexts.h"
|
||||
#include "Emu/NP/np_helpers.h"
|
||||
#include "Emu/NP/np_structs_extra.h"
|
||||
#include "Emu/system_config.h"
|
||||
|
||||
LOG_CHANNEL(sceNp);
|
||||
@@ -985,6 +987,8 @@ error_code sceNpBasicSendMessageGui(vm::cptr<SceNpBasicMessageDetails> msg, sys_
|
||||
msg_data.data.assign(msg->data.get_ptr(), msg->data.get_ptr() + msg->size);
|
||||
}
|
||||
|
||||
sceNp.trace("Message Data:\n%s", fmt::buf_to_hexstring(msg->data.get_ptr(), msg->size));
|
||||
|
||||
bool result = false;
|
||||
|
||||
input::SetIntercepted(true);
|
||||
@@ -1082,7 +1086,7 @@ error_code sceNpBasicRecvMessageAttachment(sys_memory_container_t containerId)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sceNpBasicRecvMessageAttachmentLoad(u32 id, vm::ptr<void> buffer, vm::ptr<u32> size)
|
||||
error_code sceNpBasicRecvMessageAttachmentLoad(SceNpBasicAttachmentDataId id, vm::ptr<void> buffer, vm::ptr<u32> size)
|
||||
{
|
||||
sceNp.warning("sceNpBasicRecvMessageAttachmentLoad(id=%d, buffer=*0x%x, size=*0x%x)", id, buffer, size);
|
||||
|
||||
@@ -1103,12 +1107,20 @@ error_code sceNpBasicRecvMessageAttachmentLoad(u32 id, vm::ptr<void> buffer, vm:
|
||||
return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
const auto opt_msg = nph.get_message(id);
|
||||
if (id != SCE_NP_BASIC_SELECTED_INVITATION_DATA && id != SCE_NP_BASIC_SELECTED_MESSAGE_DATA)
|
||||
{
|
||||
return SCE_NP_BASIC_ERROR_INVALID_DATA_ID;
|
||||
}
|
||||
|
||||
const auto opt_msg = nph.get_message_selected(id);
|
||||
if (!opt_msg)
|
||||
{
|
||||
return SCE_NP_BASIC_ERROR_INVALID_DATA_ID;
|
||||
}
|
||||
|
||||
// Not sure about this
|
||||
// nph.clear_message_selected(id);
|
||||
|
||||
const auto msg_pair = opt_msg.value();
|
||||
const auto msg = msg_pair->second;
|
||||
|
||||
@@ -1116,6 +1128,8 @@ error_code sceNpBasicRecvMessageAttachmentLoad(u32 id, vm::ptr<void> buffer, vm:
|
||||
const u32 size_to_copy = std::min(static_cast<u32>(msg.data.size()), orig_size);
|
||||
memcpy(buffer.get_ptr(), msg.data.data(), size_to_copy);
|
||||
|
||||
sceNp.trace("Message Data received:\n%s", fmt::buf_to_hexstring(static_cast<u8*>(buffer.get_ptr()), size_to_copy));
|
||||
|
||||
*size = size_to_copy;
|
||||
if (size_to_copy < msg.data.size())
|
||||
{
|
||||
@@ -1180,11 +1194,18 @@ error_code sceNpBasicRecvMessageCustom(u16 mainType, u32 recvOptions, sys_memory
|
||||
SceNpBasicExtendedAttachmentData* att_data = reinterpret_cast<SceNpBasicExtendedAttachmentData*>(to_add.data.data());
|
||||
att_data->flags = 0; // ?
|
||||
att_data->msgId = chosen_msg_id;
|
||||
att_data->data.id = static_cast<u32>(chosen_msg_id);
|
||||
att_data->data.id = (mainType == SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE) ? SCE_NP_BASIC_SELECTED_INVITATION_DATA : SCE_NP_BASIC_SELECTED_MESSAGE_DATA;
|
||||
att_data->data.size = static_cast<u32>(msg.data.size());
|
||||
att_data->userAction = recv_result;
|
||||
att_data->markedAsUsed = (recvOptions & SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_PRESERVE) ? 0 : 1;
|
||||
|
||||
extra_nps::print_SceNpBasicExtendedAttachmentData(att_data);
|
||||
|
||||
nph.set_message_selected(att_data->data.id, chosen_msg_id);
|
||||
|
||||
// Is this sent if used from home menu but not from sceNpBasicRecvMessageCustom, not sure
|
||||
// sysutil_send_system_cmd(CELL_SYSUTIL_NP_INVITATION_SELECTED, 0);
|
||||
|
||||
nph.queue_basic_event(to_add);
|
||||
nph.send_basic_event(event_to_send, 0, 0);
|
||||
|
||||
@@ -1985,7 +2006,7 @@ error_code sceNpBasicGetMessageEntry(u32 type, u32 index, vm::ptr<SceNpUserInfo>
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sceNpBasicGetEvent(vm::ptr<s32> event, vm::ptr<SceNpUserInfo> from, vm::ptr<s32> data, vm::ptr<u32> size)
|
||||
error_code sceNpBasicGetEvent(vm::ptr<s32> event, vm::ptr<SceNpUserInfo> from, vm::ptr<u8> data, vm::ptr<u32> size)
|
||||
{
|
||||
sceNp.warning("sceNpBasicGetEvent(event=*0x%x, from=*0x%x, data=*0x%x, size=*0x%x)", event, from, data, size);
|
||||
|
||||
@@ -3334,7 +3355,7 @@ error_code sceNpManagerGetChatRestrictionFlag(vm::ptr<s32> isRestricted)
|
||||
|
||||
error_code sceNpManagerGetCachedInfo(CellSysutilUserId userId, vm::ptr<SceNpManagerCacheParam> param)
|
||||
{
|
||||
sceNp.todo("sceNpManagerGetCachedInfo(userId=%d, param=*0x%x)", userId, param);
|
||||
sceNp.warning("sceNpManagerGetCachedInfo(userId=%d, param=*0x%x)", userId, param);
|
||||
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
|
||||
@@ -3348,6 +3369,17 @@ error_code sceNpManagerGetCachedInfo(CellSysutilUserId userId, vm::ptr<SceNpMana
|
||||
return SCE_NP_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (userId != CELL_SYSUTIL_USERID_CURRENT && userId != Emu.GetUsrId())
|
||||
{
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
param->size = sizeof(SceNpManagerCacheParam);
|
||||
param->onlineId = nph.get_online_id();
|
||||
param->npId = nph.get_npid();
|
||||
param->onlineName = nph.get_online_name();
|
||||
param->avatarUrl = nph.get_avatar_url();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -5300,7 +5332,10 @@ error_code sceNpSignalingGetConnectionStatus(u32 ctx_id, u32 conn_id, vm::ptr<s3
|
||||
const auto si = sigh.get_sig_infos(conn_id);
|
||||
|
||||
if (!si)
|
||||
{
|
||||
*conn_status = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
|
||||
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
|
||||
}
|
||||
|
||||
*conn_status = si->conn_status;
|
||||
|
||||
|
||||
@@ -1057,7 +1057,7 @@ struct SceNpManagerCacheParam
|
||||
// Message attachment data
|
||||
struct SceNpBasicAttachmentData
|
||||
{
|
||||
be_t<u32> id; // SceNpBasicAttachmentDataId
|
||||
be_t<SceNpBasicAttachmentDataId> id;
|
||||
be_t<u32> size;
|
||||
};
|
||||
|
||||
@@ -1068,7 +1068,7 @@ struct SceNpBasicExtendedAttachmentData
|
||||
be_t<u64> msgId;
|
||||
SceNpBasicAttachmentData data;
|
||||
be_t<u32> userAction;
|
||||
b8 markedAsUsed;
|
||||
u8 markedAsUsed;
|
||||
u8 reserved[3];
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user