Compare commits
313 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0064976c43 | |||
| 4bdb6674eb | |||
| c7f7d7ef5b | |||
| 2c19fdf092 | |||
| 8fc9862614 | |||
| 55d84414ee | |||
| 8c0bdd71d9 | |||
| 3c9126d91f | |||
| 8b4836a12f | |||
| b2a7eee1ec | |||
| ed21bb309f | |||
| 7b3e4f5e3d | |||
| 30b3af0d12 | |||
| 541cb4062b | |||
| 4e9160104a | |||
| 86fa379c78 | |||
| 8733505d0a | |||
| 242611aa46 | |||
| baa5a261a5 | |||
| 3730b9d1da | |||
| 0d35363ea0 | |||
| 75504b3f5e | |||
| 4ca98e53a6 | |||
| 300a36d3d6 | |||
| 60c7a508a7 | |||
| 1fa18757fc | |||
| fbb7186e66 | |||
| 0961a43997 | |||
| 7037504dcf | |||
| 2385029eab | |||
| eed55a446c | |||
| bbcb6b6851 | |||
| b95630d84a | |||
| af1d3c2aa6 | |||
| ec3e5c547f | |||
| 963a87fed5 | |||
| 173d05b54f | |||
| 865bb47462 | |||
| 3e7ed8a831 | |||
| 3a49a77c07 | |||
| 6782b22637 | |||
| 4600094829 | |||
| daaa83b9ca | |||
| 3288050680 | |||
| b8c29ae957 | |||
| 47bacc0ef0 | |||
| 3d0dced4bd | |||
| 30bba09fed | |||
| 31b07f2c5c | |||
| f7063bb57b | |||
| e4ef85b6e0 | |||
| b7c2088489 | |||
| 59cd0a9c7f | |||
| af107df0b4 | |||
| 0e7e40f2cb | |||
| 0b788f5b43 | |||
| db5c2500c2 | |||
| a1496eb1f1 | |||
| 4aa89132d7 | |||
| 9b8eb089b1 | |||
| c1f08ce58d | |||
| 09a0d046f4 | |||
| 0741698f13 | |||
| c2ac05f734 | |||
| f8f5f9f418 | |||
| 7e6d6b45d4 | |||
| 361e80f7dc | |||
| 395b4bfa45 | |||
| ce2b790d8f | |||
| 1ffc1e82b0 | |||
| 8520ca7ef7 | |||
| 89fba1c385 | |||
| 00a0d37455 | |||
| dbb2251f93 | |||
| 7abf755a57 | |||
| 055f0e2e4a | |||
| 49f4da3016 | |||
| bf234dc668 | |||
| 11bd65c2b5 | |||
| e0d1ac676e | |||
| 494cbac78b | |||
| 0d46a8e786 | |||
| 626b9f93c4 | |||
| 53f9defb07 | |||
| 4bf8d1e41f | |||
| 936c817bd8 | |||
| 9c9495621c | |||
| d53673c6f7 | |||
| 882e949f80 | |||
| e6849a59a2 | |||
| 6918e265ec | |||
| e9f293f522 | |||
| 5fc36d64b6 | |||
| 95e6d78689 | |||
| f4a666345a | |||
| 7a5c88a8d1 | |||
| 0de0dded53 | |||
| 5e58cf6079 | |||
| b0737d1c90 | |||
| 779ed75a19 | |||
| dbf1573e89 | |||
| 96fd8556f2 | |||
| 8f324dfc0a | |||
| 34a6085cc0 | |||
| b3efa75206 | |||
| b90a7dc66a | |||
| 200557c036 | |||
| 472cb3b1c2 | |||
| d8ee6a2edb | |||
| ddcacb8258 | |||
| a8e1754fa4 | |||
| 5db45c3699 | |||
| 89dcafbe41 | |||
| 3d05e61f7e | |||
| 5146f3ec47 | |||
| 170a95f5df | |||
| c661578906 | |||
| f20e0c2898 | |||
| 64b2ae3cd5 | |||
| a11d66f52d | |||
| 304a4a1b61 | |||
| 76b7103fed | |||
| 1572d01c53 | |||
| 86bf61ad35 | |||
| 479aa91368 | |||
| bb398c4a08 | |||
| eab9d06981 | |||
| c63ff05e6e | |||
| 0129c54ab6 | |||
| c570410e06 | |||
| 9af71699a4 | |||
| 58860614e3 | |||
| e8bde583ef | |||
| 5b19908996 | |||
| 19f3bb8cb0 | |||
| ac64792d99 | |||
| efe140bc0c | |||
| df2fc13b7a | |||
| f5d450f24c | |||
| 2e5f8c0786 | |||
| 9bcc298b18 | |||
| 5a03db7d2e | |||
| 91ef202ee7 | |||
| 6d6b281270 | |||
| a3c49bea2c | |||
| 1d375cb13c | |||
| 20ad9a13b8 | |||
| fc0f98b5db | |||
| 3fe37ede97 | |||
| 55df3cdf67 | |||
| 6e8107a5cb | |||
| 7bee4064a6 | |||
| 12ab03b0b5 | |||
| 47202d5839 | |||
| 47b121a700 | |||
| d53b640bcf | |||
| 78ef467138 | |||
| b7f6bd4c91 | |||
| e272acd7c1 | |||
| 93d2ac887d | |||
| a84cc1d3bb | |||
| cc594ad353 | |||
| beab5291bb | |||
| 3907dd0444 | |||
| 3d64b65813 | |||
| ab4e66a0bf | |||
| 144f6809bf | |||
| d296e6021d | |||
| 45a855ef1f | |||
| e5f756205c | |||
| 6335fa8df1 | |||
| b2605206b1 | |||
| 33182650ca | |||
| 0ca1f82059 | |||
| 0c5cb4824b | |||
| cf83b796e1 | |||
| b338c81907 | |||
| 81b3e7e449 | |||
| 425ddd13e5 | |||
| eb8af974dc | |||
| 3067c8bd27 | |||
| 632c8872cd | |||
| 9650218bb8 | |||
| 0b51102167 | |||
| ca36d08893 | |||
| a358384900 | |||
| 77a75305c7 | |||
| 85b9809b39 | |||
| d36de7d54f | |||
| 2b1c757084 | |||
| e7db0c7d99 | |||
| 393e3b702f | |||
| 23ad687e7e | |||
| a04ecdbe0a | |||
| 9ee21af524 | |||
| b74cdcde00 | |||
| 4d83d749a0 | |||
| 8e66e719fa | |||
| c6e6f4afea | |||
| d0148728c6 | |||
| dfc564f837 | |||
| 2b0edf6cde | |||
| daa7520d1d | |||
| 3499d089e7 | |||
| 6b96a2022a | |||
| 3836b40bf7 | |||
| 571dbfb7b1 | |||
| 10e25eb362 | |||
| 45d0e821dc | |||
| e37a2a8f7d | |||
| 07c83f6e44 | |||
| 061824a7ec | |||
| abb56a354d | |||
| 9359b8c170 | |||
| 2d0f1f27a8 | |||
| 73312fc363 | |||
| deb590cb05 | |||
| 2033f3f7dc | |||
| 3e3160d7ac | |||
| dd919c76b8 | |||
| a6a0f13264 | |||
| b9a0c107ab | |||
| 5c93acefd9 | |||
| a428dac71c | |||
| 3901f08fa0 | |||
| 519f21db18 | |||
| 18d472b7e1 | |||
| bc098d6b9c | |||
| 22ff8abd7d | |||
| 871ccfd32c | |||
| 7a79e184c5 | |||
| 0e72cc879f | |||
| 13304bd18b | |||
| a4b824c50a | |||
| ccc87081f3 | |||
| 800ba9d902 | |||
| 015b9fdf8b | |||
| 83f93202d0 | |||
| ae2ea02377 | |||
| 4fe4521881 | |||
| b83575bcbb | |||
| 17175e1c23 | |||
| cc57719856 | |||
| b9b71ccbc1 | |||
| e789b969b0 | |||
| be44024a1a | |||
| c7d4a30646 | |||
| 837c5dddee | |||
| 669b1385cc | |||
| 01ffaab3e0 | |||
| d5fb7180d0 | |||
| b141b43c1c | |||
| cad91e114d | |||
| db51779682 | |||
| c18e71ca29 | |||
| 6a54b3929e | |||
| 07af701afe | |||
| 669d953529 | |||
| 22d8b57027 | |||
| 0e691e2c51 | |||
| ae1e9e78db | |||
| e00aedd1a0 | |||
| 4a10dcc549 | |||
| 553f67d7e3 | |||
| fac8a520f0 | |||
| f0358f85fc | |||
| 4b9fa8ec6d | |||
| 45cdf6af3b | |||
| 47685bef39 | |||
| b11f9e0405 | |||
| 84e7de0a78 | |||
| f39e2b999f | |||
| cd4b28b4d7 | |||
| 2db2114a45 | |||
| 4b11a62b4d | |||
| 0457f23b13 | |||
| a6ba7ed21c | |||
| 5326912bc0 | |||
| be46c82aaa | |||
| 43bae9f9d7 | |||
| 95231c4dee | |||
| a95e01290e | |||
| 0cbbd3a5b1 | |||
| d8f3354ce3 | |||
| e4105f46de | |||
| 9a1ee9e984 | |||
| 7c897d5019 | |||
| bfe2bccc51 | |||
| 11aa0be04a | |||
| d2cae96e8d | |||
| 8e955297ef | |||
| 205f6a9000 | |||
| 4558f93f92 | |||
| 634c411946 | |||
| d4d0d35e05 | |||
| f4f36a3cb1 | |||
| 21d70a75d5 | |||
| 47ed9aa1b9 | |||
| b60ac78c58 | |||
| 83e139cd1a | |||
| b415b0e737 | |||
| 2e510e5ca0 | |||
| 1262263f5c | |||
| 9b9e2bcafb | |||
| cde29aba64 | |||
| 34cf1ff7c7 | |||
| cc880b53aa | |||
| 8ad44dd00f | |||
| 9440e65452 | |||
| 5cb6815bf3 | |||
| caab400258 | |||
| d3f13ab8a3 | |||
| ca6064b109 |
@@ -0,0 +1,24 @@
|
||||
<!---
|
||||
|
||||
THIS IS NOT A SUPPORT FORUM, FOR SUPPORT GO TO:
|
||||
https://forums.rpcs3.net
|
||||
or our discord:
|
||||
https://discord.me/RPCS3
|
||||
|
||||
PLEASE READ THE GUIDELINES BEFORE OPENING AN ISSUE:
|
||||
https://github.com/RPCS3/rpcs3/blob/master/CONTRIBUTING.md
|
||||
|
||||
====================================================
|
||||
|
||||
When submitting an issue, please check the following:
|
||||
|
||||
- You have read the above.
|
||||
- You have provided the version (commit hash) of RPCS3 you are using.
|
||||
- You have provided sufficient detail for the issue to be reproduced.
|
||||
- You have provided system specs.
|
||||
- Please also provide:
|
||||
- For crashes, a backtrace.
|
||||
- For graphical issues, comparison screenshots with real hardware.
|
||||
|
||||
Remember that the GitHub Issue Tracker is not the place to ask for support or to submit Game Compatibility reports. You must use our forums for that.
|
||||
--->
|
||||
@@ -59,7 +59,6 @@ rpcs3/git-version.h
|
||||
|
||||
# Visual Studio Files
|
||||
.vs/*
|
||||
*.ipch
|
||||
*.vspx
|
||||
*.psess
|
||||
*.VC.*
|
||||
|
||||
+7
-10
@@ -8,16 +8,13 @@
|
||||
[submodule "llvm"]
|
||||
path = llvm
|
||||
url = https://github.com/llvm-mirror/llvm
|
||||
branch = release_50
|
||||
[submodule "rsx_program_decompiler"]
|
||||
path = rsx_program_decompiler
|
||||
url = https://github.com/RPCS3/rsx_program_decompiler
|
||||
branch = release_40
|
||||
[submodule "GSL"]
|
||||
path = 3rdparty/GSL
|
||||
url = https://github.com/Microsoft/GSL.git
|
||||
[submodule "libpng"]
|
||||
path = 3rdparty/libpng
|
||||
url = https://github.com/Zangetsu38/libpng
|
||||
url = https://github.com/RPCS3/libpng
|
||||
ignore = dirty
|
||||
[submodule "Vulkan/glslang"]
|
||||
path = Vulkan/glslang
|
||||
@@ -34,13 +31,13 @@
|
||||
[submodule "3rdparty/cereal"]
|
||||
path = 3rdparty/cereal
|
||||
url = https://github.com/USCiLab/cereal.git
|
||||
[submodule "rsx-debugger"]
|
||||
path = rsx-debugger
|
||||
url = https://github.com/RPCS3/rsx-debugger.git
|
||||
[submodule "3rdparty/zlib"]
|
||||
path = 3rdparty/zlib
|
||||
url = https://github.com/madler/zlib
|
||||
[submodule "3rdparty/hidapi"]
|
||||
path = 3rdparty/hidapi
|
||||
url = https://github.com/Zangetsu38/hidapi
|
||||
branch = master
|
||||
url = https://github.com/RPCS3/hidapi
|
||||
branch = master
|
||||
[submodule "3rdparty/Optional"]
|
||||
path = 3rdparty/Optional
|
||||
url = https://github.com/akrzemi1/Optional.git
|
||||
|
||||
+14
-43
@@ -1,6 +1,5 @@
|
||||
language: cpp
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
os:
|
||||
- linux
|
||||
@@ -17,19 +16,10 @@ cache:
|
||||
directories:
|
||||
- $HOME/hombebrew_cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: BXyNziNYFLqLtY6Q58BDEUpRJr81HUtHpxf2Sr646bDcbG0Rf2rb2utqHZJ1Om926WdH7RqHuoVti4dr2X1lh4nHMkLD7MrIrfIkNN5T9aZdk19uw9IyMtz/cXon7/wqVo24tVqtBI0UghFxKii/GTDJEvRKgfpPp1e1vKSNGa4=
|
||||
# Which Travis environment to run Coverity on
|
||||
- coverity_scan_run_condition='"$TRAVIS_OS_NAME" = linux -a "$CC" = gcc'
|
||||
# Test mode is for testing if it's working with Coverity. Change to true if testing, to avoid reaching the quota.
|
||||
- coverity_scan_script_test_mode=false
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
|
||||
|
||||
git:
|
||||
submodules: false
|
||||
@@ -40,7 +30,6 @@ before_install:
|
||||
fi;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CXX" = "g++" ]; then
|
||||
export CXX="g++-5" CC="gcc-5" CXXFLAGS="-Wno-format-security";
|
||||
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01';
|
||||
fi;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
wget http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run ;
|
||||
@@ -48,33 +37,24 @@ before_install:
|
||||
export QT_QPA_PLATFORM=minimal ;
|
||||
./qt-unified-linux-x64-online.run --script qt-installer-noninteractive.qs --no-force-installations ;
|
||||
fi;
|
||||
|
||||
# Add coverall for C++ so coverall.io could be triggered. Even it should be --coverage and gcov.
|
||||
|
||||
# Install updated libglew-dev since the version provided by trusty is outdated
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
pip install --user cpp-coveralls requests[security];
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew-dev_1.13.0-2_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew1.13_1.13.0-2_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
|
||||
sudo dpkg -i libglew1.13_1.13.0-2_amd64.deb libglew-dev_1.13.0-2_amd64.deb libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
|
||||
else
|
||||
brew update; brew update;
|
||||
brew update;
|
||||
brew install ccache glew llvm40;
|
||||
fi;
|
||||
# We need to update binutils to a newer version to link against the ffmpeg libs on.
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
sudo add-apt-repository ppa:jonathonf/binutils -y ;
|
||||
sudo apt-get update ;
|
||||
sudo apt-get install binutils -y;
|
||||
ld --version ;
|
||||
fi;
|
||||
|
||||
before_script:
|
||||
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
|
||||
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi 3rdparty/Optional Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
|
||||
- mkdir build
|
||||
- cd build
|
||||
- export CMAKE_PREFIX_PATH=~/Qt/5.9.1/gcc_64/lib/cmake
|
||||
- export CMAKE_PREFIX_PATH=~/Qt/5.9.2/gcc_64/lib/cmake
|
||||
- if [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH";
|
||||
else
|
||||
@@ -83,21 +63,21 @@ before_script:
|
||||
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
|
||||
- make -j 3
|
||||
- # AppImage generation
|
||||
- if [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export LD_LIBRARY_PATH=~/Qt/5.9.1/gcc_64/lib;
|
||||
- if [ -n "$UPLOAD_URL" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export LD_LIBRARY_PATH=~/Qt/5.9.2/gcc_64/lib;
|
||||
make DESTDIR=appdir install ; find appdir/ ;
|
||||
find ../bin ;
|
||||
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" ;
|
||||
chmod a+x linuxdeployqt*.AppImage ;
|
||||
export PATH=~/Qt/5.9.1/gcc_64/bin/:${PATH} ;
|
||||
export PATH=~/Qt/5.9.2/gcc_64/bin/:${PATH} ;
|
||||
./linuxdeployqt*.AppImage --appimage-extract ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
|
||||
mkdir ./appdir/usr/plugins/xcbglintegrations/ ;
|
||||
mkdir ./appdir/usr/plugins/imageformats/ ;
|
||||
cp ~/Qt/5.9.1/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
|
||||
cp ~/Qt/5.9.1/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
|
||||
cp ~/Qt/5.9.1/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
|
||||
cp ~/Qt/5.9.1/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
|
||||
export PATH=${TRAVIS_BUILD_DIR}/build/squashfs-root/usr/bin/:${PATH} ;
|
||||
./squashfs-root/usr/bin/appimagetool ${TRAVIS_BUILD_DIR}/build/appdir ;
|
||||
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
|
||||
@@ -109,14 +89,15 @@ script:
|
||||
#- echo "--Shell Export Lists START--" ; export -p; echo "--Shell Export Lists STOP--";
|
||||
# And to ensure the versions of toolchain
|
||||
- echo "--CXX version?"; "$CXX" --version; echo "--CXX version confirmed";
|
||||
#- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j 3; fi
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- sourceline: 'ppa:jonathonf/binutils' # We need to update binutils to a newer version to link against the ffmpeg libs on.
|
||||
packages:
|
||||
- binutils
|
||||
- cmake
|
||||
- libasound2-dev
|
||||
- libopenal-dev
|
||||
@@ -134,18 +115,8 @@ addons:
|
||||
- libstdc++-5-dev
|
||||
- lib32stdc++6
|
||||
- zlib1g-dev
|
||||
# We need to install qt 5.9.1 manually because the version trusty provides is too old.
|
||||
# We need to install qt 5.9.2 manually because the version trusty provides is too old.
|
||||
#- qtbase5-dev
|
||||
- libudev-dev
|
||||
- libevdev-dev
|
||||
- libpulse-dev
|
||||
coverity_scan:
|
||||
project:
|
||||
name: $TRAVIS_REPO_SLUG
|
||||
description: "PS3 emulator/debugger"
|
||||
notification_email: nekotekina@gmail.com
|
||||
build_command: "make -j 3"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
after_success:
|
||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "$TRAVIS_OS_NAME" = linux ]; then coveralls --extension .c --extension .cpp --extension .h; fi
|
||||
|
||||
+1
Submodule 3rdparty/Optional added at f27e79084a
Vendored
+1
-1
Submodule 3rdparty/hidapi updated: 4c2750112e...ca39ce8939
Vendored
+1
-1
Submodule 3rdparty/libpng updated: bbbcaf1122...1dcba4d6eb
@@ -3,7 +3,6 @@ RPCS3
|
||||
|
||||
[](https://travis-ci.org/RPCS3/rpcs3)
|
||||
[](https://ci.appveyor.com/project/rpcs3/rpcs3/branch/master)
|
||||
[](https://scan.coverity.com/projects/3960)
|
||||
|
||||
The world's first open-source PlayStation 3 emulator/debugger written in C++ for Windows and Linux.
|
||||
|
||||
@@ -21,22 +20,23 @@ If you want to contribute please take a look at the [Coding Style](https://githu
|
||||
## Dependencies
|
||||
|
||||
### Windows
|
||||
* [Visual Studio 2017](https://www.visualstudio.com/downloads/)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572)
|
||||
* [Visual Studio 2015](https://www.visualstudio.com/vs/older-downloads/)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
|
||||
* [Cmake 3.1.0+](https://www.cmake.org/download/) (required; add to PATH)
|
||||
* [Python 3.3+](https://www.python.org/downloads/) (required; add to PATH)
|
||||
* [Qt 5.9+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.9\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
|
||||
* [Qt 5.8+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.8\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
|
||||
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
|
||||
|
||||
### Linux
|
||||
* [Qt 5.9+](https://www.qt.io/download-open-source/)
|
||||
* [Qt 5.7+](https://www.qt.io/download-open-source/)
|
||||
* GCC 5.1+ or Clang 3.5.0+ ([not GCC 6.1](https://github.com/RPCS3/rpcs3/issues/1691))
|
||||
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default`
|
||||
* Arch: `sudo pacman -S glew openal cmake llvm qt5-base`
|
||||
* Fedora: `sudo dnf install cmake qt5-devel vulkan-devel glew glew-devel`
|
||||
**If you have a NVIDIA GPU, you may need to install the libglvnd package.**
|
||||
|
||||
### Mac OSX
|
||||
Mac OSX is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
|
||||
### MacOS
|
||||
MacOS is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
|
||||
* Xcode 6+ (tested with Xcode 6.4)
|
||||
* Install with Homebrew: `brew install glew llvm qt cmake`
|
||||
|
||||
@@ -47,7 +47,7 @@ To initialize the repository don't forget to execute `git submodule update --ini
|
||||
### Configuring Qt
|
||||
|
||||
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):*
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.9\msvc2017_64\` </br>
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.8\msvc2015_64\` </br>
|
||||
|
||||
*If you wish to use the Visual Studio plugin for Qt:* </br>
|
||||
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.8\msvc2015_64`. </br>
|
||||
@@ -58,15 +58,16 @@ To initialize the repository don't forget to execute `git submodule update --ini
|
||||
2) Press *BUILD* > *Build Solution* or *Rebuild Solution*. </br>
|
||||
|
||||
|
||||
## Building on Linux & Mac OSX:
|
||||
## Building on Linux & Mac OS:
|
||||
|
||||
1) `git clone https://github.com/RPCS3/rpcs3.git` </br>
|
||||
2) `cd rpcs3/` </br>
|
||||
3) `git submodule update --init` </br>
|
||||
4) `cmake CMakeLists.txt && make GitVersion && make` </br>
|
||||
4) `cd ../ && mkdir rpcs3_build && cd rpcs3_build`
|
||||
4) `cmake ../rpcs3/ && make GitVersion && make` </br>
|
||||
5) Run RPCS3 with `./bin/rpcs3` </br>
|
||||
|
||||
If you are on OSX and want to build with brew llvm and qt don't forget to add the following environment variables
|
||||
If you are on MacOS and want to build with brew llvm and qt don't forget to add the following environment variables
|
||||
|
||||
* `LLVM_DIR=/usr/local/opt/llvm/` (or wherever llvm was installed).
|
||||
* `Qt5_DIR=/usr/local/opt/qt/lib/cmake/Qt5` (or wherever qt was installed).
|
||||
@@ -74,14 +75,22 @@ If you are on OSX and want to build with brew llvm and qt don't forget to add th
|
||||
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
|
||||
|
||||
|
||||
## CMake Build Options (Linux & Mac OSX)
|
||||
## CMake Build Options (Linux & Mac OS)
|
||||
|
||||
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*) </br>
|
||||
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*)
|
||||
Build against the shared libpng instead of using the builtin one. libpng 1.6+ highly recommended. Try this option if you get version conflict errors or only see black game icons.
|
||||
|
||||
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*) </br>
|
||||
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*)
|
||||
Build against the shared ffmpeg libraries instead of using the builtin patched version. Try this if the builtin version breaks the OpenGL renderer for you.
|
||||
|
||||
- ```-DWITHOUT_LLVM=ON/OFF``` (default = *OFF*)
|
||||
This forces RPCS3 to build without LLVM, not recommended.
|
||||
|
||||
- ```-DWITH_GDB=ON/OFF``` (default = *OFF*)
|
||||
This Builds RPCS3 with support for debugging PS3 games using gdb.
|
||||
|
||||
- ```-DUSE_VULKAN=ON/OFF``` (default = *ON*)
|
||||
This builds RPCS3 with Vulkan support.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
logs::channel cfg("CFG");
|
||||
|
||||
+13
-17
@@ -8,6 +8,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <typeinfo>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
@@ -94,6 +95,8 @@ static fs::error to_error(DWORD e)
|
||||
case ERROR_DIRECTORY: return fs::error::inval;
|
||||
case ERROR_INVALID_NAME: return fs::error::inval;
|
||||
case ERROR_SHARING_VIOLATION: return fs::error::acces;
|
||||
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
|
||||
case ERROR_NOT_READY: return fs::error::noent;
|
||||
default: fmt::throw_exception("Unknown Win32 error: %u.", e);
|
||||
}
|
||||
}
|
||||
@@ -128,6 +131,7 @@ static fs::error to_error(int e)
|
||||
case EEXIST: return fs::error::exist;
|
||||
case EINVAL: return fs::error::inval;
|
||||
case EACCES: return fs::error::acces;
|
||||
case ENOTEMPTY: return fs::error::notempty;
|
||||
default: fmt::throw_exception("Unknown system error: %d.", e);
|
||||
}
|
||||
}
|
||||
@@ -675,18 +679,17 @@ bool fs::truncate_file(const std::string& path, u64 length)
|
||||
|
||||
#ifdef _WIN32
|
||||
// Open the file
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
LARGE_INTEGER distance;
|
||||
distance.QuadPart = length;
|
||||
FILE_END_OF_FILE_INFO _eof;
|
||||
_eof.EndOfFile.QuadPart = length;
|
||||
|
||||
// Seek and truncate
|
||||
if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN) || !SetEndOfFile(handle))
|
||||
if (!SetFileInformationByHandle(handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -715,7 +718,7 @@ bool fs::utime(const std::string& path, s64 atime, s64 mtime)
|
||||
|
||||
#ifdef _WIN32
|
||||
// Open the file
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
@@ -846,23 +849,15 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
bool trunc(u64 length) override
|
||||
{
|
||||
LARGE_INTEGER old, pos;
|
||||
FILE_END_OF_FILE_INFO _eof;
|
||||
_eof.EndOfFile.QuadPart = length;
|
||||
|
||||
pos.QuadPart = 0;
|
||||
if (!SetFilePointerEx(m_handle, pos, &old, FILE_CURRENT)) // get old position
|
||||
if (!SetFileInformationByHandle(m_handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
pos.QuadPart = length;
|
||||
if (!SetFilePointerEx(m_handle, pos, NULL, FILE_BEGIN)) // set new position
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
verify("file::trunc" HERE), SetEndOfFile(m_handle), SetFilePointerEx(m_handle, old, NULL, FILE_BEGIN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1458,6 +1453,7 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
|
||||
case fs::error::noent: return "Not found";
|
||||
case fs::error::exist: return "Already exists";
|
||||
case fs::error::acces: return "Access violation";
|
||||
case fs::error::notempty: return "Not empty";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
|
||||
@@ -502,6 +502,7 @@ namespace fs
|
||||
noent,
|
||||
exist,
|
||||
acces,
|
||||
notempty,
|
||||
};
|
||||
|
||||
// Error code returned
|
||||
|
||||
+2
-2
@@ -258,11 +258,11 @@ struct MemoryManager : llvm::RTDyldMemoryManager
|
||||
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
|
||||
}
|
||||
|
||||
virtual void deregisterEHFrames() override
|
||||
virtual void deregisterEHFrames(u8* addr, u64 load_addr, std::size_t size) override
|
||||
{
|
||||
LOG_ERROR(GENERAL, "deregisterEHFrames() called"); // Not expected
|
||||
|
||||
return RTDyldMemoryManager::deregisterEHFrames();
|
||||
return RTDyldMemoryManager::deregisterEHFrames(addr, load_addr, size);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
|
||||
* https://github.com/corporateshark/LUrlParser
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "LUrlParser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
// check if the scheme name is valid
|
||||
static bool IsSchemeValid( const std::string& SchemeName )
|
||||
{
|
||||
for ( auto c : SchemeName )
|
||||
{
|
||||
if ( !isalpha( c ) && c != '+' && c != '-' && c != '.' ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LUrlParser::clParseURL::GetPort( int* OutPort ) const
|
||||
{
|
||||
if ( !IsValid() ) { return false; }
|
||||
|
||||
int Port = atoi( m_Port.c_str() );
|
||||
|
||||
if ( Port <= 0 || Port > 65535 ) { return false; }
|
||||
|
||||
if ( OutPort ) { *OutPort = Port; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// based on RFC 1738 and RFC 3986
|
||||
LUrlParser::clParseURL LUrlParser::clParseURL::ParseURL( const std::string& URL )
|
||||
{
|
||||
LUrlParser::clParseURL Result;
|
||||
|
||||
const char* CurrentString = URL.c_str();
|
||||
|
||||
/*
|
||||
* <scheme>:<scheme-specific-part>
|
||||
* <scheme> := [a-z\+\-\.]+
|
||||
* For resiliency, programs interpreting URLs should treat upper case letters as equivalent to lower case in scheme names
|
||||
*/
|
||||
|
||||
// try to read scheme
|
||||
{
|
||||
const char* LocalString = strchr( CurrentString, ':' );
|
||||
|
||||
if ( !LocalString )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoUrlCharacter );
|
||||
}
|
||||
|
||||
// save the scheme name
|
||||
Result.m_Scheme = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
if ( !IsSchemeValid( Result.m_Scheme ) )
|
||||
{
|
||||
return clParseURL( LUrlParserError_InvalidSchemeName );
|
||||
}
|
||||
|
||||
// scheme should be lowercase
|
||||
std::transform( Result.m_Scheme.begin(), Result.m_Scheme.end(), Result.m_Scheme.begin(), ::tolower );
|
||||
|
||||
// skip ':'
|
||||
CurrentString = LocalString+1;
|
||||
}
|
||||
|
||||
/*
|
||||
* //<user>:<password>@<host>:<port>/<url-path>
|
||||
* any ":", "@" and "/" must be normalized
|
||||
*/
|
||||
|
||||
// skip "//"
|
||||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
|
||||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
|
||||
|
||||
// check if the user name and password are specified
|
||||
bool bHasUserName = false;
|
||||
|
||||
const char* LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString )
|
||||
{
|
||||
if ( *LocalString == '@' )
|
||||
{
|
||||
// user name and password are specified
|
||||
bHasUserName = true;
|
||||
break;
|
||||
}
|
||||
else if ( *LocalString == '/' )
|
||||
{
|
||||
// end of <host>:<port> specification
|
||||
bHasUserName = false;
|
||||
break;
|
||||
}
|
||||
|
||||
LocalString++;
|
||||
}
|
||||
|
||||
// user name and password
|
||||
LocalString = CurrentString;
|
||||
|
||||
if ( bHasUserName )
|
||||
{
|
||||
// read user name
|
||||
while ( *LocalString && *LocalString != ':' && *LocalString != '@' ) LocalString++;
|
||||
|
||||
Result.m_UserName = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
// proceed with the current pointer
|
||||
CurrentString = LocalString;
|
||||
|
||||
if ( *CurrentString == ':' )
|
||||
{
|
||||
// skip ':'
|
||||
CurrentString++;
|
||||
|
||||
// read password
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '@' ) LocalString++;
|
||||
|
||||
Result.m_Password = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// skip '@'
|
||||
if ( *CurrentString != '@' )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoAtSign );
|
||||
}
|
||||
|
||||
CurrentString++;
|
||||
}
|
||||
|
||||
bool bHasBracket = ( *CurrentString == '[' );
|
||||
|
||||
// go ahead, read the host name
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString )
|
||||
{
|
||||
if ( bHasBracket && *LocalString == ']' )
|
||||
{
|
||||
// end of IPv6 address
|
||||
LocalString++;
|
||||
break;
|
||||
}
|
||||
else if ( !bHasBracket && ( *LocalString == ':' || *LocalString == '/' ) )
|
||||
{
|
||||
// port number is specified
|
||||
break;
|
||||
}
|
||||
|
||||
LocalString++;
|
||||
}
|
||||
|
||||
Result.m_Host = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
|
||||
// is port number specified?
|
||||
if ( *CurrentString == ':' )
|
||||
{
|
||||
CurrentString++;
|
||||
|
||||
// read port number
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '/' ) LocalString++;
|
||||
|
||||
Result.m_Port = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// end of string
|
||||
if ( !*CurrentString )
|
||||
{
|
||||
Result.m_ErrorCode = LUrlParserError_Ok;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// skip '/'
|
||||
if ( *CurrentString != '/' )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoSlash );
|
||||
}
|
||||
|
||||
CurrentString++;
|
||||
|
||||
// parse the path
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '#' && *LocalString != '?' ) LocalString++;
|
||||
|
||||
Result.m_Path = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
|
||||
// check for query
|
||||
if ( *CurrentString == '?' )
|
||||
{
|
||||
// skip '?'
|
||||
CurrentString++;
|
||||
|
||||
// read query
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '#' ) LocalString++;
|
||||
|
||||
Result.m_Query = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// check for fragment
|
||||
if ( *CurrentString == '#' )
|
||||
{
|
||||
// skip '#'
|
||||
CurrentString++;
|
||||
|
||||
// read fragment
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString ) LocalString++;
|
||||
|
||||
Result.m_Fragment = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
Result.m_ErrorCode = LUrlParserError_Ok;
|
||||
|
||||
return Result;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
|
||||
* https://github.com/corporateshark/LUrlParser
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace LUrlParser
|
||||
{
|
||||
enum LUrlParserError
|
||||
{
|
||||
LUrlParserError_Ok = 0,
|
||||
LUrlParserError_Uninitialized = 1,
|
||||
LUrlParserError_NoUrlCharacter = 2,
|
||||
LUrlParserError_InvalidSchemeName = 3,
|
||||
LUrlParserError_NoDoubleSlash = 4,
|
||||
LUrlParserError_NoAtSign = 5,
|
||||
LUrlParserError_UnexpectedEndOfLine = 6,
|
||||
LUrlParserError_NoSlash = 7,
|
||||
};
|
||||
|
||||
class clParseURL
|
||||
{
|
||||
public:
|
||||
LUrlParserError m_ErrorCode;
|
||||
std::string m_Scheme;
|
||||
std::string m_Host;
|
||||
std::string m_Port;
|
||||
std::string m_Path;
|
||||
std::string m_Query;
|
||||
std::string m_Fragment;
|
||||
std::string m_UserName;
|
||||
std::string m_Password;
|
||||
|
||||
clParseURL()
|
||||
: m_ErrorCode( LUrlParserError_Uninitialized )
|
||||
{}
|
||||
|
||||
/// return 'true' if the parsing was successful
|
||||
bool IsValid() const { return m_ErrorCode == LUrlParserError_Ok; }
|
||||
|
||||
/// helper to convert the port number to int, return 'true' if the port is valid (within the 0..65535 range)
|
||||
bool GetPort( int* OutPort ) const;
|
||||
|
||||
/// parse the URL
|
||||
static clParseURL ParseURL( const std::string& URL );
|
||||
|
||||
private:
|
||||
explicit clParseURL( LUrlParserError ErrorCode )
|
||||
: m_ErrorCode( ErrorCode )
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace LUrlParser
|
||||
+50
-49
@@ -76,6 +76,30 @@ namespace logs
|
||||
void log(logs::level sev, const char* text, std::size_t size);
|
||||
};
|
||||
|
||||
struct channel_info
|
||||
{
|
||||
channel* pointer = nullptr;
|
||||
level enabled = level::notice;
|
||||
|
||||
void set_level(level value)
|
||||
{
|
||||
enabled = value;
|
||||
|
||||
if (pointer)
|
||||
{
|
||||
pointer->enabled = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct stored_message
|
||||
{
|
||||
message m;
|
||||
u64 stamp;
|
||||
std::string prefix;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
struct file_listener : public file_writer, public listener
|
||||
{
|
||||
file_listener(const std::string& name);
|
||||
@@ -84,6 +108,12 @@ namespace logs
|
||||
|
||||
// Encode level, current thread name, channel name and write log message
|
||||
virtual void log(u64 stamp, const message& msg, const std::string& prefix, const std::string& text) override;
|
||||
|
||||
// Channel registry
|
||||
std::unordered_map<std::string, channel_info> channels;
|
||||
|
||||
// Messages for delayed listener initialization
|
||||
std::vector<stored_message> messages;
|
||||
};
|
||||
|
||||
static file_listener* get_logger()
|
||||
@@ -135,39 +165,9 @@ namespace logs
|
||||
channel SPU("SPU");
|
||||
channel ARMv7("ARMv7");
|
||||
|
||||
struct channel_info
|
||||
{
|
||||
channel* pointer = nullptr;
|
||||
level enabled = level::notice;
|
||||
|
||||
void set_level(level value)
|
||||
{
|
||||
enabled = value;
|
||||
|
||||
if (pointer)
|
||||
{
|
||||
pointer->enabled = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct stored_message
|
||||
{
|
||||
message m;
|
||||
u64 stamp;
|
||||
std::string prefix;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
// Channel registry mutex
|
||||
semaphore<> g_mutex;
|
||||
|
||||
// Channel registry
|
||||
std::unordered_map<std::string, channel_info> g_channels;
|
||||
|
||||
// Messages for delayed listener initialization
|
||||
std::vector<stored_message> g_messages;
|
||||
|
||||
// Must be set to true in main()
|
||||
atomic_t<bool> g_init{false};
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace logs
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
for (auto&& pair : g_channels)
|
||||
for (auto&& pair : get_logger()->channels)
|
||||
{
|
||||
pair.second.set_level(level::notice);
|
||||
}
|
||||
@@ -185,7 +185,7 @@ namespace logs
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
g_channels[ch_name].set_level(value);
|
||||
get_logger()->channels[ch_name].set_level(value);
|
||||
}
|
||||
|
||||
// Must be called in main() to stop accumulating messages in g_messages
|
||||
@@ -194,7 +194,7 @@ namespace logs
|
||||
if (!g_init)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
g_messages.clear();
|
||||
get_logger()->messages.clear();
|
||||
g_init = true;
|
||||
}
|
||||
}
|
||||
@@ -218,7 +218,7 @@ void logs::listener::add(logs::listener* _new)
|
||||
}
|
||||
|
||||
// Send initial messages
|
||||
for (const auto& msg : g_messages)
|
||||
for (const auto& msg : get_logger()->messages)
|
||||
{
|
||||
_new->log(msg.stamp, msg.m, msg.prefix, msg.text);
|
||||
}
|
||||
@@ -234,7 +234,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
auto& info = g_channels[ch->name];
|
||||
auto& info = get_logger()->channels[ch->name];
|
||||
|
||||
if (info.pointer && info.pointer != ch)
|
||||
{
|
||||
@@ -274,10 +274,10 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
}
|
||||
|
||||
// Store message additionally
|
||||
g_messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
|
||||
get_logger()->messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Send message to all listeners
|
||||
while (lis)
|
||||
{
|
||||
@@ -289,11 +289,11 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
[[noreturn]] extern void catch_all_exceptions();
|
||||
|
||||
logs::file_writer::file_writer(const std::string& name)
|
||||
: m_name(fs::get_config_dir() + name)
|
||||
: m_name(name)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!m_file.open(m_name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
|
||||
if (!m_file.open(fs::get_config_dir() + name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
|
||||
{
|
||||
fmt::throw_exception("Can't create file %s (error %s)", name, fs::g_tls_error);
|
||||
}
|
||||
@@ -306,11 +306,13 @@ logs::file_writer::file_writer(const std::string& name)
|
||||
m_fptr = (uchar*)::mmap(0, s_log_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_file.get_handle(), 0);
|
||||
#endif
|
||||
|
||||
verify(m_name.c_str()), m_fptr;
|
||||
verify(name.c_str()), m_fptr;
|
||||
std::memset(m_fptr, '\n', s_log_size);
|
||||
|
||||
// Rotate backups (TODO)
|
||||
fs::rename(m_name + ".gz", m_name + "1.gz", true);
|
||||
fs::remove_file(fs::get_config_dir() + name + "1.gz");
|
||||
fs::create_dir(fs::get_config_dir() + "old_logs");
|
||||
fs::rename(fs::get_config_dir() + m_name + ".gz", fs::get_config_dir() + "old_logs/" + m_name + ".gz", true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -337,7 +339,7 @@ logs::file_writer::~file_writer()
|
||||
|
||||
if (deflate(&zs, Z_FINISH) != Z_STREAM_ERROR)
|
||||
{
|
||||
fs::file(m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
|
||||
fs::file(fs::get_config_dir() + m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
|
||||
}
|
||||
|
||||
if (deflateEnd(&zs) != Z_OK)
|
||||
@@ -348,12 +350,10 @@ logs::file_writer::~file_writer()
|
||||
#ifdef _WIN32
|
||||
UnmapViewOfFile(m_fptr);
|
||||
CloseHandle(m_fmap);
|
||||
m_file.seek(m_size);
|
||||
SetEndOfFile(m_file.get_handle());
|
||||
#else
|
||||
::munmap(m_fptr, s_log_size);
|
||||
m_file.trunc(m_size);
|
||||
#endif
|
||||
m_file.trunc(m_size);
|
||||
}
|
||||
|
||||
void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||
@@ -395,10 +395,11 @@ logs::file_listener::file_listener(const std::string& name)
|
||||
ver.m.ch = nullptr;
|
||||
ver.m.sev = level::always;
|
||||
ver.stamp = 0;
|
||||
ver.text = fmt::format("RPCS3 v%s\n%s", rpcs3::version.to_string(), utils::get_system_info());
|
||||
ver.text = fmt::format("RPCS3 v%s | %s\n%s", rpcs3::version.to_string(), rpcs3::get_branch(), utils::get_system_info());
|
||||
|
||||
file_writer::log(logs::level::always, ver.text.data(), ver.text.size());
|
||||
file_writer::log(logs::level::always, "\n", 1);
|
||||
g_messages.emplace_back(std::move(ver));
|
||||
messages.emplace_back(std::move(ver));
|
||||
}
|
||||
|
||||
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
|
||||
@@ -431,7 +432,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
text += prefix;
|
||||
text += "} ";
|
||||
}
|
||||
|
||||
|
||||
if (msg.ch && '\0' != *msg.ch->name)
|
||||
{
|
||||
text += msg.ch->name;
|
||||
@@ -441,7 +442,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
{
|
||||
text += "TODO: ";
|
||||
}
|
||||
|
||||
|
||||
text += _text;
|
||||
text += '\n';
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class MTProgressDialog : public wxDialog
|
||||
{
|
||||
wxGauge** m_gauge;
|
||||
wxStaticText** m_msg;
|
||||
|
||||
wxArrayLong m_maximum;
|
||||
const u8 m_cores;
|
||||
|
||||
static const uint layout = 16;
|
||||
static const uint maxdial = 65536;
|
||||
wxArrayInt m_lastupdate;
|
||||
|
||||
public:
|
||||
MTProgressDialog(wxWindow* parent, const wxSize& size, const wxString& title,
|
||||
const wxString& msg, const wxArrayLong& maximum, const u8 cores)
|
||||
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition)
|
||||
, m_maximum(maximum)
|
||||
, m_cores(cores)
|
||||
{
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_gauge = new wxGauge*[m_cores];
|
||||
m_msg = new wxStaticText*[m_cores];
|
||||
|
||||
m_lastupdate.SetCount(cores);
|
||||
|
||||
for(uint i=0; i<m_cores; ++i)
|
||||
{
|
||||
m_lastupdate[i] = -1;
|
||||
|
||||
m_msg[i] = new wxStaticText(this, wxID_ANY, msg);
|
||||
sizer->Add(m_msg[i], 0, wxLEFT | wxTOP, layout);
|
||||
|
||||
m_gauge[i] = new wxGauge(this, wxID_ANY, maxdial,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxGA_HORIZONTAL );
|
||||
|
||||
sizer->Add(m_gauge[i], 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, layout);
|
||||
m_gauge[i]->SetValue(0);
|
||||
|
||||
sizer->AddSpacer(5);
|
||||
}
|
||||
|
||||
SetSizerAndFit(sizer);
|
||||
if(size != wxDefaultSize)
|
||||
{
|
||||
SetSize(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxSize ws;
|
||||
ws.x = 400;
|
||||
ws.y = GetSize().y + 8;
|
||||
SetSize(ws);
|
||||
}
|
||||
|
||||
m_maximum.SetCount(m_cores);
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
void Update(const u8 thread_id, const u64 value, const wxString& msg)
|
||||
{
|
||||
if(thread_id > m_cores) return;
|
||||
|
||||
const int curupdate = (int)(((double)value/(double)m_maximum[thread_id])*1000);
|
||||
if(curupdate == m_lastupdate[thread_id]) return;
|
||||
m_lastupdate[thread_id] = curupdate;
|
||||
|
||||
m_msg[thread_id]->SetLabel(msg);
|
||||
|
||||
if(value >= (u32)m_maximum[thread_id]) return;
|
||||
m_gauge[thread_id]->SetValue(((double)value / (double)m_maximum[thread_id]) * maxdial);
|
||||
}
|
||||
|
||||
const u32 GetMaxValue(const uint thread_id) const
|
||||
{
|
||||
if(thread_id > m_cores) return 0;
|
||||
return m_maximum[thread_id];
|
||||
}
|
||||
|
||||
void SetMaxFor(const uint thread_id, const u64 val)
|
||||
{
|
||||
if(thread_id > m_cores) return;
|
||||
m_maximum[thread_id] = val;
|
||||
m_lastupdate[thread_id] = 0;
|
||||
}
|
||||
|
||||
virtual void Close(bool force = false)
|
||||
{
|
||||
m_lastupdate.Empty();
|
||||
m_maximum.Empty();
|
||||
|
||||
wxDialog::Close(force);
|
||||
}
|
||||
};
|
||||
+76
-12
@@ -3,7 +3,10 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_mmapper.h"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "Thread.h"
|
||||
#include <typeinfo>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
@@ -1258,9 +1261,60 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
|
||||
if (cpu)
|
||||
{
|
||||
if (fxm::check<page_fault_notification_entries>())
|
||||
{
|
||||
for (const auto& entry : fxm::get<page_fault_notification_entries>()->entries)
|
||||
{
|
||||
auto mem = vm::get(vm::any, entry.start_addr);
|
||||
if (!mem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry.start_addr <= addr && addr <= addr + mem->size - 1)
|
||||
{
|
||||
// Place the page fault event onto table so that other functions [sys_mmapper_free_address and ppu pagefault funcs]
|
||||
// know that this thread is page faulted and where.
|
||||
|
||||
auto pf_entries = fxm::get_always<page_fault_event_entries>();
|
||||
{
|
||||
semaphore_lock pf_lock(pf_entries->pf_mutex);
|
||||
page_fault_event pf_event{ cpu->id, addr };
|
||||
pf_entries->events.emplace_back(pf_event);
|
||||
}
|
||||
|
||||
// Now, 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.
|
||||
be_t<u64> data1 = addr;
|
||||
be_t<u64> data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_PPU_THREAD << 32) + cpu->id; // TODO: fix hack for now that assumes PPU thread always.
|
||||
be_t<u64> data3 = vm::check_addr(addr, a_size, vm::page_readable) ? SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY : SYS_MEMORY_PAGE_FAULT_CAUSE_NON_MAPPED;
|
||||
|
||||
LOG_ERROR(MEMORY, "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");
|
||||
|
||||
error_code sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);
|
||||
|
||||
// If we fail due to being busy, wait a bit and try again.
|
||||
while (sending_error == CELL_EBUSY)
|
||||
{
|
||||
lv2_obj::sleep(*cpu, 1000);
|
||||
thread_ctrl::wait_for(1000);
|
||||
sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);
|
||||
}
|
||||
|
||||
if (sending_error)
|
||||
{
|
||||
fmt::throw_exception("Unknown error %x while trying to pass page fault.", sending_error.value);
|
||||
}
|
||||
|
||||
lv2_obj::sleep(*cpu);
|
||||
thread_ctrl::wait();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
|
||||
cpu->state += cpu_flag::dbg_pause;
|
||||
cpu->check_state();
|
||||
@@ -1830,20 +1884,30 @@ void thread_ctrl::set_native_priority(int priority)
|
||||
HANDLE _this_thread = GetCurrentThread();
|
||||
INT native_priority = THREAD_PRIORITY_NORMAL;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (priority > 0)
|
||||
native_priority = THREAD_PRIORITY_ABOVE_NORMAL;
|
||||
break;
|
||||
case -1:
|
||||
if (priority < 0)
|
||||
native_priority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
SetThreadPriority(_this_thread, native_priority);
|
||||
if (!SetThreadPriority(_this_thread, native_priority))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "SetThreadPriority() failed: 0x%x", GetLastError());
|
||||
}
|
||||
#else
|
||||
int policy;
|
||||
struct sched_param param;
|
||||
|
||||
pthread_getschedparam(pthread_self(), &policy, ¶m);
|
||||
|
||||
if (priority > 0)
|
||||
param.sched_priority = sched_get_priority_max(policy);
|
||||
if (priority < 0)
|
||||
param.sched_priority = sched_get_priority_min(policy);
|
||||
|
||||
if (int err = pthread_setschedparam(pthread_self(), policy, ¶m))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "pthraed_setschedparam() failed: %d", err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace utils
|
||||
void memory_decommit(void* pointer, std::size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
verify(HERE), ::VirtualFree(pointer, 0, MEM_DECOMMIT);
|
||||
verify(HERE), ::VirtualFree(pointer, size, MEM_DECOMMIT);
|
||||
#else
|
||||
verify(HERE), ::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
|
||||
+30
-1
@@ -10,6 +10,7 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case patch_type::load: return "load";
|
||||
case patch_type::byte: return "byte";
|
||||
case patch_type::le16: return "le16";
|
||||
case patch_type::le32: return "le32";
|
||||
@@ -45,10 +46,33 @@ void patch_engine::append(const std::string& patch)
|
||||
|
||||
struct patch info{};
|
||||
info.type = static_cast<patch_type>(type64);
|
||||
info.offset = patch[1].as<u32>();
|
||||
info.offset = patch[1].as<u32>(0);
|
||||
|
||||
switch (info.type)
|
||||
{
|
||||
case patch_type::load:
|
||||
{
|
||||
// Special syntax: copy named sequence (must be loaded before)
|
||||
const auto found = m_map.find(patch[1].Scalar());
|
||||
|
||||
if (found != m_map.end())
|
||||
{
|
||||
// Address modifier (optional)
|
||||
const u32 mod = patch[2].as<u32>(0);
|
||||
|
||||
for (const auto& rd : found->second)
|
||||
{
|
||||
info = rd;
|
||||
info.offset += mod;
|
||||
data.emplace_back(info);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: error
|
||||
break;
|
||||
}
|
||||
case patch_type::bef32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
@@ -90,6 +114,11 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
|
||||
switch (p.type)
|
||||
{
|
||||
case patch_type::load:
|
||||
{
|
||||
// Invalid in this context
|
||||
break;
|
||||
}
|
||||
case patch_type::byte:
|
||||
{
|
||||
*ptr = static_cast<u8>(p.value);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
enum class patch_type
|
||||
{
|
||||
load,
|
||||
byte,
|
||||
le16,
|
||||
le32,
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
Copyright (C) 2011-2012 Andrzej Krzemienski
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0
|
||||
(see accompanying file LICENSE_1_0.txt or a copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
The idea and interface is based on Boost.Optional library
|
||||
authored by Fernando Luis Cacciola Carballal
|
||||
|
||||
Home at https://github.com/akrzemi1/Optional
|
||||
@@ -731,9 +731,9 @@ struct area_base
|
||||
{
|
||||
return{ x1 * size.width, y1 * size.height, x2 * size.width, y2 * size.height };
|
||||
}
|
||||
constexpr area_base operator * (const T& value) const
|
||||
constexpr area_base operator * (const f32& value) const
|
||||
{
|
||||
return{ x1 * value, y1 * value, x2 * value, y2 * value };
|
||||
return{ (T)(x1 * value), (T)(y1 * value), (T)(x2 * value), (T)(y2 * value) };
|
||||
}
|
||||
|
||||
template<typename NT>
|
||||
|
||||
@@ -16,6 +16,7 @@ rem // Official git repository and contact information can be found at
|
||||
rem // https://github.com/RPCS3/rpcs3 and http://rpcs3.net/.
|
||||
|
||||
setlocal ENABLEDELAYEDEXPANSION
|
||||
setlocal ENABLEEXTENSIONS
|
||||
|
||||
set GIT_VERSION_FILE=%~p0..\rpcs3\git-version.h
|
||||
if not defined GIT (
|
||||
@@ -47,15 +48,43 @@ if errorlevel 1 (
|
||||
echo // This is a generated file. > "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION "unknown" >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_BRANCH "unknown" >> "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%"
|
||||
goto done
|
||||
)
|
||||
|
||||
rem // Get commit count from HEAD by default
|
||||
for /F %%I IN ('call %GIT% rev-list HEAD --count') do set GIT_VERSION=%%I
|
||||
|
||||
rem // If we're in AppVeyor and we're building for master: Get commit count from unshallowed upstream
|
||||
if defined APPVEYOR (
|
||||
if not defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
|
||||
call %GIT% remote add upstream https://github.com/RPCS3/RPCS3.git
|
||||
call %GIT% fetch --unshallow upstream
|
||||
for /F %%I IN ('call %GIT% rev-list --count upstream/master') do set GIT_VERSION=%%I
|
||||
)
|
||||
)
|
||||
|
||||
if defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
|
||||
if "%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"=="master" (
|
||||
for /f "tokens=1* delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set user=%%a
|
||||
set "GIT_BRANCH=!user!/%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"
|
||||
) else (
|
||||
set GIT_BRANCH=%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%
|
||||
)
|
||||
|
||||
) else (
|
||||
for /F %%I IN ('call %GIT% rev-parse --abbrev-ref HEAD') do set GIT_BRANCH=%%I
|
||||
)
|
||||
|
||||
rem // Get last commit (shortened) and concat after commit count in GIT_VERSION
|
||||
for /F %%I IN ('call %GIT% rev-parse --short HEAD') do set GIT_VERSION=%GIT_VERSION%-%%I
|
||||
|
||||
rem // Echo obtained GIT_VERSION for debug purposes if needed
|
||||
echo %GIT_VERSION%
|
||||
|
||||
rem // Don't modify the file if it already has the current version.
|
||||
if exist "%GIT_VERSION_FILE%" (
|
||||
findstr /C:"%GIT_VERSION%" "%GIT_VERSION_FILE%" > NUL
|
||||
@@ -67,6 +96,7 @@ if exist "%GIT_VERSION_FILE%" (
|
||||
echo // This is a generated file. > "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION "%GIT_VERSION%" >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_BRANCH ^"%GIT_BRANCH%^" >> "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%"
|
||||
|
||||
+83
-1
@@ -1,7 +1,12 @@
|
||||
#include "mutex.h"
|
||||
#include "sync.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <climits>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
// TLS variable for tracking owned mutexes
|
||||
thread_local std::vector<shared_mutex*> g_tls_locks;
|
||||
|
||||
void shared_mutex::imp_lock_shared(s64 _old)
|
||||
{
|
||||
@@ -217,12 +222,14 @@ void shared_mutex::imp_unlock(s64 _old)
|
||||
|
||||
void shared_mutex::imp_lock_upgrade()
|
||||
{
|
||||
// TODO
|
||||
unlock_shared();
|
||||
lock();
|
||||
}
|
||||
|
||||
void shared_mutex::imp_lock_degrade()
|
||||
{
|
||||
// TODO
|
||||
unlock();
|
||||
lock_shared();
|
||||
}
|
||||
@@ -250,3 +257,78 @@ bool shared_mutex::try_lock_degrade()
|
||||
// TODO
|
||||
return m_value.compare_and_swap_test(0, c_one - c_min);
|
||||
}
|
||||
|
||||
safe_reader_lock::safe_reader_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
, m_is_owned(false)
|
||||
{
|
||||
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||
{
|
||||
m_is_owned = true;
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
g_tls_locks.emplace_back(&m_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
}
|
||||
|
||||
safe_reader_lock::~safe_reader_lock()
|
||||
{
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.unlock_shared();
|
||||
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
safe_writer_lock::safe_writer_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
, m_is_owned(false)
|
||||
, m_is_upgraded(false)
|
||||
{
|
||||
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||
{
|
||||
m_is_owned = true;
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
g_tls_locks.emplace_back(&m_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
if (m_mutex.is_reading())
|
||||
{
|
||||
m_is_upgraded = true;
|
||||
m_mutex.lock_upgrade();
|
||||
}
|
||||
}
|
||||
|
||||
safe_writer_lock::~safe_writer_lock()
|
||||
{
|
||||
if (m_is_upgraded)
|
||||
{
|
||||
m_mutex.lock_degrade();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.unlock();
|
||||
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
@@ -95,6 +95,11 @@ public:
|
||||
imp_lock_degrade();
|
||||
}
|
||||
}
|
||||
|
||||
bool is_reading() const
|
||||
{
|
||||
return (m_value.load() % c_one) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Simplified shared (reader) lock implementation.
|
||||
@@ -171,3 +176,56 @@ public:
|
||||
unlock();
|
||||
}
|
||||
};
|
||||
|
||||
// Safe reader lock. Can be recursive above other safe locks (reader or writer).
|
||||
class safe_reader_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
bool m_is_owned;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock_shared();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
||||
public:
|
||||
safe_reader_lock(const safe_reader_lock&) = delete;
|
||||
|
||||
explicit safe_reader_lock(shared_mutex& mutex);
|
||||
|
||||
~safe_reader_lock();
|
||||
};
|
||||
|
||||
// Safe writer lock. Can be recursive above other safe locks. Performs upgrade and degrade operations above existing reader lock if necessary.
|
||||
class safe_writer_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
bool m_is_owned;
|
||||
bool m_is_upgraded;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
||||
public:
|
||||
safe_writer_lock(const safe_writer_lock&) = delete;
|
||||
|
||||
explicit safe_writer_lock(shared_mutex& mutex);
|
||||
|
||||
~safe_writer_lock();
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2
-3
@@ -61,10 +61,9 @@ rXmlDocument::rXmlDocument() : handle()
|
||||
{
|
||||
}
|
||||
|
||||
void rXmlDocument::Load(const std::string & path)
|
||||
void rXmlDocument::Read(const std::string& data)
|
||||
{
|
||||
// TODO: Unsure of use of c_str.
|
||||
handle.load_file(path.c_str());
|
||||
handle.load_buffer(data.data(), data.size());
|
||||
}
|
||||
|
||||
std::shared_ptr<rXmlNode> rXmlDocument::GetRoot()
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ struct rXmlDocument
|
||||
rXmlDocument();
|
||||
rXmlDocument(const rXmlDocument& other) = delete;
|
||||
rXmlDocument &operator=(const rXmlDocument& other) = delete;
|
||||
void Load(const std::string & path);
|
||||
void Read(const std::string& data);
|
||||
std::shared_ptr<rXmlNode> GetRoot();
|
||||
|
||||
pugi::xml_document handle;
|
||||
|
||||
+21
-1
@@ -48,7 +48,7 @@
|
||||
#define CONCATENATE_DETAIL(x, y) x ## y
|
||||
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
|
||||
|
||||
#define STRINGIZE_DETAIL(x) #x
|
||||
#define STRINGIZE_DETAIL(x) #x ""
|
||||
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
|
||||
|
||||
#define HERE "\n(in file " __FILE__ ":" STRINGIZE(__LINE__) ")"
|
||||
@@ -534,6 +534,26 @@ inline u64 cntlz64(u64 arg, bool nonzero = false)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u32 cnttz32(u32 arg, bool nonzero = false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanForward(&res, arg) || nonzero ? res : 32;
|
||||
#else
|
||||
return arg || nonzero ? __builtin_ctzll(arg) : 32;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u64 cnttz64(u64 arg, bool nonzero = false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanForward64(&res, arg) || nonzero ? res : 64;
|
||||
#else
|
||||
return arg || nonzero ? __builtin_ctzll(arg) : 64;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper function, used by ""_u16, ""_u32, ""_u64
|
||||
constexpr u8 to_u8(char c)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
Submodule Vulkan/Vulkan-LoaderAndValidationLayers updated: 115665a3b5...85926a33d4
@@ -19,12 +19,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -39,20 +39,20 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
|
||||
</NMakeReBuildCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
|
||||
+1
-1
Submodule Vulkan/glslang updated: 0e07119ae2...cf571f7310
@@ -19,12 +19,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -39,24 +39,24 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
+72
-34
@@ -1,44 +1,82 @@
|
||||
version: '0.0.3-{build}'
|
||||
#---------------------------------#
|
||||
# general configuration #
|
||||
#---------------------------------#
|
||||
|
||||
os: Visual Studio 2017
|
||||
platform: x64
|
||||
clone_folder: C:\rpcs3
|
||||
clone_depth: 3
|
||||
test: off
|
||||
# version format
|
||||
version: '0.0.4-{build}'
|
||||
|
||||
configuration:
|
||||
# Release
|
||||
- ReleaseLLVM
|
||||
#---------------------------------#
|
||||
# environment configuration #
|
||||
#---------------------------------#
|
||||
|
||||
before_build:
|
||||
- ps: $env:Date="$(git show -s --date=short --format='%ad')"
|
||||
- git submodule update --init 3rdparty/ffmpeg 3rdparty/pugixml asmjit 3rdparty/GSL 3rdparty/libpng Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers Utilities/yaml-cpp 3rdparty/cereal 3rdparty/zlib 3rdparty/hidapi
|
||||
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
|
||||
- 7z x vulkan.7z -aos -oC:\rpcs3\Vulkan > null
|
||||
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
|
||||
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
|
||||
- set CXXFLAGS=-DBRANCH=%BRANCH%
|
||||
- if %configuration%==Release (cmake -G "Visual Studio 15 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 15 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
# Build worker image (VM template)
|
||||
image: Visual Studio 2015
|
||||
|
||||
build_script:
|
||||
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
# clone directory
|
||||
clone_folder: c:\projects\rpcs3
|
||||
|
||||
install:
|
||||
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
|
||||
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
|
||||
- if not exist zlib.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B-HVE3xvheVFX05lRFdnZlh5aUU" -FileName zlib.7z
|
||||
- set QTDIR=C:\Qt\5.9.1\msvc2017_64
|
||||
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
|
||||
- set PATH=C:\Program Files (x86)\MSBuild\15.0\Bin;%QTDIR%;%PATH%
|
||||
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
|
||||
# set clone depth
|
||||
clone_depth: 3 # clone entire repository history if not defined
|
||||
|
||||
artifacts:
|
||||
- path: bin
|
||||
name: 'rpcs3-v0.0.3-$(Date)-$(COMMIT_SHA)_win64'
|
||||
type: zip
|
||||
# environment variables
|
||||
environment:
|
||||
QTDIR: C:\Qt\5.9.1\msvc2015_64
|
||||
|
||||
# build cache to preserve files/folders between builds
|
||||
cache:
|
||||
- llvmlibs.7z -> appveyor.yml
|
||||
- vulkan.7z -> appveyor.yml
|
||||
- zlib.7z -> appveyor.yml
|
||||
|
||||
# scripts that run after cloning repository
|
||||
install:
|
||||
- git submodule update --init 3rdparty/cereal 3rdparty/ffmpeg 3rdparty/GSL 3rdparty/hidapi 3rdparty/libpng 3rdparty/Optional 3rdparty/pugixml 3rdparty/zlib asmjit Utilities/yaml-cpp Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
|
||||
|
||||
#---------------------------------#
|
||||
# build configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
|
||||
platform: x64
|
||||
|
||||
# build Configuration, i.e. Debug, Release, etc.
|
||||
configuration: Release - LLVM
|
||||
|
||||
build:
|
||||
parallel: true # enable MSBuild parallel builds
|
||||
project: rpcs3.sln # path to Visual Studio solution or project
|
||||
# MSBuild verbosity level
|
||||
verbosity: normal
|
||||
|
||||
# scripts to run before build
|
||||
before_build:
|
||||
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
|
||||
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
|
||||
- set PATH=%PATH%;%QTDIR%
|
||||
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
|
||||
- 7z x llvmlibs.7z -aos -o%APPVEYOR_BUILD_FOLDER% > null
|
||||
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
|
||||
- 7z x vulkan.7z -aos -o"%APPVEYOR_BUILD_FOLDER%\lib\%CONFIGURATION%-%PLATFORM%" > null
|
||||
|
||||
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
|
||||
before_package:
|
||||
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.exp
|
||||
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.lib
|
||||
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.pdb
|
||||
- set COMMIT_DATE=%APPVEYOR_REPO_COMMIT_TIMESTAMP:~0,10%
|
||||
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
|
||||
|
||||
#---------------------------------#
|
||||
# tests configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# to disable automatic tests
|
||||
test: off
|
||||
|
||||
#---------------------------------#
|
||||
# artifacts configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# pushing entire folder as a zip archive
|
||||
artifacts:
|
||||
- path: bin
|
||||
name: 'rpcs3-v0.0.4-$(COMMIT_DATE)-$(COMMIT_SHA)_win64'
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -40,7 +40,7 @@ QWidget {
|
||||
|
||||
/* Mouse tooltips */
|
||||
QToolTip {
|
||||
border: 1px solid #323232;
|
||||
border: 0.05em solid #323232;
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
@@ -49,29 +49,29 @@ QToolTip {
|
||||
QHeaderView::section {
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
padding-left: 4px;
|
||||
border: 1px solid #323232;
|
||||
padding-left: 0.2em;
|
||||
border: 0.05em solid #323232;
|
||||
}
|
||||
|
||||
/* Settings Dialog: Tabs */
|
||||
QTabBar::tab {
|
||||
color: #ecf0f1;
|
||||
border: 1px solid #444;
|
||||
border: 0.05em solid #444;
|
||||
border-bottom-style: none;
|
||||
background-color: #333333;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
margin-right: -2px;
|
||||
padding-left: 0.9em;
|
||||
padding-right: 0.9em;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
margin-right: -0.2em;
|
||||
}
|
||||
QTabBar::tab:last {
|
||||
margin-right: 0px;
|
||||
margin-right: 0em;
|
||||
}
|
||||
QTabBar::tab:!selected {
|
||||
color: #b1b1b1;
|
||||
border-bottom-style: solid;
|
||||
margin-top: 3px;
|
||||
margin-top: 0.15em;
|
||||
background-color: #292929;
|
||||
}
|
||||
QTabBar::tab:hover {
|
||||
@@ -81,11 +81,11 @@ QTabBar::tab:hover {
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border-radius: 2px;
|
||||
border: 1px solid #ecf0f1;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: 1px;
|
||||
border-radius: 0.1em;
|
||||
border: 0.05em solid #ecf0f1;
|
||||
margin-top: 0.05em;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
@@ -99,11 +99,11 @@ QCheckBox::indicator::disabled {
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border-radius: 6px;
|
||||
border: 1px solid #ecf0f1;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: 1px;
|
||||
border-radius: 0.4em;
|
||||
border: 0.05em solid;
|
||||
border-color: white;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QRadioButton::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
@@ -119,10 +119,10 @@ QRadioButton::indicator::disabled {
|
||||
QComboBox {
|
||||
background-color: #404040;
|
||||
color: #fff;
|
||||
border: 1px solid #1e1e1e;
|
||||
border-radius: 3px;
|
||||
padding-bottom: 2px;
|
||||
padding-left: 4px;
|
||||
border: 0.05em solid #1e1e1e;
|
||||
border-radius: 0.15em;
|
||||
padding-bottom: 0.2em;
|
||||
padding-left: 0.4em;
|
||||
}
|
||||
QComboBox::disabled {
|
||||
background-color: #828790;
|
||||
@@ -131,15 +131,15 @@ QComboBox::disabled {
|
||||
|
||||
/* Group Boxes (Settings Dialog) */
|
||||
QGroupBox {
|
||||
margin-top: 17px;
|
||||
font-size: 13px;
|
||||
border: 1px solid #bdc3c7;
|
||||
border-radius: 4px;
|
||||
margin-top: 1em;
|
||||
font-size: 8pt;
|
||||
border: 0.05em solid #bdc3c7;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top center;
|
||||
padding: 5px 10px 5px 10px;
|
||||
subcontrol-position: top;
|
||||
padding: 0.3em 0.5em 0.3em 0.5em;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -154,19 +154,19 @@ QPushButton::disabled {
|
||||
|
||||
/* Log and Debugger borders */
|
||||
QTextEdit {
|
||||
border: 1px solid #828790;
|
||||
border: 0.05em solid #828790;
|
||||
}
|
||||
|
||||
/* For dock buttons to be visible */
|
||||
QDockWidget::close-button, QDockWidget::float-button {
|
||||
background-color: #bdc3c7;
|
||||
border: 1px solid #000;
|
||||
border-radius: 4px;
|
||||
border: 0.05em solid #000;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
/* Disable ugly borders */
|
||||
QTabWidget::pane {
|
||||
border: 0px solid #828790;
|
||||
border: 0em solid #828790;
|
||||
}
|
||||
|
||||
/* Top menu bar */
|
||||
@@ -174,14 +174,14 @@ QMenuBar::item:selected {
|
||||
background: #444444;
|
||||
}
|
||||
QMenu::item {
|
||||
padding-left: 20px;
|
||||
padding-right: 15px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 1.5em;
|
||||
padding-right: 0.75em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
QMenu::item:selected {
|
||||
background: #444444;
|
||||
border: 1px solid #bdc3c7;
|
||||
border: 0.05em solid #bdc3c7;
|
||||
}
|
||||
QMenu::item:disabled {
|
||||
background-color: #444444;
|
||||
@@ -223,7 +223,7 @@ QLabel#color_button {
|
||||
|
||||
/* Seachbar on main toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left:14px;
|
||||
margin-left: 0.7em;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
@@ -246,3 +246,85 @@ QLabel#gamelist_icon_background_color {
|
||||
QLabel#gamelist_toolbar_icon_color {
|
||||
background-color: #e3e3e3;
|
||||
}
|
||||
|
||||
/* Set Windows Taskbar Thumbnail colors */
|
||||
QLabel#thumbnail_icon_color {
|
||||
color: #444444;
|
||||
}
|
||||
|
||||
/* Set Log colors */
|
||||
QTextEdit#log_frame {
|
||||
background-color: #000000; /* Black */
|
||||
}
|
||||
QLabel#log_level_always {
|
||||
color: #00ffff; /* Cyan */
|
||||
}
|
||||
QLabel#log_level_fatal {
|
||||
color: #ff00ff; /* Fuchsia */
|
||||
}
|
||||
QLabel#log_level_error {
|
||||
color: #ff0000; /* Red */
|
||||
}
|
||||
QLabel#log_level_todo {
|
||||
color: #ff6000; /* Orange */
|
||||
}
|
||||
QLabel#log_level_success {
|
||||
color: #00ff00; /* Green */
|
||||
}
|
||||
QLabel#log_level_warning {
|
||||
color: #ffff00; /* Yellow */
|
||||
}
|
||||
QLabel#log_level_notice {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
QLabel#log_level_trace {
|
||||
color: #808080; /* Gray */
|
||||
}
|
||||
QLabel#log_stack {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
|
||||
/* Set TTY colors */
|
||||
QTextEdit#tty_frame {
|
||||
background-color: #000000; /* Black */
|
||||
}
|
||||
QLabel#tty_text {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
|
||||
/* RSX Debugger */
|
||||
QLabel#rsx_debugger_display_buffer {
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Kernel Explorer */
|
||||
QDialog#kernel_explorer {
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Memory Viewer */
|
||||
QDialog#memory_viewer {
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_address_panel {
|
||||
color: #00cbff; /* Font Color: Blue */
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_hex_panel {
|
||||
color: #bdc3c7; /* Font Color: Grey */
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_ascii_panel {
|
||||
color: #bdc3c7; /* Font Color: Grey */
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Debugger colors */
|
||||
QLabel#debugger_frame_breakpoint {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #ffff00; /* Yellow */
|
||||
}
|
||||
QLabel#debugger_frame_pc {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #00ff00; /* Green */
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
Submodule llvm updated: a3b2103ffc...4423e35117
@@ -18,12 +18,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -39,30 +39,30 @@
|
||||
<NMakePreprocessorDefinitions>
|
||||
</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakePreprocessorDefinitions />
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -32,7 +32,7 @@ Controller.prototype.ComponentSelectionPageCallback = function() {
|
||||
var widget = gui.currentPageWidget();
|
||||
|
||||
widget.deselectAll();
|
||||
widget.selectComponent("qt.591.gcc_64");
|
||||
widget.selectComponent("qt.592.gcc_64");
|
||||
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.13
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
|
||||
EndProject
|
||||
|
||||
+77
-19
@@ -6,25 +6,31 @@ set(CMAKE_CXX_STANDARD 14)
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
# Qt section
|
||||
find_package(Qt5 5.9 COMPONENTS Widgets)
|
||||
find_package(Qt5 5.7 COMPONENTS Widgets)
|
||||
if (WIN32)
|
||||
find_package(Qt5WinExtras REQUIRED)
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras)
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5WinExtras_INCLUDE_DIRS})
|
||||
else()
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets)
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||
find_package(Qt5DBus)
|
||||
if (Qt5DBus_FOUND)
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus)
|
||||
add_definitions(-DHAVE_QTDBUS)
|
||||
else()
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets)
|
||||
endif()
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Let's make sure we have Qt before we continue
|
||||
if (NOT Qt5Widgets_FOUND)
|
||||
if (Qt5Widgets_VERSION VERSION_LESS 5.9.0)
|
||||
message("Minimum supported Qt5 version is 5.9! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
|
||||
if (Qt5Widgets_VERSION VERSION_LESS 5.7.0)
|
||||
message("Minimum supported Qt5 version is 5.7! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
|
||||
if ("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
message(FATAL_ERROR "Most distros do not provide an up-to-date version of Qt.
|
||||
If you're on Ubuntu or Linux Mint, there are PPAs you can use to install an up-to-date qt5 version.
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-xenial
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-trusty
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-xenial
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-trusty
|
||||
just make sure to run
|
||||
source /opt/qt59/bin/qt59-env.sh
|
||||
before re-running cmake")
|
||||
@@ -38,7 +44,7 @@ before re-running cmake")
|
||||
|
||||
message("CMake was unable to find Qt5!")
|
||||
if (WIN32)
|
||||
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.9\\msvc2017_64\\)")
|
||||
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.8\\msvc2017_64\\)")
|
||||
elseif("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
message(FATAL_ERROR "Make sure to install your distro's qt5 package!")
|
||||
else()
|
||||
@@ -134,15 +140,17 @@ else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /DYNAMICBASE:NO /BASE:0x10000 /FIXED")
|
||||
endif()
|
||||
|
||||
set(ADDITIONAL_LIBS "")
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
#on some Linux distros shm_unlink and similar functions are in librt only
|
||||
set(ADDITIONAL_LIBS "rt" "X11")
|
||||
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "rt")
|
||||
elseif(NOT MSVC AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG")
|
||||
#it seems like glibc includes the iconv functions we use but other libc
|
||||
#implementations like the one on OSX don't seem implement them
|
||||
set(ADDITIONAL_LIBS "iconv")
|
||||
else()
|
||||
set(ADDITIONAL_LIBS "")
|
||||
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "iconv")
|
||||
endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "X11")
|
||||
endif()
|
||||
|
||||
if(NOT RPCS3_SRC_DIR)
|
||||
@@ -158,6 +166,29 @@ find_package(OpenGL REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
if (NOT WITHOUT_LLVM)
|
||||
find_package(LLVM 4.0 CONFIG)
|
||||
if (NOT LLVM_FOUND)
|
||||
message("System LLVM was not found, LLVM will be built from the submodule.")
|
||||
|
||||
set(LLVM_TARGETS_TO_BUILD "X86" CACHE INTERNAL "")
|
||||
option(LLVM_BUILD_RUNTIME OFF)
|
||||
option(LLVM_BUILD_TOOLS OFF)
|
||||
option(LLVM_INCLUDE_DOCS OFF)
|
||||
option(LLVM_INCLUDE_EXAMPLES OFF)
|
||||
option(LLVM_INCLUDE_TESTS OFF)
|
||||
option(LLVM_INCLUDE_TOOLS OFF)
|
||||
option(LLVM_INCLUDE_UTILS OFF)
|
||||
option(WITH_POLLY OFF)
|
||||
|
||||
# LLVM needs to be built out-of-tree
|
||||
add_subdirectory(../llvm ../llvm_build)
|
||||
set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/../llvm_build/lib/cmake/llvm/")
|
||||
|
||||
# now tries to find LLVM again
|
||||
find_package(LLVM 4.0 CONFIG)
|
||||
if (NOT LLVM_FOUND)
|
||||
message(WARNING "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -170,6 +201,7 @@ else()
|
||||
option(USE_ALSA "ALSA audio backend" ON)
|
||||
option(USE_PULSE "PulseAudio audio backend" ON)
|
||||
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
|
||||
option(USE_VULKAN "Vulkan render backend" ON)
|
||||
endif()
|
||||
|
||||
if(USE_ALSA)
|
||||
@@ -199,6 +231,15 @@ if(USE_LIBEVDEV)
|
||||
list(APPEND ADDITIONAL_LIBS ${LIBEVDEV_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
if(NOT WIN32 AND USE_VULKAN)
|
||||
find_package(Vulkan)
|
||||
if(VULKAN_FOUND)
|
||||
add_definitions(-DHAVE_VULKAN)
|
||||
list(APPEND ADDITIONAL_LIBS ${VULKAN_LIBRARY})
|
||||
else()
|
||||
message("WARNING! USE_VULKAN was enabled, but libvulkan was not found. RPCS3 will be compiled without Vulkan support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Select the version of libpng to use, default is builtin
|
||||
if(USE_SYSTEM_LIBPNG)
|
||||
@@ -241,6 +282,7 @@ ${LLVM_INCLUDE_DIRS}
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/GL"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/stblib"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/cereal/include"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/Optional"
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
@@ -255,9 +297,9 @@ else()
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
add_definitions(-DLLVM_AVAILABLE)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler)
|
||||
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler)
|
||||
else()
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
|
||||
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
@@ -291,7 +333,7 @@ RPCS3_SRC
|
||||
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit/*.cpp"
|
||||
)
|
||||
|
||||
if (NOT WIN32 AND "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
if (NOT WIN32 AND VULKAN_FOUND)
|
||||
# Compile glslang and SPIRV modules needed for glsl compilation
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
@@ -300,7 +342,6 @@ if (NOT WIN32 AND "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/MachineIndependent/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/OSDependent/Unix/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/OGLCompilersDLL/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/hlsl/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/SPIRV/*.cpp"
|
||||
)
|
||||
|
||||
@@ -309,8 +350,7 @@ endif()
|
||||
|
||||
#File exclusion section
|
||||
|
||||
#Ignore vulkan if not on windows or linux
|
||||
if(NOT WIN32 AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
if(NOT WIN32 AND NOT VULKAN_FOUND)
|
||||
set (EXCLUDE_FILES "/RSX/VK/")
|
||||
endif()
|
||||
|
||||
@@ -353,10 +393,13 @@ else()
|
||||
if(APPLE)
|
||||
target_link_libraries(rpcs3 hidapi-mac "-framework CoreFoundation" "-framework IOKit")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_libraries(rpcs3 hidapi-hidraw udev vulkan)
|
||||
target_link_libraries(rpcs3 hidapi-hidraw udev)
|
||||
else()
|
||||
target_link_libraries(rpcs3 hidapi-libusb usb)
|
||||
endif()
|
||||
if(VULKAN_FOUND)
|
||||
target_link_libraries(rpcs3 ${VULKAN_LIBRARIES})
|
||||
endif()
|
||||
target_link_libraries(rpcs3 ${CMAKE_DL_LIBS} -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
|
||||
if (USE_SYSTEM_FFMPEG)
|
||||
link_libraries(${FFMPEG_LIBRARY_DIR})
|
||||
@@ -384,6 +427,21 @@ target_link_libraries(rpcs3 ${RPCS3_QT_LIBS})
|
||||
|
||||
set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h")
|
||||
|
||||
if (MSVC)
|
||||
# Under Windows, some QT DLLs need to be in the same directory of the compiled
|
||||
# RPCS3 binary, so call the windeployqt tool that will take care of copying
|
||||
# them from the local QT installation at the end of the build.
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations --debug ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
cotire(rpcs3)
|
||||
|
||||
# Unix installation
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "sha1.h"
|
||||
#include "key_vault.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "unpkg.h"
|
||||
|
||||
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync, const std::string& pkg_filepath)
|
||||
@@ -120,7 +121,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
u64 cursize = pkg_f.size();
|
||||
while (cursize != header.pkg_size)
|
||||
{
|
||||
std::string archive_filename = fmt::format("%s_%2d.pkg", name_wo_number, filelist.size());
|
||||
std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, filelist.size());
|
||||
|
||||
fs::file archive_file(archive_filename);
|
||||
if (!archive_file)
|
||||
@@ -285,7 +286,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
|
||||
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : dec_key.data());
|
||||
|
||||
const std::string name(reinterpret_cast<char*>(buf.get()), entry.name_size);
|
||||
std::string name{reinterpret_cast<char*>(buf.get()), entry.name_size};
|
||||
|
||||
LOG_NOTICE(LOADER, "Entry 0x%08x: %s", entry.type, name);
|
||||
|
||||
@@ -303,17 +304,17 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
{
|
||||
const std::string path = dir + name;
|
||||
const std::string path = dir + vfs::escape(name);
|
||||
|
||||
const bool did_overwrite = fs::is_file(path);
|
||||
|
||||
if (did_overwrite && (entry.type&PKG_FILE_ENTRY_OVERWRITE) == 0)
|
||||
if (did_overwrite && (entry.type & PKG_FILE_ENTRY_OVERWRITE) == 0)
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Didn't overwrite %s", name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fs::file out{ path, fs::rewrite })
|
||||
if (fs::file out{path, fs::rewrite})
|
||||
{
|
||||
for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE)
|
||||
{
|
||||
@@ -358,7 +359,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
case PKG_FILE_ENTRY_FOLDER:
|
||||
case 0x12:
|
||||
{
|
||||
const std::string path = dir + name;
|
||||
const std::string path = dir + vfs::escape(name);
|
||||
|
||||
if (fs::create_dir(path))
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -50,6 +50,8 @@ OpenALThread::OpenALThread()
|
||||
{
|
||||
m_format = g_cfg.audio.convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
|
||||
}
|
||||
|
||||
m_buffers = std::make_unique<ALuint[]>(g_cfg.audio.frames);
|
||||
}
|
||||
|
||||
OpenALThread::~OpenALThread()
|
||||
@@ -83,7 +85,7 @@ void OpenALThread::Close()
|
||||
if (alIsSource(m_source))
|
||||
alDeleteSources(1, &m_source);
|
||||
|
||||
alDeleteBuffers(g_al_buffers_count, m_buffers);
|
||||
alDeleteBuffers(g_cfg.audio.frames, m_buffers.get());
|
||||
checkForAlError("alDeleteBuffers");
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ void OpenALThread::Open(const void* src, int size)
|
||||
alGenSources(1, &m_source);
|
||||
checkForAlError("alGenSources");
|
||||
|
||||
alGenBuffers(g_al_buffers_count, m_buffers);
|
||||
alGenBuffers(g_cfg.audio.frames, m_buffers.get());
|
||||
checkForAlError("alGenBuffers");
|
||||
|
||||
alSourcei(m_source, AL_LOOPING, AL_FALSE);
|
||||
@@ -106,13 +108,13 @@ void OpenALThread::Open(const void* src, int size)
|
||||
|
||||
m_buffer_size = size;
|
||||
|
||||
for (uint i = 0; i<g_al_buffers_count; ++i)
|
||||
for (int i = 0; i < g_cfg.audio.frames; ++i)
|
||||
{
|
||||
alBufferData(m_buffers[i], m_format, src, m_buffer_size, 48000);
|
||||
checkForAlError("alBufferData");
|
||||
}
|
||||
|
||||
alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers);
|
||||
alSourceQueueBuffers(m_source, g_cfg.audio.frames, m_buffers.get());
|
||||
checkForAlError("alSourceQueueBuffers");
|
||||
Play();
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
#include "3rdparty/OpenAL/include/alext.h"
|
||||
#include <memory>
|
||||
|
||||
class OpenALThread : public AudioThread
|
||||
{
|
||||
private:
|
||||
static const uint g_al_buffers_count = 24;
|
||||
|
||||
ALint m_format;
|
||||
ALuint m_source;
|
||||
ALuint m_buffers[g_al_buffers_count];
|
||||
std::unique_ptr<ALuint[]> m_buffers;
|
||||
ALsizei m_buffer_size;
|
||||
|
||||
public:
|
||||
|
||||
@@ -59,7 +59,7 @@ ALSAThread::ALSAThread()
|
||||
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, g_cfg.audio.downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, 8 * 256), "snd_pcm_hw_params_set_buffer_size"))
|
||||
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, g_cfg.audio.frames * 256), "snd_pcm_hw_params_set_buffer_size"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_period_size(s_tls_handle, hw_params, 256, 0), "snd_pcm_hw_params_set_period_size"))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "CPUThread.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Utilities/GDBDebugServer.h"
|
||||
#include <typeinfo>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
||||
@@ -12,6 +12,34 @@
|
||||
|
||||
logs::channel cellAudio("cellAudio");
|
||||
|
||||
template <>
|
||||
void fmt_class_string<CellAudioError>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](CellAudioError value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
STR_CASE(CELL_AUDIO_ERROR_ALREADY_INIT);
|
||||
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM);
|
||||
STR_CASE(CELL_AUDIO_ERROR_NOT_INIT);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PARAM);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_FULL);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_ALREADY_RUN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_OPEN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_RUN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_TRANS_EVENT);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_OPEN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_SHAREDMEMORY);
|
||||
STR_CASE(CELL_AUDIO_ERROR_MUTEX);
|
||||
STR_CASE(CELL_AUDIO_ERROR_EVENT_QUEUE);
|
||||
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND);
|
||||
STR_CASE(CELL_AUDIO_ERROR_TAG_NOT_FOUND);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
void audio_config::on_init(const std::shared_ptr<void>& _this)
|
||||
{
|
||||
m_buffer.set(vm::alloc(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, vm::main));
|
||||
@@ -29,6 +57,8 @@ void audio_config::on_init(const std::shared_ptr<void>& _this)
|
||||
|
||||
void audio_config::on_task()
|
||||
{
|
||||
thread_ctrl::set_native_priority(1);
|
||||
|
||||
AudioDumper m_dump(g_cfg.audio.dump_to_file ? 2 : 0); // Init AudioDumper for 2 channels if enabled
|
||||
|
||||
float buf2ch[2 * BUFFER_SIZE]{}; // intermediate buffer for 2 channels
|
||||
@@ -309,12 +339,12 @@ void audio_config::on_task()
|
||||
case 8: m_dump.WriteData(&buf8ch, sizeof(buf8ch)); break; // write file data (8 ch)
|
||||
}
|
||||
|
||||
cellAudio.trace("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)",
|
||||
time_pos, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
|
||||
cellAudio.trace("Audio perf: (access=%d, AddData=%d, events=%d, dump=%d)",
|
||||
stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioInit()
|
||||
error_code cellAudioInit()
|
||||
{
|
||||
cellAudio.warning("cellAudioInit()");
|
||||
|
||||
@@ -329,7 +359,7 @@ s32 cellAudioInit()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioQuit()
|
||||
error_code cellAudioQuit()
|
||||
{
|
||||
cellAudio.warning("cellAudioQuit()");
|
||||
|
||||
@@ -344,7 +374,7 @@ s32 cellAudioQuit()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
|
||||
error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum);
|
||||
|
||||
@@ -444,7 +474,7 @@ s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portN
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
|
||||
error_code cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
|
||||
{
|
||||
cellAudio.warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig);
|
||||
|
||||
@@ -479,7 +509,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioPortStart(u32 portNum)
|
||||
error_code cellAudioPortStart(u32 portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortStart(portNum=%d)", portNum);
|
||||
|
||||
@@ -504,7 +534,7 @@ s32 cellAudioPortStart(u32 portNum)
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioPortClose(u32 portNum)
|
||||
error_code cellAudioPortClose(u32 portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortClose(portNum=%d)", portNum);
|
||||
|
||||
@@ -529,7 +559,7 @@ s32 cellAudioPortClose(u32 portNum)
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioPortStop(u32 portNum)
|
||||
error_code cellAudioPortStop(u32 portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortStop(portNum=%d)", portNum);
|
||||
|
||||
@@ -554,7 +584,7 @@ s32 cellAudioPortStop(u32 portNum)
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
error_code cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
{
|
||||
cellAudio.trace("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp);
|
||||
|
||||
@@ -584,7 +614,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||
error_code cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||
{
|
||||
cellAudio.trace("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag);
|
||||
|
||||
@@ -627,7 +657,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSetPortLevel(u32 portNum, float level)
|
||||
error_code cellAudioSetPortLevel(u32 portNum, float level)
|
||||
{
|
||||
cellAudio.trace("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level);
|
||||
|
||||
@@ -662,7 +692,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
|
||||
error_code cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
|
||||
{
|
||||
cellAudio.warning("cellAudioCreateNotifyEventQueue(id=*0x%x, key=*0x%x)", id, key);
|
||||
|
||||
@@ -693,7 +723,7 @@ s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
|
||||
return CELL_AUDIO_ERROR_EVENT_QUEUE;
|
||||
}
|
||||
|
||||
s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
|
||||
error_code cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
|
||||
{
|
||||
cellAudio.todo("cellAudioCreateNotifyEventQueueEx(id=*0x%x, key=*0x%x, iFlags=0x%x)", id, key, iFlags);
|
||||
|
||||
@@ -707,7 +737,7 @@ s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFl
|
||||
return CELL_AUDIO_ERROR_EVENT_QUEUE;
|
||||
}
|
||||
|
||||
s32 cellAudioSetNotifyEventQueue(u64 key)
|
||||
error_code cellAudioSetNotifyEventQueue(u64 key)
|
||||
{
|
||||
cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
|
||||
|
||||
@@ -733,7 +763,7 @@ s32 cellAudioSetNotifyEventQueue(u64 key)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
{
|
||||
cellAudio.todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
|
||||
|
||||
@@ -742,7 +772,7 @@ s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioRemoveNotifyEventQueue(u64 key)
|
||||
error_code cellAudioRemoveNotifyEventQueue(u64 key)
|
||||
{
|
||||
cellAudio.warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
|
||||
|
||||
@@ -768,7 +798,7 @@ s32 cellAudioRemoveNotifyEventQueue(u64 key)
|
||||
return CELL_AUDIO_ERROR_TRANS_EVENT;
|
||||
}
|
||||
|
||||
s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
error_code cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
{
|
||||
cellAudio.todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
|
||||
|
||||
@@ -777,7 +807,7 @@ s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
error_code cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
{
|
||||
cellAudio.trace("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
|
||||
|
||||
@@ -812,7 +842,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
error_code cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
{
|
||||
cellAudio.trace("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
|
||||
|
||||
@@ -881,7 +911,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volu
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
{
|
||||
cellAudio.trace("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume);
|
||||
|
||||
@@ -935,25 +965,25 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
|
||||
error_code cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
|
||||
{
|
||||
cellAudio.todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSendAck(u64 data3)
|
||||
error_code cellAudioSendAck(u64 data3)
|
||||
{
|
||||
cellAudio.todo("cellAudioSendAck(data3=0x%llx)", data3);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
|
||||
error_code cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
|
||||
{
|
||||
cellAudio.todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream)
|
||||
error_code cellAudioUnsetPersonalDevice(s32 iPersonalStream)
|
||||
{
|
||||
cellAudio.todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream);
|
||||
return CELL_OK;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
// Error codes
|
||||
enum
|
||||
enum CellAudioError : u32
|
||||
{
|
||||
CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701,
|
||||
CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702,
|
||||
|
||||
@@ -152,7 +152,7 @@ s32 cellVideoOutSetCopyControl(u32 videoOut, u32 control)
|
||||
|
||||
DECLARE(ppu_module_manager::cellAvconfExt)("cellSysutilAvconfExt", []()
|
||||
{
|
||||
REG_VNID(cellSysutilAvconfExt, 0x00000000u, g_gamma).init = []
|
||||
REG_VAR(cellSysutilAvconfExt, g_gamma).flag(MFF_HIDDEN).init = []
|
||||
{
|
||||
// Test
|
||||
*g_gamma = 1.0f;
|
||||
|
||||
@@ -554,7 +554,7 @@ s32 cellFontExtend(u32 a1, u32 a2, u32 a3)
|
||||
//Something happens
|
||||
}
|
||||
//Something happens?
|
||||
return -1;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFontRenderCharGlyphImageVertical()
|
||||
|
||||
@@ -1035,22 +1035,22 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
|
||||
REG_FUNC(sys_fs, cellFsChangeFileSizeWithoutAllocation);
|
||||
REG_FUNC(sys_fs, cellFsChmod);
|
||||
REG_FUNC(sys_fs, cellFsChown);
|
||||
REG_FUNC(sys_fs, cellFsClose).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsClosedir).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsClose).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsClosedir).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsFcntl);
|
||||
REG_FUNC(sys_fs, cellFsFdatasync);
|
||||
REG_FUNC(sys_fs, cellFsFGetBlockSize).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsFGetBlockSize).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsFGetBlockSize2);
|
||||
REG_FUNC(sys_fs, cellFsFstat).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsFsync);
|
||||
REG_FUNC(sys_fs, cellFsFtruncate).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsFtruncate).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsGetBlockSize);
|
||||
REG_FUNC(sys_fs, cellFsGetBlockSize2);
|
||||
REG_FUNC(sys_fs, cellFsGetDirectoryEntries);
|
||||
REG_FUNC(sys_fs, cellFsGetFreeSize);
|
||||
REG_FUNC(sys_fs, cellFsGetPath);
|
||||
REG_FUNC(sys_fs, cellFsLink);
|
||||
REG_FUNC(sys_fs, cellFsLseek).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsLseek).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsLsnGetCDA);
|
||||
REG_FUNC(sys_fs, cellFsLsnGetCDASize);
|
||||
REG_FUNC(sys_fs, cellFsLsnLock);
|
||||
@@ -1063,8 +1063,8 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
|
||||
REG_FUNC(sys_fs, cellFsOpen);
|
||||
REG_FUNC(sys_fs, cellFsOpen2);
|
||||
REG_FUNC(sys_fs, cellFsOpendir);
|
||||
REG_FUNC(sys_fs, cellFsRead).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsReaddir).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsRead).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsReaddir).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsReadWithOffset);
|
||||
REG_FUNC(sys_fs, cellFsRegisterConversionCallback);
|
||||
REG_FUNC(sys_fs, cellFsRename);
|
||||
@@ -1095,6 +1095,6 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
|
||||
REG_FUNC(sys_fs, cellFsUnlink);
|
||||
REG_FUNC(sys_fs, cellFsUnregisterL10nCallbacks);
|
||||
REG_FUNC(sys_fs, cellFsUtime);
|
||||
REG_FUNC(sys_fs, cellFsWrite).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsWrite).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsWriteWithOffset);
|
||||
});
|
||||
|
||||
@@ -659,6 +659,11 @@ error_code cellGameGetParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
|
||||
{
|
||||
cellGame.warning("cellGameGetParamString(id=%d, buf=*0x%x, bufsize=%d)", id, buf, bufsize);
|
||||
|
||||
if (!buf || bufsize == 0)
|
||||
{
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
const auto prm = fxm::get<content_permission>();
|
||||
|
||||
if (!prm)
|
||||
@@ -685,6 +690,11 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
|
||||
{
|
||||
cellGame.warning("cellGameSetParamString(id=%d, buf=*0x%x)", id, buf);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
const auto prm = fxm::get<content_permission>();
|
||||
|
||||
if (!prm)
|
||||
|
||||
@@ -595,7 +595,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
||||
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
|
||||
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
|
||||
@@ -603,7 +603,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
||||
|
||||
if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12)))
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ENUM");
|
||||
return CELL_GCM_ERROR_INVALID_ENUM;
|
||||
}
|
||||
|
||||
@@ -1171,7 +1171,7 @@ s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize(u32 bufferSize, u32 segment
|
||||
const auto& put = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put;
|
||||
const auto& get = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).get;
|
||||
|
||||
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2)
|
||||
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2 || segmentSize >= 0x80000000)
|
||||
{
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
@@ -1220,7 +1220,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT");
|
||||
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
|
||||
@@ -1484,5 +1484,5 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
|
||||
REG_FUNC(cellGcmSys, cellGcmGpadCaptureSnapshot);
|
||||
|
||||
// Special
|
||||
REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN;
|
||||
});
|
||||
REG_FUNC(cellGcmSys, cellGcmCallback).flag(MFF_HIDDEN);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Utilities/LUrlParser.h"
|
||||
|
||||
#include "cellHttpUtil.h"
|
||||
|
||||
@@ -14,50 +15,15 @@ logs::channel cellHttpUtil("cellHttpUtil");
|
||||
|
||||
s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
URL_COMPONENTS stUrlComp;
|
||||
|
||||
ZeroMemory(&stUrlComp, sizeof(URL_COMPONENTS));
|
||||
stUrlComp.dwStructSize = sizeof(URL_COMPONENTS);
|
||||
|
||||
wchar_t lpszScheme[MAX_PATH] = { 0 };
|
||||
wchar_t lpszHostName[MAX_PATH] = { 0 };
|
||||
wchar_t lpszPath[MAX_PATH] = { 0 };
|
||||
wchar_t lpszUserName[MAX_PATH] = { 0 };
|
||||
wchar_t lpszPassword[MAX_PATH] = { 0 };
|
||||
|
||||
stUrlComp.lpszScheme = lpszScheme;
|
||||
stUrlComp.dwSchemeLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszHostName = lpszHostName;
|
||||
stUrlComp.dwHostNameLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszUrlPath = lpszPath;
|
||||
stUrlComp.dwUrlPathLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszUserName = lpszUserName;
|
||||
stUrlComp.dwUserNameLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszPassword = lpszPassword;
|
||||
stUrlComp.dwPasswordLength = MAX_PATH;
|
||||
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
|
||||
LPCWSTR stupidTypeUrlString = converter.from_bytes(str.get_ptr()).c_str();
|
||||
if (!::WinHttpCrackUrl(stupidTypeUrlString, (DWORD)(LONG_PTR)wcslen(stupidTypeUrlString), ICU_ESCAPE, &stUrlComp))
|
||||
cellHttpUtil.trace("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
|
||||
LUrlParser::clParseURL URL = LUrlParser::clParseURL::ParseURL(str.get_ptr());
|
||||
if ( URL.IsValid() )
|
||||
{
|
||||
cellHttpUtil.error("Error %u in WinHttpCrackUrl.\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
std::string scheme = converter.to_bytes(lpszScheme);
|
||||
std::string host = converter.to_bytes(lpszHostName);
|
||||
std::string path = converter.to_bytes(lpszPath);
|
||||
std::string username = converter.to_bytes(lpszUserName);
|
||||
std::string password = converter.to_bytes(lpszPassword);
|
||||
std::string scheme = URL.m_Scheme;
|
||||
std::string host = URL.m_Host;
|
||||
std::string path = URL.m_Path;
|
||||
std::string username = URL.m_UserName;
|
||||
std::string password = URL.m_Password;
|
||||
|
||||
u32 schemeOffset = 0;
|
||||
u32 hostOffset = scheme.length() + 1;
|
||||
@@ -67,10 +33,13 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
|
||||
u32 totalSize = passwordOffset + password.length() + 1;
|
||||
|
||||
//called twice, first to setup pool, then to populate.
|
||||
if (!uri) {
|
||||
if (!uri)
|
||||
{
|
||||
*required = totalSize;
|
||||
return CELL_OK;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
std::strncpy((char*)vm::base(pool.addr() + schemeOffset), (char*)scheme.c_str(), scheme.length() + 1);
|
||||
std::strncpy((char*)vm::base(pool.addr() + hostOffset), (char*)host.c_str(), host.length() + 1);
|
||||
std::strncpy((char*)vm::base(pool.addr() + pathOffset), (char*)path.c_str(), path.length() + 1);
|
||||
@@ -82,14 +51,55 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
|
||||
uri->path.set(pool.addr() + pathOffset);
|
||||
uri->username.set(pool.addr() + usernameOffset);
|
||||
uri->password.set(pool.addr() + passwordOffset);
|
||||
uri->port = stUrlComp.nPort;
|
||||
|
||||
if (URL.m_Port != "")
|
||||
{
|
||||
int port = stoi(URL.m_Port);
|
||||
uri->port = port;
|
||||
}
|
||||
else
|
||||
{
|
||||
uri->port = (u32)80;
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
cellHttpUtil.todo("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
|
||||
#endif
|
||||
return CELL_OK;
|
||||
else
|
||||
{
|
||||
std::string parseError;
|
||||
switch(URL.m_ErrorCode)
|
||||
{
|
||||
case LUrlParser::LUrlParserError_Ok:
|
||||
parseError = "No error, URL was parsed fine";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_Uninitialized:
|
||||
parseError = "Error, LUrlParser is uninitialized";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoUrlCharacter:
|
||||
parseError = "Error, the URL has invalid characters";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_InvalidSchemeName:
|
||||
parseError = "Error, the URL has an invalid scheme";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoDoubleSlash:
|
||||
parseError = "Error, the URL did not contain a double slash";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoAtSign:
|
||||
parseError = "Error, the URL did not contain an @ sign";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_UnexpectedEndOfLine:
|
||||
parseError = "Error, unexpectedly got the end of the line";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoSlash:
|
||||
parseError = "Error, URI didn't contain a slash";
|
||||
break;
|
||||
default:
|
||||
parseError = "Error, unkown error #" + std::to_string(static_cast<int>(URL.m_ErrorCode));
|
||||
break;
|
||||
}
|
||||
cellHttpUtil.error("%s, while parsing URI, %s.", parseError, str.get_ptr());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellHttpUtilParseUriPath(vm::ptr<CellHttpUriPath> path, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
|
||||
|
||||
@@ -177,6 +177,9 @@ error_code cellKbSetCodeType(u32 port_no, u32 type)
|
||||
|
||||
if (!handler)
|
||||
return CELL_KB_ERROR_UNINITIALIZED;
|
||||
|
||||
if (port_no >= handler->GetKeyboards().size())
|
||||
return CELL_KB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
KbConfig& current_config = handler->GetConfig(port_no);
|
||||
current_config.code_type = type;
|
||||
@@ -197,6 +200,9 @@ error_code cellKbSetReadMode(u32 port_no, u32 rmode)
|
||||
|
||||
if (!handler)
|
||||
return CELL_KB_ERROR_UNINITIALIZED;
|
||||
|
||||
if (port_no >= handler->GetKeyboards().size())
|
||||
return CELL_KB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
KbConfig& current_config = handler->GetConfig(port_no);
|
||||
current_config.read_mode = rmode;
|
||||
@@ -213,6 +219,9 @@ error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
|
||||
if (!handler)
|
||||
return CELL_KB_ERROR_UNINITIALIZED;
|
||||
|
||||
if (port_no >= handler->GetKeyboards().size())
|
||||
return CELL_KB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
const KbConfig& current_config = handler->GetConfig(port_no);
|
||||
config->arrange = current_config.arrange;
|
||||
config->read_mode = current_config.read_mode;
|
||||
|
||||
@@ -74,7 +74,7 @@ s32 cellMouseGetInfo(vm::ptr<CellMouseInfo> info)
|
||||
for (u32 i=0; i<CELL_MAX_MICE; i++) info->vendor_id[i] = current_info.vendor_id[i];
|
||||
for (u32 i=0; i<CELL_MAX_MICE; i++) info->product_id[i] = current_info.product_id[i];
|
||||
for (u32 i=0; i<CELL_MAX_MICE; i++) info->status[i] = current_info.status[i];
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr<CellMouseInfoTablet> info)
|
||||
|
||||
info->is_supported = 0; // Unimplemented: (0=Tablet mode is not supported)
|
||||
info->mode = 1; // Unimplemented: (1=Mouse mode)
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
|
||||
{
|
||||
return CELL_MOUSE_ERROR_NO_DEVICE;
|
||||
}
|
||||
|
||||
|
||||
MouseData& current_data = handler->GetData(port_no);
|
||||
data->update = current_data.update;
|
||||
data->buttons = current_data.buttons;
|
||||
@@ -134,22 +134,27 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
|
||||
|
||||
s32 cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sys_io);
|
||||
|
||||
return CELL_OK;
|
||||
sys_io.todo("cellMouseGetDataList(port_no=%d, data=0x%x", port_no, data);
|
||||
if (g_cfg.io.mouse == mouse_handler::null)
|
||||
return CELL_MOUSE_ERROR_NO_DEVICE;
|
||||
else
|
||||
{
|
||||
data->list_num = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellMouseSetTabletMode(u32 port_no, u32 mode)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sys_io);
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellMouseGetTabletDataList(u32 port_no, u32 data_addr)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sys_io);
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,10 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
|
||||
{
|
||||
strcpy_trunc(info->netmask, "255.255.255.255");
|
||||
}
|
||||
else if (code == CELL_NET_CTL_INFO_HTTP_PROXY_CONFIG)
|
||||
{
|
||||
info->http_proxy_config = 0;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
+180
-145
@@ -3,7 +3,7 @@
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Io/PadHandler.h"
|
||||
#include "pad_thread.h"
|
||||
#include "cellPad.h"
|
||||
|
||||
extern logs::channel sys_io;
|
||||
@@ -12,7 +12,7 @@ s32 cellPadInit(u32 max_connect)
|
||||
{
|
||||
sys_io.warning("cellPadInit(max_connect=%d)", max_connect);
|
||||
|
||||
const auto handler = fxm::import<PadHandlerBase>(Emu.GetCallbacks().get_pad_handler);
|
||||
const auto handler = fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler);
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_ALREADY_INITIALIZED;
|
||||
@@ -26,7 +26,7 @@ s32 cellPadEnd()
|
||||
{
|
||||
sys_io.notice("cellPadEnd()");
|
||||
|
||||
if (!fxm::remove<PadHandlerBase>())
|
||||
if (!fxm::remove<pad_thread>())
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
|
||||
return CELL_OK;
|
||||
@@ -36,7 +36,7 @@ s32 cellPadClearBuf(u32 port_no)
|
||||
{
|
||||
sys_io.trace("cellPadClearBuf(port_no=%d)", port_no);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -51,20 +51,20 @@ s32 cellPadClearBuf(u32 port_no)
|
||||
//Set 'm_buffer_cleared' to force a resend of everything
|
||||
//might as well also reset everything in our pad 'buffer' to nothing as well
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
Pad& pad = pads[port_no];
|
||||
auto& pads = handler->GetPads();
|
||||
auto pad = pads[port_no];
|
||||
|
||||
pad.m_buffer_cleared = true;
|
||||
pad.m_analog_left_x = pad.m_analog_left_y = pad.m_analog_right_x = pad.m_analog_right_y = 128;
|
||||
pad->m_buffer_cleared = true;
|
||||
pad->m_analog_left_x = pad->m_analog_left_y = pad->m_analog_right_x = pad->m_analog_right_y = 128;
|
||||
|
||||
pad.m_digital_1 = pad.m_digital_2 = 0;
|
||||
pad.m_press_right = pad.m_press_left = pad.m_press_up = pad.m_press_down = 0;
|
||||
pad.m_press_triangle = pad.m_press_circle = pad.m_press_cross = pad.m_press_square = 0;
|
||||
pad.m_press_L1 = pad.m_press_L2 = pad.m_press_R1 = pad.m_press_R2 = 0;
|
||||
pad->m_digital_1 = pad->m_digital_2 = 0;
|
||||
pad->m_press_right = pad->m_press_left = pad->m_press_up = pad->m_press_down = 0;
|
||||
pad->m_press_triangle = pad->m_press_circle = pad->m_press_cross = pad->m_press_square = 0;
|
||||
pad->m_press_L1 = pad->m_press_L2 = pad->m_press_R1 = pad->m_press_R2 = 0;
|
||||
|
||||
//~399 on sensor y is a level non moving controller
|
||||
pad.m_sensor_y = 399;
|
||||
pad.m_sensor_x = pad.m_sensor_z = pad.m_sensor_g = 512;
|
||||
pad->m_sensor_y = 399;
|
||||
pad->m_sensor_x = pad->m_sensor_z = pad->m_sensor_g = 512;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -73,12 +73,12 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
{
|
||||
sys_io.trace("cellPadGetData(port_no=%d, data=*0x%x)", port_no, data);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
const PadInfo& rinfo = handler->GetInfo();
|
||||
|
||||
@@ -89,39 +89,39 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
Pad& pad = pads[port_no];
|
||||
auto pad = pads[port_no];
|
||||
|
||||
u16 d1Initial, d2Initial;
|
||||
d1Initial = pad.m_digital_1;
|
||||
d2Initial = pad.m_digital_2;
|
||||
d1Initial = pad->m_digital_1;
|
||||
d2Initial = pad->m_digital_2;
|
||||
bool btnChanged = false;
|
||||
for(Button& button : pad.m_buttons)
|
||||
for(Button& button : pad->m_buttons)
|
||||
{
|
||||
//here we check btns, and set pad accordingly,
|
||||
//if something changed, set btnChanged
|
||||
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||
{
|
||||
if (button.m_pressed) pad.m_digital_1 |= button.m_outKeyCode;
|
||||
else pad.m_digital_1 &= ~button.m_outKeyCode;
|
||||
if (button.m_pressed) pad->m_digital_1 |= button.m_outKeyCode;
|
||||
else pad->m_digital_1 &= ~button.m_outKeyCode;
|
||||
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_LEFT:
|
||||
if (pad.m_press_left != button.m_value) btnChanged = true;
|
||||
pad.m_press_left = button.m_value;
|
||||
if (pad->m_press_left != button.m_value) btnChanged = true;
|
||||
pad->m_press_left = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_DOWN:
|
||||
if (pad.m_press_down != button.m_value) btnChanged = true;
|
||||
pad.m_press_down = button.m_value;
|
||||
if (pad->m_press_down != button.m_value) btnChanged = true;
|
||||
pad->m_press_down = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_RIGHT:
|
||||
if (pad.m_press_right != button.m_value) btnChanged = true;
|
||||
pad.m_press_right = button.m_value;
|
||||
if (pad->m_press_right != button.m_value) btnChanged = true;
|
||||
pad->m_press_right = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_UP:
|
||||
if (pad.m_press_up != button.m_value) btnChanged = true;
|
||||
pad.m_press_up = button.m_value;
|
||||
if (pad->m_press_up != button.m_value) btnChanged = true;
|
||||
pad->m_press_up = button.m_value;
|
||||
break;
|
||||
//These arent pressure btns
|
||||
case CELL_PAD_CTRL_R3:
|
||||
@@ -133,42 +133,42 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
}
|
||||
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
|
||||
{
|
||||
if (button.m_pressed) pad.m_digital_2 |= button.m_outKeyCode;
|
||||
else pad.m_digital_2 &= ~button.m_outKeyCode;
|
||||
if (button.m_pressed) pad->m_digital_2 |= button.m_outKeyCode;
|
||||
else pad->m_digital_2 &= ~button.m_outKeyCode;
|
||||
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_SQUARE:
|
||||
if (pad.m_press_square != button.m_value) btnChanged = true;
|
||||
pad.m_press_square = button.m_value;
|
||||
if (pad->m_press_square != button.m_value) btnChanged = true;
|
||||
pad->m_press_square = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CROSS:
|
||||
if (pad.m_press_cross != button.m_value) btnChanged = true;
|
||||
pad.m_press_cross = button.m_value;
|
||||
if (pad->m_press_cross != button.m_value) btnChanged = true;
|
||||
pad->m_press_cross = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CIRCLE:
|
||||
if (pad.m_press_circle != button.m_value) btnChanged = true;
|
||||
pad.m_press_circle = button.m_value;
|
||||
if (pad->m_press_circle != button.m_value) btnChanged = true;
|
||||
pad->m_press_circle = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_TRIANGLE:
|
||||
if (pad.m_press_triangle != button.m_value) btnChanged = true;
|
||||
pad.m_press_triangle = button.m_value;
|
||||
if (pad->m_press_triangle != button.m_value) btnChanged = true;
|
||||
pad->m_press_triangle = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_R1:
|
||||
if (pad.m_press_R1 != button.m_value) btnChanged = true;
|
||||
pad.m_press_R1 = button.m_value;
|
||||
if (pad->m_press_R1 != button.m_value) btnChanged = true;
|
||||
pad->m_press_R1 = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_L1:
|
||||
if (pad.m_press_L1 != button.m_value) btnChanged = true;
|
||||
pad.m_press_L1 = button.m_value;
|
||||
if (pad->m_press_L1 != button.m_value) btnChanged = true;
|
||||
pad->m_press_L1 = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_R2:
|
||||
if (pad.m_press_R2 != button.m_value) btnChanged = true;
|
||||
pad.m_press_R2 = button.m_value;
|
||||
if (pad->m_press_R2 != button.m_value) btnChanged = true;
|
||||
pad->m_press_R2 = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_L2:
|
||||
if (pad.m_press_L2 != button.m_value) btnChanged = true;
|
||||
pad.m_press_L2 = button.m_value;
|
||||
if (pad->m_press_L2 != button.m_value) btnChanged = true;
|
||||
pad->m_press_L2 = button.m_value;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
@@ -182,96 +182,131 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
}
|
||||
}
|
||||
|
||||
for (const AnalogStick& stick : pad.m_sticks)
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
{
|
||||
switch (stick.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
||||
if (pad.m_analog_left_x != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_left_x = stick.m_value;
|
||||
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_left_x = stick.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
|
||||
if (pad.m_analog_left_y != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_left_y = stick.m_value;
|
||||
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_left_y = stick.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
|
||||
if (pad.m_analog_right_x != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_right_x = stick.m_value;
|
||||
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_right_x = stick.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
|
||||
if (pad.m_analog_right_y != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_right_y = stick.m_value;
|
||||
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_right_y = stick.m_value;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const AnalogSensor& sensor : pad.m_sensors)
|
||||
for (const AnalogSensor& sensor : pad->m_sensors)
|
||||
{
|
||||
switch (sensor.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_X:
|
||||
if (pad.m_sensor_x != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_x = sensor.m_value;
|
||||
if (pad->m_sensor_x != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_x = sensor.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_Y:
|
||||
if (pad.m_sensor_y != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_y = sensor.m_value;
|
||||
if (pad->m_sensor_y != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_y = sensor.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_Z:
|
||||
if (pad.m_sensor_z != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_z = sensor.m_value;
|
||||
if (pad->m_sensor_z != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_z = sensor.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_G:
|
||||
if (pad.m_sensor_g != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_g = sensor.m_value;
|
||||
if (pad->m_sensor_g != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_g = sensor.m_value;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d1Initial != pad.m_digital_1 || d2Initial != pad.m_digital_2)
|
||||
if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2)
|
||||
{
|
||||
btnChanged = true;
|
||||
}
|
||||
|
||||
//not sure if this should officially change with capabilities/portsettings :(
|
||||
data->len = 24;
|
||||
|
||||
// the real hardware only fills the buffer up to "len" elements (16 bit each)
|
||||
if (pad->m_port_setting & CELL_PAD_SETTING_SENSOR_ON)
|
||||
{
|
||||
// report back new data every ~10 ms even if the input doesn't change
|
||||
// this is observed behaviour when using a Dualshock 3 controller
|
||||
static std::chrono::time_point<steady_clock> last_update[CELL_PAD_MAX_PORT_NUM] = { };
|
||||
const std::chrono::time_point<steady_clock> now = steady_clock::now();
|
||||
|
||||
if (pad.m_buffer_cleared)
|
||||
{
|
||||
pad.m_buffer_cleared = false;
|
||||
if (btnChanged || pad->m_buffer_cleared || (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_update[port_no]).count() >= 10))
|
||||
{
|
||||
data->len = CELL_PAD_LEN_CHANGE_SENSOR_ON;
|
||||
last_update[port_no] = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->len = CELL_PAD_LEN_NO_CHANGE;
|
||||
}
|
||||
}
|
||||
else if (!btnChanged)
|
||||
else if (btnChanged || pad->m_buffer_cleared)
|
||||
{
|
||||
data->len = 0;
|
||||
// only give back valid data if a controller state changed
|
||||
data->len = (pad->m_port_setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// report no state changes
|
||||
data->len = CELL_PAD_LEN_NO_CHANGE;
|
||||
}
|
||||
|
||||
pad->m_buffer_cleared = false;
|
||||
|
||||
// only update parts of the output struct depending on the controller setting
|
||||
if (data->len > CELL_PAD_LEN_NO_CHANGE)
|
||||
{
|
||||
memset(data->button, 0, sizeof(data->button));
|
||||
|
||||
data->button[0] = 0x0; // always 0
|
||||
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
|
||||
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15);
|
||||
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad->m_digital_1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad->m_digital_2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad->m_analog_right_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad->m_analog_right_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad->m_analog_left_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad->m_analog_left_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad->m_press_right;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad->m_press_left;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad->m_press_up;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad->m_press_down;
|
||||
}
|
||||
|
||||
if (data->len >= CELL_PAD_LEN_CHANGE_PRESS_ON)
|
||||
{
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad->m_press_triangle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad->m_press_circle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad->m_press_cross;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad->m_press_square;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad->m_press_L1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad->m_press_L2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad->m_press_R1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad->m_press_R2;
|
||||
}
|
||||
|
||||
if (data->len == CELL_PAD_LEN_CHANGE_SENSOR_ON)
|
||||
{
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad->m_sensor_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad->m_sensor_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad->m_sensor_z;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad->m_sensor_g;
|
||||
}
|
||||
data->button[0] = 0x0; // always 0
|
||||
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
|
||||
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15);
|
||||
//lets still send new data anyway, not sure whats expected still
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad.m_digital_1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad.m_digital_2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad.m_analog_right_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad.m_analog_right_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad.m_analog_left_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad.m_analog_left_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad.m_press_right;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad.m_press_left;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad.m_press_up;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad.m_press_down;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad.m_press_triangle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad.m_press_circle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad.m_press_cross;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad.m_press_square;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad.m_press_L1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad.m_press_L2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad.m_press_R1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad.m_press_R2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad.m_sensor_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad.m_sensor_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad.m_sensor_z;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad.m_sensor_g;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -280,7 +315,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
{
|
||||
sys_io.trace("cellPadPeriphGetInfo(info=*0x%x)", info);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -293,7 +328,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
info->now_connect = rinfo.now_connect;
|
||||
info->system_info = rinfo.system_info;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
// TODO: Support other types of controllers
|
||||
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
|
||||
@@ -301,10 +336,10 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
if (i >= pads.size())
|
||||
break;
|
||||
|
||||
info->port_status[i] = pads[i].m_port_status;
|
||||
info->port_setting[i] = pads[i].m_port_setting;
|
||||
info->device_capability[i] = pads[i].m_device_capability;
|
||||
info->device_type[i] = pads[i].m_device_type;
|
||||
info->port_status[i] = pads[i]->m_port_status;
|
||||
info->port_setting[i] = pads[i]->m_port_setting;
|
||||
info->device_capability[i] = pads[i]->m_device_capability;
|
||||
info->device_type[i] = pads[i]->m_device_type;
|
||||
info->pclass_type[i] = CELL_PAD_PCLASS_TYPE_STANDARD;
|
||||
info->pclass_profile[i] = 0x0;
|
||||
}
|
||||
@@ -315,7 +350,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
s32 cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
|
||||
{
|
||||
sys_io.trace("cellPadPeriphGetData(port_no=%d, data=*0x%x)", port_no, data);
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -342,7 +377,7 @@ s32 cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<CellPadDa
|
||||
{
|
||||
sys_io.trace("cellPadGetDataExtra(port_no=%d, device_type=*0x%x, device_type=*0x%x)", port_no, device_type, data);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -370,7 +405,7 @@ s32 cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
|
||||
{
|
||||
sys_io.trace("cellPadSetActDirect(port_no=%d, param=*0x%x)", port_no, param);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -391,7 +426,7 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
|
||||
{
|
||||
sys_io.trace("cellPadGetInfo(info=*0x%x)", info);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -403,15 +438,15 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
|
||||
info->now_connect = rinfo.now_connect;
|
||||
info->system_info = rinfo.system_info;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
for (u32 i=0; i<CELL_MAX_PADS; ++i)
|
||||
{
|
||||
if (i >= pads.size())
|
||||
break;
|
||||
|
||||
info->status[i] = pads[i].m_port_status;
|
||||
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->status[i] = pads[i]->m_port_status;
|
||||
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->product_id[i] = 0x0268;
|
||||
info->vendor_id[i] = 0x054C;
|
||||
}
|
||||
@@ -423,7 +458,7 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
|
||||
{
|
||||
sys_io.trace("cellPadGetInfo2(info=*0x%x)", info);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -435,18 +470,18 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
|
||||
info->now_connect = rinfo.now_connect;
|
||||
info->system_info = rinfo.system_info;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
for (u32 i=0; i<CELL_PAD_MAX_PORT_NUM; ++i)
|
||||
{
|
||||
if (i >= pads.size())
|
||||
break;
|
||||
|
||||
info->port_status[i] = pads[i].m_port_status;
|
||||
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->port_setting[i] = pads[i].m_port_setting;
|
||||
info->device_capability[i] = pads[i].m_device_capability;
|
||||
info->device_type[i] = pads[i].m_device_type;
|
||||
info->port_status[i] = pads[i]->m_port_status;
|
||||
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->port_setting[i] = pads[i]->m_port_setting;
|
||||
info->device_capability[i] = pads[i]->m_device_capability;
|
||||
info->device_type[i] = pads[i]->m_device_type;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@@ -456,7 +491,7 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
|
||||
{
|
||||
sys_io.trace("cellPadGetCapabilityInfo(port_no=%d, data_addr:=0x%x)", port_no, info.addr());
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -468,10 +503,10 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
const std::vector<Pad>& pads = handler->GetPads();
|
||||
const auto& pads = handler->GetPads();
|
||||
|
||||
//Should return the same as device capability mask, psl1ght has it backwards in pad.h
|
||||
info->info[0] = pads[port_no].m_device_capability;
|
||||
//Should return the same as device capability mask, psl1ght has it backwards in pad->h
|
||||
info->info[0] = pads[port_no]->m_device_capability;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -480,7 +515,7 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
|
||||
{
|
||||
sys_io.trace("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -492,8 +527,8 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
pads[port_no].m_port_setting = port_setting;
|
||||
auto& pads = handler->GetPads();
|
||||
pads[port_no]->m_port_setting = port_setting;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -502,7 +537,7 @@ s32 cellPadInfoPressMode(u32 port_no)
|
||||
{
|
||||
sys_io.trace("cellPadInfoPressMode(port_no=%d)", port_no);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -514,16 +549,16 @@ s32 cellPadInfoPressMode(u32 port_no)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
const std::vector<Pad>& pads = handler->GetPads();
|
||||
const auto& pads = handler->GetPads();
|
||||
|
||||
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
|
||||
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
|
||||
}
|
||||
|
||||
s32 cellPadInfoSensorMode(u32 port_no)
|
||||
{
|
||||
sys_io.trace("cellPadInfoSensorMode(port_no=%d)", port_no);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -535,16 +570,16 @@ s32 cellPadInfoSensorMode(u32 port_no)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
const std::vector<Pad>& pads = handler->GetPads();
|
||||
const auto& pads = handler->GetPads();
|
||||
|
||||
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
|
||||
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
|
||||
}
|
||||
|
||||
s32 cellPadSetPressMode(u32 port_no, u32 mode)
|
||||
{
|
||||
sys_io.trace("cellPadSetPressMode(port_no=%d, mode=%d)", port_no, mode);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -559,12 +594,12 @@ s32 cellPadSetPressMode(u32 port_no, u32 mode)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
if (mode)
|
||||
pads[port_no].m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
|
||||
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
|
||||
else
|
||||
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
|
||||
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -573,7 +608,7 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
|
||||
{
|
||||
sys_io.trace("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -588,12 +623,12 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
if (mode)
|
||||
pads[port_no].m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
|
||||
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
|
||||
else
|
||||
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
|
||||
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -602,7 +637,7 @@ s32 cellPadLddRegisterController()
|
||||
{
|
||||
sys_io.todo("cellPadLddRegisterController()");
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -614,7 +649,7 @@ s32 cellPadLddDataInsert(s32 handle, vm::ptr<CellPadData> data)
|
||||
{
|
||||
sys_io.todo("cellPadLddDataInsert(handle=%d, data=*0x%x)", handle, data);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -626,7 +661,7 @@ s32 cellPadLddGetPortNo(s32 handle)
|
||||
{
|
||||
sys_io.todo("cellPadLddGetPortNo(handle=%d)", handle);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -638,7 +673,7 @@ s32 cellPadLddUnregisterController(s32 handle)
|
||||
{
|
||||
sys_io.todo("cellPadLddUnregisterController(handle=%d)", handle);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
|
||||
@@ -27,6 +27,15 @@ enum
|
||||
CELL_PAD_PCLASS_TYPE_NAVIGATION = 0x05,
|
||||
};
|
||||
|
||||
// Length returned in CellPadData struct
|
||||
enum
|
||||
{
|
||||
CELL_PAD_LEN_NO_CHANGE = 0,
|
||||
CELL_PAD_LEN_CHANGE_DEFAULT = 8,
|
||||
CELL_PAD_LEN_CHANGE_PRESS_ON = 20,
|
||||
CELL_PAD_LEN_CHANGE_SENSOR_ON = 24,
|
||||
};
|
||||
|
||||
struct CellPadData
|
||||
{
|
||||
be_t<s32> len;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "sys_net.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
// Return Codes
|
||||
@@ -79,7 +77,9 @@ enum
|
||||
CELL_RUDP_POLL_EV_ERROR = 0x0008,
|
||||
};
|
||||
|
||||
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net::sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
|
||||
struct sys_net_sockaddr;
|
||||
|
||||
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net_sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
|
||||
|
||||
using CellRudpAllocatorFuncAlloc = vm::ptr<void>(u32 size);
|
||||
using CellRudpAllocatorFuncFree = void(vm::ptr<void> ptr);
|
||||
|
||||
@@ -103,13 +103,15 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" });
|
||||
|
||||
// get the saves matching the supplied prefix
|
||||
for (const auto& entry : fs::dir(base_dir))
|
||||
for (auto&& entry : fs::dir(base_dir))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.name = vfs::unescape(entry.name);
|
||||
|
||||
for (const auto& prefix : prefix_list)
|
||||
{
|
||||
if (entry.name.substr(0, prefix.size()) == prefix)
|
||||
@@ -453,8 +455,10 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
auto file_list = statGet->fileList.get_ptr();
|
||||
|
||||
for (const auto& entry : fs::dir(dir_path))
|
||||
for (auto&& entry : fs::dir(dir_path))
|
||||
{
|
||||
entry.name = vfs::unescape(entry.name);
|
||||
|
||||
// only files, system files ignored, fileNum is limited by setBuf->fileListMax
|
||||
if (!entry.is_directory && entry.name != "PARAM.SFO" && statGet->fileListNum++ < setBuf->fileListMax)
|
||||
{
|
||||
@@ -1083,7 +1087,7 @@ s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<Cell
|
||||
|
||||
void cellSysutil_SaveData_init()
|
||||
{
|
||||
REG_VNID(cellSysutil, 0x00000000u, g_savedata_context);
|
||||
REG_VAR(cellSysutil, g_savedata_context).flag(MFF_HIDDEN);
|
||||
|
||||
// libsysutil functions:
|
||||
REG_FUNC(cellSysutil, cellSaveDataEnableOverlay);
|
||||
|
||||
@@ -66,5 +66,5 @@ error_code cellSpudllHandleConfigSetDefaultValues(vm::ptr<CellSpudllHandleConfig
|
||||
DECLARE(ppu_module_manager::cellSpudll)("cellSpudll", []()
|
||||
{
|
||||
REG_FUNC(cellSpudll, cellSpudllGetImageSize);
|
||||
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flags = MFF_PERFECT;
|
||||
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flag(MFF_PERFECT);
|
||||
});
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <string>
|
||||
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Utilities/File.h"
|
||||
#include "Emu/VFS.h"
|
||||
|
||||
logs::channel cellSsl("cellSsl");
|
||||
|
||||
s32 cellSslInit()
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
enum SpecialCerts { BaltimoreCert = 6, Class3G2V2Cert = 13, ClassSSV4Cert = 15, EntrustNetCert = 18, GTECyberTrustGlobalCert = 23 };
|
||||
|
||||
s32 cellSslInit(vm::ptr<void> pool, u32 poolSize)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSsl);
|
||||
cellSsl.todo("cellSslInit(pool=0x%x, poolSize=%d)", pool, poolSize);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -15,9 +25,66 @@ s32 cellSslEnd()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSslCertificateLoader()
|
||||
std::string getCert(const std::string certPath, const int certID, const bool isNormalCert)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSsl);
|
||||
int newID = certID;
|
||||
|
||||
// The 'normal' certs have some special rules for loading.
|
||||
if (isNormalCert && certID >= BaltimoreCert && certID <= GTECyberTrustGlobalCert)
|
||||
{
|
||||
if (certID == BaltimoreCert)
|
||||
newID = GTECyberTrustGlobalCert;
|
||||
else if (certID == Class3G2V2Cert)
|
||||
newID = BaltimoreCert;
|
||||
else if (certID == EntrustNetCert)
|
||||
newID = ClassSSV4Cert;
|
||||
else
|
||||
newID = certID - 1;
|
||||
}
|
||||
|
||||
std::string filePath = fmt::format("%sCA%02d.cer", certPath, newID);
|
||||
|
||||
if (!fs::exists(filePath))
|
||||
{
|
||||
cellSsl.error("Can't find certificate file %s, do you have the PS3 firmware installed?", filePath);
|
||||
return "";
|
||||
}
|
||||
return fs::file(filePath).to_string();
|
||||
}
|
||||
|
||||
s32 cellSslCertificateLoader(u64 flag, vm::ptr<char> buffer, u32 size, vm::ptr<u32> required)
|
||||
{
|
||||
cellSsl.trace("cellSslCertificateLoader(flag=%llu, buffer=0x%x, size=%zu, required=0x%x)", flag, buffer, size, required);
|
||||
|
||||
const std::bitset<58> flagBits(flag);
|
||||
const std::string certPath = vfs::get("/dev_flash/") + "data/cert/";
|
||||
|
||||
if (required)
|
||||
{
|
||||
*required = 0;
|
||||
for (int i = 1; i <= flagBits.size(); i++)
|
||||
{
|
||||
if (!flagBits[i-1])
|
||||
continue;
|
||||
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
|
||||
*required += (u32)(getCert(certPath, i, flagBits[BaltimoreCert-1]).size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string final;
|
||||
for (int i = 1; i <= flagBits.size(); i++)
|
||||
{
|
||||
if (!flagBits[i-1])
|
||||
continue;
|
||||
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
|
||||
final.append(getCert(certPath, i, flagBits[BaltimoreCert-1]));
|
||||
}
|
||||
|
||||
memset(buffer.get_ptr(), '\0', size - 1);
|
||||
memcpy(buffer.get_ptr(), final.c_str(), final.size());
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,11 +100,8 @@ void fmt_class_string<CellSysutilLang>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
// For test
|
||||
enum systemparam_id_name : s32 {};
|
||||
|
||||
template <>
|
||||
void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
|
||||
void fmt_class_string<CellSysutilParamId>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](auto value)
|
||||
{
|
||||
@@ -133,13 +130,13 @@ void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
|
||||
s32 cellSysutilGetSystemParamInt(CellSysutilParamId id, vm::ptr<s32> value)
|
||||
{
|
||||
cellSysutil.warning("cellSysutilGetSystemParamInt(id=0x%x(%s), value=*0x%x)", id, id, value);
|
||||
|
||||
// TODO: load this information from config (preferably "sys/" group)
|
||||
|
||||
switch(id)
|
||||
switch (id)
|
||||
{
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG:
|
||||
*value = g_cfg.sys.language;
|
||||
@@ -208,13 +205,13 @@ s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilGetSystemParamString(systemparam_id_name id, vm::ptr<char> buf, u32 bufsize)
|
||||
s32 cellSysutilGetSystemParamString(CellSysutilParamId id, vm::ptr<char> buf, u32 bufsize)
|
||||
{
|
||||
cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, id, buf, bufsize);
|
||||
|
||||
memset(buf.get_ptr(), 0, bufsize);
|
||||
|
||||
switch(id)
|
||||
switch (id)
|
||||
{
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
|
||||
memcpy(buf.get_ptr(), "Unknown", 8); // for example
|
||||
|
||||
@@ -14,7 +14,7 @@ enum
|
||||
};
|
||||
|
||||
// Parameter IDs
|
||||
enum
|
||||
enum CellSysutilParamId: s32
|
||||
{
|
||||
// Integers
|
||||
CELL_SYSUTIL_SYSTEMPARAM_ID_LANG = 0x0111,
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/lv2/sys_sync.h"
|
||||
#include "Emu/Cell/lv2/sys_ppu_thread.h"
|
||||
#include "sysPrxForUser.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -74,11 +76,14 @@ struct vdec_thread : ppu_thread
|
||||
u32 frc_set{}; // Frame Rate Override
|
||||
u64 next_pts{};
|
||||
u64 next_dts{};
|
||||
u64 ppu_tid{};
|
||||
|
||||
std::mutex mutex;
|
||||
std::queue<vdec_frame> out;
|
||||
u32 max_frames = 60;
|
||||
|
||||
atomic_t<u32> au_count{0};
|
||||
|
||||
vdec_thread(s32 type, u32 profile, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg, u32 prio, u32 stack)
|
||||
: ppu_thread("HLE Video Decoder", prio, stack)
|
||||
, type(type)
|
||||
@@ -351,6 +356,11 @@ struct vdec_thread : ppu_thread
|
||||
cb_func(*this, id, vcmd == vdec_cmd::decode ? CELL_VDEC_MSG_TYPE_AUDONE : CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, cb_arg);
|
||||
lv2_obj::sleep(*this);
|
||||
}
|
||||
|
||||
if (vcmd == vdec_cmd::decode)
|
||||
{
|
||||
au_count--;
|
||||
}
|
||||
|
||||
while (std::lock_guard<std::mutex>{mutex}, max_frames && out.size() > max_frames)
|
||||
{
|
||||
@@ -397,7 +407,7 @@ u32 vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr<C
|
||||
attr->decoderVerLower = 0x280000; // from dmux
|
||||
attr->decoderVerUpper = 0x260000;
|
||||
attr->memSize = 4 * 1024 * 1024; // 4 MB
|
||||
attr->cmdDepth = 16;
|
||||
attr->cmdDepth = 4;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -415,7 +425,7 @@ s32 cellVdecQueryAttrEx(vm::cptr<CellVdecTypeEx> type, vm::ptr<CellVdecAttr> att
|
||||
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr);
|
||||
}
|
||||
|
||||
s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
||||
s32 cellVdecOpen(ppu_thread& ppu, vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
||||
{
|
||||
cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
||||
|
||||
@@ -425,12 +435,17 @@ s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm
|
||||
// Hack: store thread id (normally it should be pointer)
|
||||
*handle = vdec->id;
|
||||
|
||||
vm::var<u64> _tid;
|
||||
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
|
||||
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
|
||||
vdec->ppu_tid = *_tid;
|
||||
|
||||
vdec->run();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
||||
s32 cellVdecOpenEx(ppu_thread& ppu, vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
|
||||
{
|
||||
cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
|
||||
|
||||
@@ -440,6 +455,11 @@ s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> r
|
||||
// Hack: store thread id (normally it should be pointer)
|
||||
*handle = vdec->id;
|
||||
|
||||
vm::var<u64> _tid;
|
||||
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
|
||||
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
|
||||
vdec->ppu_tid = *_tid;
|
||||
|
||||
vdec->run();
|
||||
|
||||
return CELL_OK;
|
||||
@@ -467,6 +487,8 @@ s32 cellVdecClose(ppu_thread& ppu, u32 handle)
|
||||
vdec->notify();
|
||||
vdec->join();
|
||||
idm::remove<ppu_thread>(handle);
|
||||
|
||||
CALL_FUNC(ppu, sys_interrupt_thread_disestablish, ppu, vdec->ppu_tid);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -513,6 +535,11 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
|
||||
return CELL_VDEC_ERROR_ARG;
|
||||
}
|
||||
|
||||
if (vdec->au_count.fetch_op([](u32& c) { if (c < 4) c++; }) >= 4)
|
||||
{
|
||||
return CELL_VDEC_ERROR_BUSY;
|
||||
}
|
||||
|
||||
// TODO: check info
|
||||
vdec->cmd_list
|
||||
({
|
||||
|
||||
@@ -256,7 +256,7 @@ s32 cellVideoOutUnregisterCallback(u32 slot)
|
||||
void cellSysutil_VideoOut_init()
|
||||
{
|
||||
REG_FUNC(cellSysutil, cellVideoOutGetState);
|
||||
REG_FUNC(cellSysutil, cellVideoOutGetResolution).flags = MFF_PERFECT;
|
||||
REG_FUNC(cellSysutil, cellVideoOutGetResolution).flag(MFF_PERFECT);
|
||||
REG_FUNC(cellSysutil, cellVideoOutConfigure);
|
||||
REG_FUNC(cellSysutil, cellVideoOutGetConfiguration);
|
||||
REG_FUNC(cellSysutil, cellVideoOutGetDeviceInfo);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_process.h"
|
||||
#include "sysPrxForUser.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Crypto/unedat.h"
|
||||
#include "Crypto/unself.h"
|
||||
#include "cellRtc.h"
|
||||
#include "sceNp.h"
|
||||
#include "cellSysutil.h"
|
||||
|
||||
logs::channel sceNp("sceNp");
|
||||
|
||||
@@ -43,7 +44,15 @@ s32 sceNpTerm()
|
||||
|
||||
s32 npDrmIsAvailable(vm::cptr<u8> k_licensee_addr, vm::cptr<char> drm_path)
|
||||
{
|
||||
const std::string& enc_drm_path = drm_path.get_ptr();
|
||||
std::array<u8, 0x10> k_licensee{};
|
||||
|
||||
if (k_licensee_addr)
|
||||
{
|
||||
std::copy_n(k_licensee_addr.get_ptr(), k_licensee.size(), k_licensee.begin());
|
||||
sceNp.notice("npDrmIsAvailable(): KLicense key %s", *reinterpret_cast<be_t<v128, 1>*>(k_licensee.data()));
|
||||
}
|
||||
|
||||
const std::string enc_drm_path = drm_path.get_ptr();
|
||||
|
||||
if (!fs::is_file(vfs::get(enc_drm_path)))
|
||||
{
|
||||
@@ -51,20 +60,6 @@ s32 npDrmIsAvailable(vm::cptr<u8> k_licensee_addr, vm::cptr<char> drm_path)
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
std::string k_licensee_str = "";
|
||||
std::array<u8, 0x10> k_licensee{0};
|
||||
|
||||
if (k_licensee_addr)
|
||||
{
|
||||
for (s8 i = 0; i < 0x10; i++)
|
||||
{
|
||||
k_licensee[i] = *(k_licensee_addr + i);
|
||||
k_licensee_str += fmt::format("%02x", k_licensee[i]);
|
||||
}
|
||||
|
||||
sceNp.notice("npDrmIsAvailable(): KLicense key %s", k_licensee_str);
|
||||
}
|
||||
|
||||
auto npdrmkeys = fxm::get_always<LoadedNpdrmKeys_t>();
|
||||
|
||||
npdrmkeys->devKlic.fill(0);
|
||||
@@ -184,27 +179,29 @@ s32 sceNpDrmGetTimelimit(vm::cptr<char> path, vm::ptr<u64> time_remain)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpDrmProcessExitSpawn(vm::cptr<u8> klicensee, vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
|
||||
s32 sceNpDrmProcessExitSpawn(ppu_thread& ppu, vm::cptr<u8> klicensee, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
|
||||
{
|
||||
sceNp.warning("sceNpDrmProcessExitSpawn() -> sys_game_process_exitspawn");
|
||||
sceNp.warning("sceNpDrmProcessExitSpawn(klicensee=*0x%x, path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", klicensee, path, argv, envp, data, data_size, prio, flags);
|
||||
|
||||
sceNp.warning("klicensee: 0x%x", klicensee);
|
||||
npDrmIsAvailable(klicensee, path);
|
||||
|
||||
sys_game_process_exitspawn(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
|
||||
if (s32 error = npDrmIsAvailable(klicensee, path))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
sys_game_process_exitspawn(ppu, path, argv, envp, data, data_size, prio, flags);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpDrmProcessExitSpawn2(vm::cptr<u8> klicensee, vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
|
||||
s32 sceNpDrmProcessExitSpawn2(ppu_thread& ppu, vm::cptr<u8> klicensee, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
|
||||
{
|
||||
sceNp.warning("sceNpDrmProcessExitSpawn2() -> sys_game_process_exitspawn2");
|
||||
sceNp.warning("sceNpDrmProcessExitSpawn2(klicensee=*0x%x, path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", klicensee, path, argv, envp, data, data_size, prio, flags);
|
||||
|
||||
sceNp.warning("klicensee: 0x%x", klicensee);
|
||||
npDrmIsAvailable(klicensee, path);
|
||||
|
||||
sys_game_process_exitspawn2(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
|
||||
if (s32 error = npDrmIsAvailable(klicensee, path))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
sys_game_process_exitspawn2(ppu, path, argv, envp, data, data_size, prio, flags);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -905,16 +902,12 @@ s32 sceNpLookupTitleSmallStorageAsync()
|
||||
|
||||
s32 sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback, vm::ptr<void> arg)
|
||||
{
|
||||
sceNp.todo("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg);
|
||||
sceNp.warning("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg);
|
||||
|
||||
if (!callback)
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SCE_NP_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,8 @@ s32 sceNpSnsFbCheckThrottle()
|
||||
|
||||
s32 sceNpSnsFbCheckConfig()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
sceNpSns.todo("sceNpSnsFbCheckConfig()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpSnsFbLoadThrottle()
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
logs::channel sceNpTrophy("sceNpTrophy");
|
||||
|
||||
TrophyNotificationBase::~TrophyNotificationBase()
|
||||
{
|
||||
}
|
||||
|
||||
struct trophy_context_t
|
||||
{
|
||||
static const u32 id_base = 1;
|
||||
@@ -181,9 +185,8 @@ error_code sceNpTrophyCreateContext(vm::ptr<u32> context, vm::cptr<SceNpCommunic
|
||||
sceNpTrophy.warning("sceNpTrophyCreateContext term=%s data=%s num=%d", commId->term, commId->data, commId->num);
|
||||
if (commId->term)
|
||||
{
|
||||
char trimchar[9];
|
||||
memcpy(trimchar, commId->data, sizeof(trimchar));
|
||||
trimchar[8] = 0;
|
||||
char trimchar[10] = { 0 };
|
||||
memcpy(trimchar, commId->data, sizeof(trimchar) - 1);
|
||||
deleteTerminateChar(trimchar, commId->term);
|
||||
name = fmt::format("%s_%02d", trimchar, commId->num);
|
||||
}
|
||||
@@ -265,7 +268,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
|
||||
const size_t kTargetBufferLength = 31;
|
||||
char target[kTargetBufferLength + 1];
|
||||
target[kTargetBufferLength] = 0;
|
||||
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", /*rpcs3::config.system.language.value()*/0));
|
||||
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", static_cast<s32>(g_cfg.sys.language)));
|
||||
|
||||
if (trp.ContainsEntry(target))
|
||||
{
|
||||
@@ -287,7 +290,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
|
||||
for (s32 i = 0; i <= 18; i++)
|
||||
{
|
||||
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", i));
|
||||
if (i != /*rpcs3::config.system.language.value()*/0)
|
||||
if (i != g_cfg.sys.language)
|
||||
{
|
||||
trp.RemoveEntry(target);
|
||||
}
|
||||
@@ -398,12 +401,15 @@ error_code sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGa
|
||||
}
|
||||
|
||||
// TODO: Get the path of the current user
|
||||
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM");
|
||||
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
|
||||
|
||||
if (!config)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
// TODO: rXmlDocument can open only real file
|
||||
verify(HERE), !fs::get_virtual_device(path);
|
||||
rXmlDocument doc;
|
||||
doc.Load(path);
|
||||
doc.Read(config.to_string());
|
||||
|
||||
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext())
|
||||
{
|
||||
@@ -474,7 +480,7 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
if (trophyId >= (s32)ctxt->tropusr->GetTrophiesCount())
|
||||
if (trophyId < 0 || trophyId >= (s32)ctxt->tropusr->GetTrophiesCount())
|
||||
return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
|
||||
if (ctxt->tropusr->GetTrophyUnlockState(trophyId))
|
||||
return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED;
|
||||
@@ -483,7 +489,45 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPUSR.DAT";
|
||||
ctxt->tropusr->Save(trophyPath);
|
||||
|
||||
*platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
|
||||
if (platinumId)
|
||||
{
|
||||
*platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
|
||||
}
|
||||
|
||||
if (g_cfg.misc.show_trophy_popups)
|
||||
{
|
||||
// Figure out how many zeros are needed for padding. (either 0, 1, or 2)
|
||||
std::string padding = "";
|
||||
if (trophyId < 10)
|
||||
{
|
||||
padding = "00";
|
||||
}
|
||||
else if (trophyId < 100)
|
||||
{
|
||||
padding = "0";
|
||||
}
|
||||
|
||||
// Get icon for the notification.
|
||||
std::string trophyIconPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROP" + padding + std::to_string(trophyId) + ".PNG";
|
||||
fs::file trophyIconFile = fs::file(vfs::get(trophyIconPath));
|
||||
u32 iconSize = trophyIconFile.size();
|
||||
std::vector<uchar> trophyIconData;
|
||||
trophyIconFile.read(trophyIconData, iconSize);
|
||||
|
||||
vm::ptr<SceNpTrophyDetails> details = vm::make_var(SceNpTrophyDetails());
|
||||
vm::ptr<SceNpTrophyData> _ = vm::make_var(SceNpTrophyData());
|
||||
|
||||
s32 ret = sceNpTrophyGetTrophyInfo(context, handle, trophyId, details, _);
|
||||
if (ret != CELL_OK)
|
||||
{
|
||||
sceNpTrophy.error("Failed to get info for trophy dialog. Error code %x", ret);
|
||||
*details = SceNpTrophyDetails();
|
||||
}
|
||||
Emu.CallAfter([det = *details, trophyIconData]() {
|
||||
Emu.GetCallbacks().get_trophy_notification_dialog()->ShowTrophyNotification(det, trophyIconData);
|
||||
});
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -551,15 +595,25 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
|
||||
}
|
||||
|
||||
// TODO: Get the path of the current user
|
||||
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM");
|
||||
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
|
||||
|
||||
if (!config)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
// TODO: rXmlDocument can open only real file
|
||||
verify(HERE), !fs::get_virtual_device(path);
|
||||
rXmlDocument doc;
|
||||
doc.Load(path);
|
||||
doc.Read(config.to_string());
|
||||
|
||||
auto trophy_base = doc.GetRoot();
|
||||
if (trophy_base->GetChildren()->GetName() == "trophyconf")
|
||||
{
|
||||
trophy_base = trophy_base->GetChildren();
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) {
|
||||
for (std::shared_ptr<rXmlNode> n = trophy_base->GetChildren(); n; n = n->GetNext())
|
||||
{
|
||||
if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").c_str())))
|
||||
{
|
||||
found = true;
|
||||
@@ -676,21 +730,21 @@ error_code sceNpTrophyGetGameIcon(u32 context, u32 handle, vm::ptr<void> buffer,
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/ICON0.PNG");
|
||||
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/ICON0.PNG"));
|
||||
|
||||
if (!fs::exists(path))
|
||||
if (!icon_file)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_FILE;
|
||||
}
|
||||
|
||||
fs::file gameIconFile(path);
|
||||
const u32 icon_size = ::size32(icon_file);
|
||||
|
||||
if (buffer && *size >= gameIconFile.size())
|
||||
if (buffer && *size >= icon_size)
|
||||
{
|
||||
gameIconFile.read(buffer.get_ptr(), gameIconFile.size());
|
||||
icon_file.read(buffer.get_ptr(), icon_size);
|
||||
}
|
||||
|
||||
*size = gameIconFile.size();
|
||||
*size = icon_size;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -729,21 +783,21 @@ error_code sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::p
|
||||
return hidden ? SCE_NP_TROPHY_ERROR_HIDDEN : SCE_NP_TROPHY_ERROR_LOCKED;
|
||||
}
|
||||
|
||||
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + fmt::format("/TROP%03d.PNG", trophyId));
|
||||
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + fmt::format("/TROP%03d.PNG", trophyId)));
|
||||
|
||||
if (!fs::exists(path))
|
||||
if (!icon_file)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_FILE;
|
||||
}
|
||||
|
||||
fs::file trophyIconFile(path);
|
||||
const u32 icon_size = ::size32(icon_file);
|
||||
|
||||
if (buffer && *size >= trophyIconFile.size())
|
||||
if (buffer && *size >= icon_size)
|
||||
{
|
||||
trophyIconFile.read(buffer.get_ptr(), trophyIconFile.size());
|
||||
icon_file.read(buffer.get_ptr(), icon_size);
|
||||
}
|
||||
|
||||
*size = trophyIconFile.size();
|
||||
*size = icon_size;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -137,3 +137,14 @@ enum
|
||||
};
|
||||
|
||||
using SceNpTrophyStatusCallback = s32(u32 context, u32 status, s32 completed, s32 total, vm::ptr<void> arg);
|
||||
|
||||
// Forward declare this function since trophyunlock needs it
|
||||
error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> data);
|
||||
|
||||
class TrophyNotificationBase
|
||||
{
|
||||
public:
|
||||
virtual ~TrophyNotificationBase();
|
||||
|
||||
virtual s32 ShowTrophyNotification(const SceNpTrophyDetails& trophy, const std::vector<uchar>& trophyIconBfr) = 0;
|
||||
};
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_mutex.h"
|
||||
#include "Emu/Cell/lv2/sys_interrupt.h"
|
||||
#include "Emu/Cell/lv2/sys_process.h"
|
||||
#include "Emu/Cell/lv2/sys_ss.h"
|
||||
#include "sysPrxForUser.h"
|
||||
|
||||
logs::channel sysPrxForUser("sysPrxForUser");
|
||||
@@ -13,6 +15,9 @@ extern u64 get_system_time();
|
||||
extern fs::file g_tty;
|
||||
|
||||
vm::gvar<s32> sys_prx_version; // ???
|
||||
vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
|
||||
vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
|
||||
extern vm::gvar<u32> g_ppu_exit_mutex;
|
||||
|
||||
s64 sys_time_get_system_time()
|
||||
{
|
||||
@@ -21,16 +26,34 @@ s64 sys_time_get_system_time()
|
||||
return get_system_time();
|
||||
}
|
||||
|
||||
s64 _sys_process_atexitspawn()
|
||||
void sys_process_exit(ppu_thread& ppu, s32 status)
|
||||
{
|
||||
sysPrxForUser.todo("_sys_process_atexitspawn()");
|
||||
return CELL_OK;
|
||||
sysPrxForUser.warning("sys_process_exit(status=%d)", status);
|
||||
|
||||
sys_mutex_lock(ppu, *g_ppu_exit_mutex, 0);
|
||||
|
||||
// TODO (process atexit)
|
||||
return _sys_process_exit(ppu, status, 0, 0);
|
||||
}
|
||||
|
||||
s64 _sys_process_at_Exitspawn()
|
||||
void _sys_process_atexitspawn(vm::ptr<void()> func)
|
||||
{
|
||||
sysPrxForUser.todo("_sys_process_at_Exitspawn");
|
||||
return CELL_OK;
|
||||
sysPrxForUser.warning("_sys_process_atexitspawn(0x%x)", func);
|
||||
|
||||
if (!*g_ppu_atexitspawn)
|
||||
{
|
||||
*g_ppu_atexitspawn = func;
|
||||
}
|
||||
}
|
||||
|
||||
void _sys_process_at_Exitspawn(vm::ptr<void()> func)
|
||||
{
|
||||
sysPrxForUser.warning("_sys_process_at_Exitspawn(0x%x)", func);
|
||||
|
||||
if (!*g_ppu_at_Exitspawn)
|
||||
{
|
||||
*g_ppu_at_Exitspawn = func;
|
||||
}
|
||||
}
|
||||
|
||||
s32 sys_process_is_stack(u32 p)
|
||||
@@ -49,24 +72,23 @@ s32 sys_process_get_paramsfo(vm::ptr<char> buffer)
|
||||
return _sys_process_get_paramsfo(buffer);
|
||||
}
|
||||
|
||||
s32 sys_get_random_number(vm::ptr<u8> addr, u64 size)
|
||||
s32 sys_get_random_number(vm::ptr<void> addr, u64 size)
|
||||
{
|
||||
sysPrxForUser.warning("sys_get_random_number(addr=*0x%x, size=%d)", addr, size);
|
||||
|
||||
if (size > 4096)
|
||||
size = 4096;
|
||||
|
||||
for (u32 i = 0; i < (u32)size - 1; i++)
|
||||
if (size > 0x1000)
|
||||
{
|
||||
addr[i] = rand() % 256;
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
switch (u32 rs = sys_ss_random_number_generator(2, addr, size))
|
||||
{
|
||||
case 0x80010501: return CELL_ENOMEM;
|
||||
case 0x80010503: return CELL_EAGAIN;
|
||||
case 0x80010509: return CELL_EINVAL;
|
||||
default: if (rs) return CELL_EABORT;
|
||||
}
|
||||
|
||||
s32 __sys_look_ctype_table()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sysPrxForUser);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -231,10 +253,11 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
|
||||
sysPrxForUser_sys_rsxaudio_init();
|
||||
|
||||
REG_VAR(sysPrxForUser, sys_prx_version); // 0x7df066cf
|
||||
REG_VAR(sysPrxForUser, g_ppu_atexitspawn).flag(MFF_HIDDEN);
|
||||
REG_VAR(sysPrxForUser, g_ppu_at_Exitspawn).flag(MFF_HIDDEN);
|
||||
|
||||
REG_FUNC(sysPrxForUser, sys_time_get_system_time);
|
||||
|
||||
// TODO: split syscalls and liblv2 functions
|
||||
REG_FUNC(sysPrxForUser, sys_process_exit);
|
||||
REG_FUNC(sysPrxForUser, _sys_process_atexitspawn);
|
||||
REG_FUNC(sysPrxForUser, _sys_process_at_Exitspawn);
|
||||
@@ -243,8 +266,6 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
|
||||
|
||||
REG_FUNC(sysPrxForUser, sys_get_random_number);
|
||||
|
||||
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);
|
||||
|
||||
REG_FUNC(sysPrxForUser, console_getc);
|
||||
REG_FUNC(sysPrxForUser, console_putc);
|
||||
REG_FUNC(sysPrxForUser, console_write);
|
||||
|
||||
@@ -52,4 +52,9 @@ error_code sys_lwcond_signal_all(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
||||
error_code sys_lwcond_signal_to(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
|
||||
error_code sys_lwcond_wait(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
|
||||
|
||||
error_code sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::cptr<char> threadname);
|
||||
error_code sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih);
|
||||
|
||||
void sys_ppu_thread_exit(ppu_thread& CPU, u64 val);
|
||||
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
|
||||
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
|
||||
|
||||
+122
-117
@@ -2,148 +2,153 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_mutex.h"
|
||||
#include "Emu/Cell/lv2/sys_process.h"
|
||||
#include "sysPrxForUser.h"
|
||||
|
||||
extern logs::channel sysPrxForUser;
|
||||
extern vm::gvar<u32> g_ppu_exit_mutex;
|
||||
extern vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
|
||||
extern vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
|
||||
|
||||
void sys_game_process_exitspawn(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
|
||||
static u32 get_string_array_size(vm::cpptr<char> list, u32& out_count)
|
||||
{
|
||||
std::string _path = path.get_ptr();
|
||||
const std::string& from = "//";
|
||||
const std::string& to = "/";
|
||||
//out_count = 0;
|
||||
u32 result = 8;
|
||||
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
|
||||
_path.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length();
|
||||
for (u32 i = 0; list; i++)
|
||||
{
|
||||
if (const vm::cptr<char> str = list[i])
|
||||
{
|
||||
out_count++;
|
||||
result += (((u32)std::strlen(str.get_ptr()) + 0x10) & -0x10) + 8;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sysPrxForUser.todo("sys_game_process_exitspawn()");
|
||||
sysPrxForUser.warning("path: %s", _path.c_str());
|
||||
sysPrxForUser.warning("argv: 0x%x", argv_addr);
|
||||
sysPrxForUser.warning("envp: 0x%x", envp_addr);
|
||||
sysPrxForUser.warning("data: 0x%x", data_addr);
|
||||
sysPrxForUser.warning("data_size: 0x%x", data_size);
|
||||
sysPrxForUser.warning("prio: %d", prio);
|
||||
sysPrxForUser.warning("flags: %d", flags);
|
||||
|
||||
std::vector<std::string> argv;
|
||||
std::vector<std::string> env;
|
||||
|
||||
if (argv_addr)
|
||||
{
|
||||
auto argvp = vm::cpptr<char>::make(argv_addr);
|
||||
while (argvp && *argvp)
|
||||
{
|
||||
argv.push_back(argvp[0].get_ptr());
|
||||
argvp++;
|
||||
}
|
||||
|
||||
for (auto &arg : argv)
|
||||
{
|
||||
sysPrxForUser.trace("argument: %s", arg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (envp_addr)
|
||||
{
|
||||
auto envp = vm::cpptr<char>::make(envp_addr);
|
||||
while (envp && *envp)
|
||||
{
|
||||
env.push_back(envp[0].get_ptr());
|
||||
envp++;
|
||||
}
|
||||
|
||||
for (auto &en : env)
|
||||
{
|
||||
sysPrxForUser.trace("env_argument: %s", en.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: execute the file in <path> with the args in argv
|
||||
// and the environment parameters in envp and copy the data
|
||||
// from data_addr into the adress space of the new process
|
||||
// then kill the current process
|
||||
|
||||
Emu.Pause();
|
||||
sysPrxForUser.success("Process finished");
|
||||
|
||||
Emu.CallAfter([=, path = vfs::get(_path)]()
|
||||
{
|
||||
Emu.Stop();
|
||||
Emu.BootGame(path, true);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void sys_game_process_exitspawn2(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
|
||||
static u32 get_exitspawn_size(vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32& arg_count, u32& env_count)
|
||||
{
|
||||
std::string _path = path.get_ptr();
|
||||
const std::string& from = "//";
|
||||
const std::string& to = "/";
|
||||
arg_count = 1;
|
||||
env_count = 0;
|
||||
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
|
||||
_path.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length();
|
||||
u32 result = (((u32)std::strlen(path.get_ptr()) + 0x10) & -0x10) + 8;
|
||||
result += get_string_array_size(argv, arg_count);
|
||||
result += get_string_array_size(envp, env_count);
|
||||
|
||||
if ((arg_count + env_count) % 2)
|
||||
{
|
||||
result += 8;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void put_string_array(vm::pptr<char, u32, u64> pstr, vm::ptr<char>& str, u32 count, vm::cpptr<char> list)
|
||||
{
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
const u32 len = (u32)std::strlen(list[i].get_ptr());
|
||||
std::memcpy(str.get_ptr(), list[i].get_ptr(), len + 1);
|
||||
pstr[i] = str;
|
||||
str += (len + 0x10) & -0x10;
|
||||
}
|
||||
|
||||
sysPrxForUser.warning("sys_game_process_exitspawn2()");
|
||||
sysPrxForUser.warning("path: %s", _path.c_str());
|
||||
sysPrxForUser.warning("argv: 0x%x", argv_addr);
|
||||
sysPrxForUser.warning("envp: 0x%x", envp_addr);
|
||||
sysPrxForUser.warning("data: 0x%x", data_addr);
|
||||
sysPrxForUser.warning("data_size: 0x%x", data_size);
|
||||
sysPrxForUser.warning("prio: %d", prio);
|
||||
sysPrxForUser.warning("flags: %d", flags);
|
||||
pstr[count] = vm::null;
|
||||
}
|
||||
|
||||
std::vector<std::string> argv;
|
||||
std::vector<std::string> env;
|
||||
static void put_exitspawn(vm::ptr<void> out, vm::cptr<char> path, u32 argc, vm::cpptr<char> argv, u32 envc, vm::cpptr<char> envp)
|
||||
{
|
||||
vm::pptr<char, u32, u64> pstr = vm::cast(out.addr());
|
||||
vm::ptr<char> str = vm::static_ptr_cast<char>(out) + (argc + envc + (argc + envc) % 2) * 8 + 0x10;
|
||||
|
||||
if (argv_addr)
|
||||
const u32 len = (u32)std::strlen(path.get_ptr());
|
||||
std::memcpy(str.get_ptr(), path.get_ptr(), len + 1);
|
||||
*pstr++ = str;
|
||||
str += (len + 0x10) & -0x10;
|
||||
|
||||
put_string_array(pstr, str, argc - 1, argv);
|
||||
put_string_array(pstr + argc, str, envc, envp);
|
||||
}
|
||||
|
||||
static void exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 _flags)
|
||||
{
|
||||
sys_mutex_lock(ppu, *g_ppu_exit_mutex, 0);
|
||||
|
||||
u32 arg_count = 0;
|
||||
u32 env_count = 0;
|
||||
u32 alloc_size = get_exitspawn_size(path, argv, envp, arg_count, env_count);
|
||||
|
||||
if (alloc_size > 0x1000)
|
||||
{
|
||||
auto argvp = vm::cpptr<char>::make(argv_addr);
|
||||
while (argvp && *argvp)
|
||||
{
|
||||
argv.push_back(argvp[0].get_ptr());
|
||||
argvp++;
|
||||
}
|
||||
|
||||
for (auto &arg : argv)
|
||||
{
|
||||
sysPrxForUser.trace("argument: %s", arg.c_str());
|
||||
}
|
||||
argv = vm::null;
|
||||
envp = vm::null;
|
||||
arg_count = 0;
|
||||
env_count = 0;
|
||||
alloc_size = get_exitspawn_size(path, vm::null, vm::null, arg_count, env_count);
|
||||
}
|
||||
|
||||
if (envp_addr)
|
||||
{
|
||||
auto envp = vm::cpptr<char>::make(envp_addr);
|
||||
while (envp && *envp)
|
||||
{
|
||||
env.push_back(envp[0].get_ptr());
|
||||
envp++;
|
||||
}
|
||||
alloc_size += 0x30;
|
||||
|
||||
for (auto &en : env)
|
||||
{
|
||||
sysPrxForUser.trace("env_argument: %s", en.c_str());
|
||||
}
|
||||
if (data_size > 0)
|
||||
{
|
||||
alloc_size += 0x1030;
|
||||
}
|
||||
|
||||
// TODO: execute the file in <path> with the args in argv
|
||||
// and the environment parameters in envp and copy the data
|
||||
// from data_addr into the adress space of the new process
|
||||
// then kill the current process
|
||||
u32 alloc_addr = vm::alloc(alloc_size, vm::main);
|
||||
|
||||
Emu.Pause();
|
||||
sysPrxForUser.success("Process finished");
|
||||
|
||||
Emu.CallAfter([=, path = vfs::get(_path)]()
|
||||
if (!alloc_addr)
|
||||
{
|
||||
Emu.Stop();
|
||||
Emu.BootGame(path, true);
|
||||
});
|
||||
// TODO (process atexit)
|
||||
return _sys_process_exit(ppu, CELL_ENOMEM, 0, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
put_exitspawn(vm::cast(alloc_addr + 0x30), path, arg_count, argv, env_count, envp);
|
||||
|
||||
if (data_size)
|
||||
{
|
||||
std::memcpy(vm::base(alloc_addr + alloc_size - 0x1000), vm::base(data), std::min<u32>(data_size, 0x1000));
|
||||
}
|
||||
|
||||
vm::ptr<sys_exit2_param> arg = vm::cast(alloc_addr);
|
||||
arg->x0 = 0x85;
|
||||
arg->this_size = 0x30;
|
||||
arg->next_size = alloc_size - 0x30;
|
||||
arg->prio = prio;
|
||||
arg->flags = _flags;
|
||||
arg->args = vm::cast(alloc_addr + 0x30);
|
||||
|
||||
if ((_flags >> 62) == 0 && *g_ppu_atexitspawn)
|
||||
{
|
||||
// Execute atexitspawn
|
||||
g_ppu_atexitspawn->operator()(ppu);
|
||||
}
|
||||
|
||||
if ((_flags >> 62) == 1 && *g_ppu_at_Exitspawn)
|
||||
{
|
||||
// Execute at_Exitspawn
|
||||
g_ppu_at_Exitspawn->operator()(ppu);
|
||||
}
|
||||
|
||||
// TODO (process atexit)
|
||||
return _sys_process_exit2(ppu, 0, arg, alloc_size, 0x10000000);
|
||||
}
|
||||
|
||||
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
|
||||
{
|
||||
sysPrxForUser.warning("sys_game_process_exitspawn(path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", path, argv, envp, data, data_size, prio, flags);
|
||||
|
||||
return exitspawn(ppu, path, argv, envp, data, data_size, prio, (flags & 0xf0) | (1ull << 63));
|
||||
}
|
||||
|
||||
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
|
||||
{
|
||||
sysPrxForUser.warning("sys_game_process_exitspawn2(path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", path, argv, envp, data, data_size, prio, flags);
|
||||
|
||||
return exitspawn(ppu, path, argv, envp, data, data_size, prio, (flags >> 62) >= 2 ? flags & 0xf0 : flags & 0xc0000000000000f0ull);
|
||||
}
|
||||
|
||||
s32 sys_game_board_storage_read()
|
||||
|
||||
@@ -16,5 +16,5 @@ void sys_libc_memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
|
||||
|
||||
DECLARE(ppu_module_manager::sys_libc)("sys_libc", []()
|
||||
{
|
||||
REG_FNID(sys_libc, "memcpy", sys_libc_memcpy).flags = MFF_FORCED_HLE;
|
||||
REG_FNID(sys_libc, "memcpy", sys_libc_memcpy).flag(MFF_FORCED_HLE);
|
||||
});
|
||||
|
||||
@@ -72,6 +72,51 @@ static std::string ps3_fmt(ppu_thread& context, vm::cptr<char> fmt, u32 g_count)
|
||||
return result;
|
||||
}
|
||||
|
||||
static const std::array<s16, 129> s_ctype_table
|
||||
{
|
||||
0,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x408,
|
||||
8, 8, 8, 8,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x18,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0x10, 0x10, 0x10, 0x10, 0x20,
|
||||
};
|
||||
|
||||
s16 __sys_look_ctype_table(s32 ch)
|
||||
{
|
||||
sysPrxForUser.trace("__sys_look_ctype_table(ch=%d)", ch);
|
||||
|
||||
verify("__sys_look_ctype_table" HERE), ch >= -1 && ch <= 127;
|
||||
|
||||
return s_ctype_table[ch + 1];
|
||||
}
|
||||
|
||||
s32 _sys_tolower(s32 ch)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_tolower(ch=%d)", ch);
|
||||
|
||||
verify("_sys_tolower" HERE), ch >= -1 && ch <= 127;
|
||||
|
||||
return s_ctype_table[ch + 1] & 1 ? ch + 0x20 : ch;
|
||||
}
|
||||
|
||||
s32 _sys_toupper(s32 ch)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_toupper(ch=%d)", ch);
|
||||
|
||||
verify("_sys_toupper" HERE), ch >= -1 && ch <= 127;
|
||||
|
||||
return s_ctype_table[ch + 1] & 2 ? ch - 0x20 : ch;
|
||||
}
|
||||
|
||||
vm::ptr<void> _sys_memset(vm::ptr<void> dst, s32 value, u32 size)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size);
|
||||
@@ -90,11 +135,26 @@ vm::ptr<void> _sys_memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
|
||||
return dst;
|
||||
}
|
||||
|
||||
s32 _sys_memcmp(vm::cptr<void> buf1, vm::cptr<void> buf2, u32 size)
|
||||
s32 _sys_memcmp(vm::cptr<u8> buf1, vm::cptr<u8> buf2, u32 size)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_memcmp(buf1=*0x%x, buf2=*0x%x, size=%d)", buf1, buf2, size);
|
||||
|
||||
return std::memcmp(buf1.get_ptr(), buf2.get_ptr(), size);
|
||||
for (u32 i = 0; i < size; i++)
|
||||
{
|
||||
const u8 b1 = buf1[i], b2 = buf2[i];
|
||||
|
||||
if (b1 < b2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (b1 > b2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vm::ptr<u8> _sys_memchr(vm::ptr<u8> buf, u8 ch, s32 size)
|
||||
@@ -129,82 +189,160 @@ vm::ptr<void> _sys_memmove(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
|
||||
return dst;
|
||||
}
|
||||
|
||||
s64 _sys_strlen(vm::cptr<char> str)
|
||||
u32 _sys_strlen(vm::cptr<char> str)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strlen(str=%s)", str);
|
||||
|
||||
return std::strlen(str.get_ptr());
|
||||
if (!str)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (u32 i = 0;; i++)
|
||||
{
|
||||
if (str[i] == '\0')
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 _sys_strcmp(vm::cptr<char> str1, vm::cptr<char> str2)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strcmp(str1=%s, str2=%s)", str1, str2);
|
||||
|
||||
return std::strcmp(str1.get_ptr(), str2.get_ptr());
|
||||
for (u32 i = 0;; i++)
|
||||
{
|
||||
const u8 ch1 = str1[i], ch2 = str2[i];
|
||||
if (ch1 < ch2)
|
||||
return -1;
|
||||
if (ch1 > ch2)
|
||||
return 1;
|
||||
if (ch1 == '\0')
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
s32 _sys_strncmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 max)
|
||||
s32 _sys_strncmp(vm::cptr<char> str1, vm::cptr<char> str2, u32 max)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strncmp(str1=%s, str2=%s, max=%d)", str1, str2, max);
|
||||
|
||||
return std::strncmp(str1.get_ptr(), str2.get_ptr(), max);
|
||||
for (u32 i = 0; i < max; i++)
|
||||
{
|
||||
const u8 ch1 = str1[i], ch2 = str2[i];
|
||||
if (ch1 < ch2)
|
||||
return -1;
|
||||
if (ch1 > ch2)
|
||||
return 1;
|
||||
if (ch1 == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vm::ptr<char> _sys_strcat(vm::ptr<char> dest, vm::cptr<char> source)
|
||||
vm::ptr<char> _sys_strcat(vm::ptr<char> dst, vm::cptr<char> src)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strcat(dest=*0x%x, source=%s)", dest, source);
|
||||
sysPrxForUser.trace("_sys_strcat(dst=*0x%x %s, src=%s)", dst, dst, src);
|
||||
|
||||
verify(HERE), std::strcat(dest.get_ptr(), source.get_ptr()) == dest.get_ptr();
|
||||
auto str = dst;
|
||||
|
||||
return dest;
|
||||
while (*str)
|
||||
{
|
||||
str++;
|
||||
}
|
||||
|
||||
for (u32 i = 0;; i++)
|
||||
{
|
||||
if (!(str[i] = src[i]))
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm::cptr<char> _sys_strchr(vm::cptr<char> str, s32 ch)
|
||||
vm::cptr<char> _sys_strchr(vm::cptr<char> str, char ch)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strchr(str=%s, ch=0x%x)", str, ch);
|
||||
sysPrxForUser.trace("_sys_strchr(str=%s, ch=%d)", str, ch);
|
||||
|
||||
return vm::cptr<char>::make(vm::get_addr(strchr(str.get_ptr(), ch)));
|
||||
for (u32 i = 0;; i++)
|
||||
{
|
||||
const char ch1 = str[i];
|
||||
if (ch1 == ch)
|
||||
return str + i;
|
||||
if (ch1 == '\0')
|
||||
return vm::null;
|
||||
}
|
||||
}
|
||||
|
||||
vm::ptr<char> _sys_strncat(vm::ptr<char> dest, vm::cptr<char> source, u32 len)
|
||||
vm::ptr<char> _sys_strncat(vm::ptr<char> dst, vm::cptr<char> src, u32 max)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strncat(dest=*0x%x, source=%s, len=%d)", dest, source, len);
|
||||
sysPrxForUser.trace("_sys_strncat(dst=*0x%x %s, src=%s, max=%u)", dst, dst, src, max);
|
||||
|
||||
verify(HERE), std::strncat(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr();
|
||||
auto str = dst;
|
||||
|
||||
return dest;
|
||||
while (*str)
|
||||
{
|
||||
str++;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < max; i++)
|
||||
{
|
||||
if (!(str[i] = src[i]))
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
str[max] = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
vm::ptr<char> _sys_strcpy(vm::ptr<char> dest, vm::cptr<char> source)
|
||||
vm::ptr<char> _sys_strcpy(vm::ptr<char> dst, vm::cptr<char> src)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strcpy(dest=*0x%x, source=%s)", dest, source);
|
||||
sysPrxForUser.trace("_sys_strcpy(dst=*0x%x, src=%s)", dst, src);
|
||||
|
||||
verify(HERE), std::strcpy(dest.get_ptr(), source.get_ptr()) == dest.get_ptr();
|
||||
|
||||
return dest;
|
||||
for (u32 i = 0;; i++)
|
||||
{
|
||||
if (!(dst[i] = src[i]))
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm::ptr<char> _sys_strncpy(vm::ptr<char> dest, vm::cptr<char> source, u32 len)
|
||||
vm::ptr<char> _sys_strncpy(vm::ptr<char> dst, vm::cptr<char> src, s32 len)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strncpy(dest=*0x%x, source=%s, len=%d)", dest, source, len);
|
||||
sysPrxForUser.trace("_sys_strncpy(dst=*0x%x %s, src=%s, len=%d)", dst, dst, src, len);
|
||||
|
||||
if (!dest || !source)
|
||||
if (!dst || !src)
|
||||
{
|
||||
return vm::null;
|
||||
}
|
||||
|
||||
verify(HERE), std::strncpy(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr();
|
||||
for (s32 i = 0; i < len; i++)
|
||||
{
|
||||
if (!(dst[i] = src[i]))
|
||||
{
|
||||
for (++i; i < len; i++)
|
||||
{
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
return dest;
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 n)
|
||||
s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, u32 n)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strncasecmp(str1=%s, str2=%s, n=%d)", str1, str2, n);
|
||||
|
||||
for (u32 i = 0; i < n; i++)
|
||||
{
|
||||
const int ch1 = tolower(str1[i]), ch2 = tolower(str2[i]);
|
||||
const int ch1 = _sys_tolower(str1[i]), ch2 = _sys_tolower(str2[i]);
|
||||
if (ch1 < ch2)
|
||||
return -1;
|
||||
if (ch1 > ch2)
|
||||
@@ -215,21 +353,22 @@ s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
vm::ptr<char> _sys_strrchr(vm::cptr<char> str, s32 character)
|
||||
vm::cptr<char> _sys_strrchr(vm::cptr<char> str, char ch)
|
||||
{
|
||||
sysPrxForUser.trace("_sys_strrchr(str=%s, character=%c)", str, (char)character);
|
||||
sysPrxForUser.trace("_sys_strrchr(str=%s, ch=%d)", str, ch);
|
||||
|
||||
return vm::ptr<char>::make(vm::get_addr(strrchr(str.get_ptr(), character)));
|
||||
}
|
||||
vm::cptr<char> res = vm::null;
|
||||
|
||||
s32 _sys_tolower()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
for (u32 i = 0;; i++)
|
||||
{
|
||||
const char ch1 = str[i];
|
||||
if (ch1 == ch)
|
||||
res = str + i;
|
||||
if (ch1 == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
s32 _sys_toupper()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 _sys_malloc(u32 size)
|
||||
@@ -320,6 +459,10 @@ s32 _sys_qsort()
|
||||
|
||||
void sysPrxForUser_sys_libc_init()
|
||||
{
|
||||
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);
|
||||
REG_FUNC(sysPrxForUser, _sys_tolower);
|
||||
REG_FUNC(sysPrxForUser, _sys_toupper);
|
||||
|
||||
REG_FUNC(sysPrxForUser, _sys_memset);
|
||||
REG_FUNC(sysPrxForUser, _sys_memcpy);
|
||||
REG_FUNC(sysPrxForUser, _sys_memcmp);
|
||||
@@ -336,8 +479,6 @@ void sysPrxForUser_sys_libc_init()
|
||||
REG_FUNC(sysPrxForUser, _sys_strncpy);
|
||||
REG_FUNC(sysPrxForUser, _sys_strncasecmp);
|
||||
REG_FUNC(sysPrxForUser, _sys_strrchr);
|
||||
REG_FUNC(sysPrxForUser, _sys_tolower);
|
||||
REG_FUNC(sysPrxForUser, _sys_toupper);
|
||||
|
||||
REG_FUNC(sysPrxForUser, _sys_malloc);
|
||||
REG_FUNC(sysPrxForUser, _sys_memalign);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,245 +0,0 @@
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/select.h>
|
||||
#undef fds_bits
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
namespace sys_net
|
||||
{
|
||||
|
||||
// It turns out SOL_SOCKET is equal to 1 on Linux, but 0xffff on Windows, and it appears the PS3 uses 0xffff, like Windows
|
||||
#define PS3_SOL_SOCKET 0xffff
|
||||
// Error codes
|
||||
enum
|
||||
{
|
||||
SYS_NET_ENOENT = 2,
|
||||
SYS_NET_EINTR = 4,
|
||||
SYS_NET_EBADF = 9,
|
||||
SYS_NET_ENOMEM = 12,
|
||||
SYS_NET_EACCES = 13,
|
||||
SYS_NET_EFAULT = 14,
|
||||
SYS_NET_EBUSY = 16,
|
||||
SYS_NET_EINVAL = 22,
|
||||
SYS_NET_EMFILE = 24,
|
||||
SYS_NET_ENOSPC = 28,
|
||||
SYS_NET_EPIPE = 32,
|
||||
SYS_NET_EAGAIN = 35,
|
||||
SYS_NET_EWOULDBLOCK = SYS_NET_EAGAIN,
|
||||
SYS_NET_EINPROGRESS = 36,
|
||||
SYS_NET_EALREADY = 37,
|
||||
SYS_NET_EDESTADDRREQ = 39,
|
||||
SYS_NET_EMSGSIZE = 40,
|
||||
SYS_NET_EPROTOTYPE = 41,
|
||||
SYS_NET_ENOPROTOOPT = 42,
|
||||
SYS_NET_EPROTONOSUPPORT = 43,
|
||||
SYS_NET_EOPNOTSUPP = 45,
|
||||
SYS_NET_EPFNOSUPPORT = 46,
|
||||
SYS_NET_EAFNOSUPPORT = 47,
|
||||
SYS_NET_EADDRINUSE = 48,
|
||||
SYS_NET_EADDRNOTAVAIL = 49,
|
||||
SYS_NET_ENETDOWN = 50,
|
||||
SYS_NET_ENETUNREACH = 51,
|
||||
SYS_NET_ECONNABORTED = 53,
|
||||
SYS_NET_ECONNRESET = 54,
|
||||
SYS_NET_ENOBUFS = 55,
|
||||
SYS_NET_EISCONN = 56,
|
||||
SYS_NET_ENOTCONN = 57,
|
||||
SYS_NET_ESHUTDOWN = 58,
|
||||
SYS_NET_ETOOMANYREFS = 59,
|
||||
SYS_NET_ETIMEDOUT = 60,
|
||||
SYS_NET_ECONNREFUSED = 61,
|
||||
SYS_NET_EHOSTDOWN = 64,
|
||||
SYS_NET_EHOSTUNREACH = 65,
|
||||
};
|
||||
|
||||
// Socket types
|
||||
enum
|
||||
{
|
||||
SOCK_STREAM = 1,
|
||||
SOCK_DGRAM = 2,
|
||||
SOCK_RAW = 3,
|
||||
SOCK_DGRAM_P2P = 6,
|
||||
SOCK_STREAM_P2P = 10,
|
||||
};
|
||||
|
||||
// Socket options
|
||||
// Note: All options are prefixed with "OP_" to prevent name conflicts.
|
||||
enum
|
||||
{
|
||||
OP_SO_SNDBUF = 0x1001,
|
||||
OP_SO_RCVBUF = 0x1002,
|
||||
OP_SO_SNDLOWAT = 0x1003,
|
||||
OP_SO_RCVLOWAT = 0x1004,
|
||||
OP_SO_SNDTIMEO = 0x1005,
|
||||
OP_SO_RCVTIMEO = 0x1006,
|
||||
OP_SO_ERROR = 0x1007,
|
||||
OP_SO_TYPE = 0x1008,
|
||||
OP_SO_NBIO = 0x1100, // Non-blocking IO
|
||||
OP_SO_TPPOLICY = 0x1101,
|
||||
|
||||
OP_SO_REUSEADDR = 0x0004,
|
||||
OP_SO_KEEPALIVE = 0x0008,
|
||||
OP_SO_BROADCAST = 0x0020,
|
||||
OP_SO_LINGER = 0x0080,
|
||||
OP_SO_OOBINLINE = 0x0100,
|
||||
OP_SO_REUSEPORT = 0x0200,
|
||||
OP_SO_ONESBCAST = 0x0800,
|
||||
OP_SO_USECRYPTO = 0x1000,
|
||||
OP_SO_USESIGNATURE = 0x2000,
|
||||
};
|
||||
|
||||
// TCP options
|
||||
enum
|
||||
{
|
||||
OP_TCP_NODELAY = 1,
|
||||
OP_TCP_MAXSEG = 2,
|
||||
OP_TCP_MSS_TO_ADVERTISE = 3,
|
||||
};
|
||||
|
||||
// IP protocols
|
||||
// Note: Proctols are prefixed with "PROTO_" to prevent name conflicts
|
||||
enum
|
||||
{
|
||||
PROTO_IPPROTO_IP = 0,
|
||||
PROTO_IPPROTO_ICMP = 1,
|
||||
PROTO_IPPROTO_IGMP = 2,
|
||||
PROTO_IPPROTO_TCP = 6,
|
||||
PROTO_IPPROTO_UDP = 17,
|
||||
PROTO_IPPROTO_ICMPV6 = 58,
|
||||
};
|
||||
|
||||
// only for reference, no need to use it
|
||||
using in_addr_t = u32;
|
||||
using in_port_t = u16;
|
||||
using sa_family_t = u8;
|
||||
using socklen_t = u32;
|
||||
|
||||
struct fd_set
|
||||
{
|
||||
be_t<u32> fds_bits[32];
|
||||
};
|
||||
|
||||
struct hostent
|
||||
{
|
||||
vm::bptr<char> h_name;
|
||||
vm::bpptr<char> h_aliases;
|
||||
be_t<s32> h_addrtype;
|
||||
be_t<s32> h_length;
|
||||
vm::bpptr<char> h_addr_list;
|
||||
};
|
||||
|
||||
struct in_addr
|
||||
{
|
||||
be_t<u32> s_addr;
|
||||
};
|
||||
|
||||
struct iovec
|
||||
{
|
||||
be_t<s32> zero1;
|
||||
vm::bptr<void> iov_base;
|
||||
be_t<s32> zero2;
|
||||
be_t<u32> iov_len;
|
||||
};
|
||||
|
||||
struct ip_mreq
|
||||
{
|
||||
be_t<u32> imr_multiaddr;
|
||||
be_t<u32> imr_interface;
|
||||
};
|
||||
|
||||
struct msghdr
|
||||
{
|
||||
be_t<s32> zero1;
|
||||
vm::bptr<void> msg_name;
|
||||
be_t<u32> msg_namelen;
|
||||
be_t<s32> pad1;
|
||||
be_t<s32> zero2;
|
||||
vm::bptr<iovec> msg_iov;
|
||||
be_t<s32> msg_iovlen;
|
||||
be_t<s32> pad2;
|
||||
be_t<s32> zero3;
|
||||
vm::bptr<void> msg_control;
|
||||
be_t<u32> msg_controllen;
|
||||
be_t<s32> msg_flags;
|
||||
};
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
be_t<s32> fd;
|
||||
be_t<s16> events;
|
||||
be_t<s16> revents;
|
||||
};
|
||||
|
||||
struct sockaddr
|
||||
{
|
||||
u8 sa_len;
|
||||
u8 sa_family;
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
struct sockaddr_dl
|
||||
{
|
||||
u8 sdl_len;
|
||||
u8 sdl_family;
|
||||
be_t<u16> sdl_index;
|
||||
u8 sdl_type;
|
||||
u8 sdl_nlen;
|
||||
u8 sdl_alen;
|
||||
u8 sdl_slen;
|
||||
char sdl_data[12];
|
||||
};
|
||||
|
||||
struct sockaddr_in
|
||||
{
|
||||
u8 sin_len;
|
||||
u8 sin_family;
|
||||
be_t<u16> sin_port;
|
||||
be_t<u32> sin_addr;
|
||||
char sin_zero[8];
|
||||
};
|
||||
|
||||
struct sockaddr_in_p2p
|
||||
{
|
||||
u8 sin_len;
|
||||
u8 sin_family;
|
||||
be_t<u16> sin_port;
|
||||
be_t<u32> sin_addr;
|
||||
be_t<u16> sin_vport;
|
||||
char sin_zero[6];
|
||||
};
|
||||
|
||||
struct timeval
|
||||
{
|
||||
be_t<s64> tv_sec;
|
||||
be_t<s64> tv_usec;
|
||||
};
|
||||
|
||||
struct sys_net_sockinfo_t
|
||||
{
|
||||
be_t<s32> s;
|
||||
be_t<s32> proto;
|
||||
be_t<s32> recv_queue_length;
|
||||
be_t<s32> send_queue_length;
|
||||
in_addr local_adr;
|
||||
be_t<s32> local_port;
|
||||
in_addr remote_adr;
|
||||
be_t<s32> remote_port;
|
||||
be_t<s32> state;
|
||||
};
|
||||
}
|
||||
|
||||
struct sys_net_initialize_parameter_t
|
||||
{
|
||||
vm::bptr<void> memory;
|
||||
be_t<s32> memory_size;
|
||||
be_t<s32> flags;
|
||||
};
|
||||
|
||||
// PS3 libnet socket struct
|
||||
struct net_socket_t
|
||||
{
|
||||
std::intptr_t native_handle;
|
||||
};
|
||||
@@ -0,0 +1,737 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/IdManager.h"
|
||||
|
||||
#include "sys_net_.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
logs::channel libnet("libnet");
|
||||
|
||||
struct sys_net_tls_data
|
||||
{
|
||||
be_t<s32> _errno;
|
||||
be_t<s32> _h_errno;
|
||||
char addr[16];
|
||||
};
|
||||
|
||||
// TODO
|
||||
thread_local vm::ptr<sys_net_tls_data> g_tls_net_data{};
|
||||
|
||||
static NEVER_INLINE vm::ptr<sys_net_tls_data> get_tls()
|
||||
{
|
||||
// Allocate if not initialized
|
||||
if (!g_tls_net_data)
|
||||
{
|
||||
g_tls_net_data.set(vm::alloc(sizeof(decltype(g_tls_net_data)::type), vm::main));
|
||||
|
||||
// Initial values
|
||||
g_tls_net_data->_errno = SYS_NET_EBUSY;
|
||||
|
||||
thread_ctrl::atexit([addr = g_tls_net_data.addr()]
|
||||
{
|
||||
vm::dealloc_verbose_nothrow(addr, vm::main);
|
||||
});
|
||||
}
|
||||
|
||||
return g_tls_net_data;
|
||||
}
|
||||
|
||||
s32 sys_net_accept(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
||||
{
|
||||
libnet.todo("accept(s=%d, addr=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_bind(s32 s, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
|
||||
{
|
||||
libnet.todo("bind(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_connect(s32 s, vm::ptr<sys_net_sockaddr> addr, u32 addrlen)
|
||||
{
|
||||
libnet.todo("connect(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_gethostbyaddr()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_gethostbyname()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_getpeername(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_getsockname(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_getsockopt(s32 s, s32 level, s32 optname, vm::ptr<void> optval, vm::ptr<u32> optlen)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
u32 sys_net_inet_addr(vm::cptr<char> cp)
|
||||
{
|
||||
libnet.todo("inet_addr(cp=%s)", cp);
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
s32 sys_net_inet_aton()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_inet_lnaof()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_inet_makeaddr()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_inet_netof()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_inet_network()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
vm::ptr<char> sys_net_inet_ntoa(u32 in)
|
||||
{
|
||||
libnet.todo("inet_ntoa(in=0x%x)", in);
|
||||
|
||||
return vm::null;
|
||||
}
|
||||
|
||||
vm::cptr<char> sys_net_inet_ntop(s32 af, vm::ptr<void> src, vm::ptr<char> dst, u32 size)
|
||||
{
|
||||
libnet.todo("inet_ntop(af=%d, src=%s, dst=*0x%x, size=%d)", af, src, dst, size);
|
||||
|
||||
return vm::null;
|
||||
}
|
||||
|
||||
s32 sys_net_inet_pton(s32 af, vm::cptr<char> src, vm::ptr<char> dst)
|
||||
{
|
||||
libnet.todo("inet_pton(af=%d, src=%s, dst=*0x%x)", af, src, dst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_listen(s32 s, s32 backlog)
|
||||
{
|
||||
libnet.todo("listen(s=%d, backlog=%d)", s, backlog);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_recv(s32 s, vm::ptr<void> buf, u32 len, s32 flags)
|
||||
{
|
||||
libnet.todo("recv(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_recvfrom(s32 s, vm::ptr<void> buf, u32 len, s32 flags, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
||||
{
|
||||
libnet.todo("recvfrom(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, paddrlen=*0x%x)", s, buf, len, flags, addr, paddrlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_recvmsg(s32 s, vm::ptr<sys_net_msghdr> msg, s32 flags)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_send(s32 s, vm::cptr<void> buf, u32 len, s32 flags)
|
||||
{
|
||||
libnet.todo("send(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_sendmsg(s32 s, vm::cptr<sys_net_msghdr> msg, s32 flags)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_sendto(s32 s, vm::cptr<void> buf, u32 len, s32 flags, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
|
||||
{
|
||||
libnet.todo("sendto(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, addrlen=%d)", s, buf, len, flags, addr, addrlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_setsockopt(s32 s, s32 level, s32 optname, vm::cptr<void> optval, u32 optlen)
|
||||
{
|
||||
libnet.todo("setsockopt(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_shutdown(s32 s, s32 how)
|
||||
{
|
||||
libnet.todo("shutdown(s=%d, how=%d)", s, how);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_socket(s32 family, s32 type, s32 protocol)
|
||||
{
|
||||
libnet.todo("socket(family=%d, type=%d, protocol=%d)", family, type, protocol);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_socketclose(s32 s)
|
||||
{
|
||||
libnet.warning("socketclose(s=%d)", s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_socketpoll(vm::ptr<sys_net_pollfd> fds, s32 nfds, s32 ms)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_socketselect(s32 nfds, vm::ptr<sys_net_fd_set> readfds, vm::ptr<sys_net_fd_set> writefds, vm::ptr<sys_net_fd_set> exceptfds, vm::ptr<sys_net_timeval> timeout)
|
||||
{
|
||||
libnet.todo("socketselect(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout=*0x%x)", nfds, readfds, writefds, exceptfds, timeout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 sys_net_initialize_network_ex(vm::ptr<sys_net_initialize_parameter_t> param)
|
||||
{
|
||||
libnet.todo("sys_net_initialize_network_ex(param=*0x%x)", param);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_udpp2p_test_param()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_set_udpp2p_test_param()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_lib_name_server()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_if_ctl()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_if_list()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_name_server()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_netemu_test_param()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_routing_table_af()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_sockinfo(s32 s, vm::ptr<sys_net_sockinfo_t> p, s32 n)
|
||||
{
|
||||
libnet.todo("sys_net_get_sockinfo(s=%d, p=*0x%x, n=%d)", s, p, n);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_close_dump(s32 id, vm::ptr<s32> pflags)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_set_test_param()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_show_nameserver()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
vm::ptr<s32> _sys_net_errno_loc()
|
||||
{
|
||||
libnet.warning("_sys_net_errno_loc()");
|
||||
|
||||
return get_tls().ptr(&sys_net_tls_data::_errno);
|
||||
}
|
||||
|
||||
s32 sys_net_set_resolver_configurations()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_show_route()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_read_dump(s32 id, vm::ptr<void> buf, s32 len, vm::ptr<s32> pflags)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_abort_resolver()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_abort_socket()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_set_lib_name_server()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_test_param()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_get_sockinfo_ex()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_open_dump(s32 len, s32 flags)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_show_ifconfig()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_finalize_network()
|
||||
{
|
||||
libnet.todo("sys_net_finalize_network()");
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
vm::ptr<s32> _sys_net_h_errno_loc()
|
||||
{
|
||||
libnet.warning("_sys_net_h_errno_loc()");
|
||||
|
||||
return get_tls().ptr(&sys_net_tls_data::_h_errno);
|
||||
}
|
||||
|
||||
s32 sys_net_set_netemu_test_param()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_net_free_thread_context(u64 tid, s32 flags)
|
||||
{
|
||||
libnet.todo("sys_net_free_thread_context(tid=0x%x, flags=%d)", tid, flags);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_abort()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_bnet_control()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 __sys_net_lib_calloc()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_free()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_get_system_time()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_if_nametoindex()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_ioctl()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 __sys_net_lib_malloc()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_rand()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 __sys_net_lib_realloc()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_reset_libnetctl_queue()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_set_libnetctl_queue()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_thread_create()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_thread_exit()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_thread_join()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_sync_clear()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_sync_create()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_sync_destroy()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_sync_signal()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_sync_wait()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_sysctl()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_net_lib_usleep()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_netset_abort()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_netset_close()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_netset_get_if_id()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_netset_get_status()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_netset_if_down()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_netset_get_key_value()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
s32 sys_netset_if_up()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_netset_open()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sce_net_get_name_server()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sce_net_add_name_server()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sce_net_add_name_server_with_char()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sce_net_flush_route()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sce_net_set_default_gateway()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sce_net_set_ip_and_mask()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sce_net_set_name_server()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(libnet);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::sys_net)("sys_net", []()
|
||||
{
|
||||
REG_FNID(sys_net, "accept", sys_net_accept);
|
||||
REG_FNID(sys_net, "bind", sys_net_bind);
|
||||
REG_FNID(sys_net, "connect", sys_net_connect);
|
||||
REG_FNID(sys_net, "gethostbyaddr", sys_net_gethostbyaddr);
|
||||
REG_FNID(sys_net, "gethostbyname", sys_net_gethostbyname);
|
||||
REG_FNID(sys_net, "getpeername", sys_net_getpeername);
|
||||
REG_FNID(sys_net, "getsockname", sys_net_getsockname);
|
||||
REG_FNID(sys_net, "getsockopt", sys_net_getsockopt);
|
||||
REG_FNID(sys_net, "inet_addr", sys_net_inet_addr);
|
||||
REG_FNID(sys_net, "inet_aton", sys_net_inet_aton);
|
||||
REG_FNID(sys_net, "inet_lnaof", sys_net_inet_lnaof);
|
||||
REG_FNID(sys_net, "inet_makeaddr", sys_net_inet_makeaddr);
|
||||
REG_FNID(sys_net, "inet_netof", sys_net_inet_netof);
|
||||
REG_FNID(sys_net, "inet_network", sys_net_inet_network);
|
||||
REG_FNID(sys_net, "inet_ntoa", sys_net_inet_ntoa);
|
||||
REG_FNID(sys_net, "inet_ntop", sys_net_inet_ntop);
|
||||
REG_FNID(sys_net, "inet_pton", sys_net_inet_pton);
|
||||
REG_FNID(sys_net, "listen", sys_net_listen);
|
||||
REG_FNID(sys_net, "recv", sys_net_recv);
|
||||
REG_FNID(sys_net, "recvfrom", sys_net_recvfrom);
|
||||
REG_FNID(sys_net, "recvmsg", sys_net_recvmsg);
|
||||
REG_FNID(sys_net, "send", sys_net_send);
|
||||
REG_FNID(sys_net, "sendmsg", sys_net_sendmsg);
|
||||
REG_FNID(sys_net, "sendto", sys_net_sendto);
|
||||
REG_FNID(sys_net, "setsockopt", sys_net_setsockopt);
|
||||
REG_FNID(sys_net, "shutdown", sys_net_shutdown);
|
||||
REG_FNID(sys_net, "socket", sys_net_socket);
|
||||
REG_FNID(sys_net, "socketclose", sys_net_socketclose);
|
||||
REG_FNID(sys_net, "socketpoll", sys_net_socketpoll);
|
||||
REG_FNID(sys_net, "socketselect", sys_net_socketselect);
|
||||
|
||||
REG_FUNC(sys_net, sys_net_initialize_network_ex);
|
||||
REG_FUNC(sys_net, sys_net_get_udpp2p_test_param);
|
||||
REG_FUNC(sys_net, sys_net_set_udpp2p_test_param);
|
||||
REG_FUNC(sys_net, sys_net_get_lib_name_server);
|
||||
REG_FUNC(sys_net, sys_net_if_ctl);
|
||||
REG_FUNC(sys_net, sys_net_get_if_list);
|
||||
REG_FUNC(sys_net, sys_net_get_name_server);
|
||||
REG_FUNC(sys_net, sys_net_get_netemu_test_param);
|
||||
REG_FUNC(sys_net, sys_net_get_routing_table_af);
|
||||
REG_FUNC(sys_net, sys_net_get_sockinfo);
|
||||
REG_FUNC(sys_net, sys_net_close_dump);
|
||||
REG_FUNC(sys_net, sys_net_set_test_param);
|
||||
REG_FUNC(sys_net, sys_net_show_nameserver);
|
||||
REG_FUNC(sys_net, _sys_net_errno_loc);
|
||||
REG_FUNC(sys_net, sys_net_set_resolver_configurations);
|
||||
REG_FUNC(sys_net, sys_net_show_route);
|
||||
REG_FUNC(sys_net, sys_net_read_dump);
|
||||
REG_FUNC(sys_net, sys_net_abort_resolver);
|
||||
REG_FUNC(sys_net, sys_net_abort_socket);
|
||||
REG_FUNC(sys_net, sys_net_set_lib_name_server);
|
||||
REG_FUNC(sys_net, sys_net_get_test_param);
|
||||
REG_FUNC(sys_net, sys_net_get_sockinfo_ex);
|
||||
REG_FUNC(sys_net, sys_net_open_dump);
|
||||
REG_FUNC(sys_net, sys_net_show_ifconfig);
|
||||
REG_FUNC(sys_net, sys_net_finalize_network);
|
||||
REG_FUNC(sys_net, _sys_net_h_errno_loc);
|
||||
REG_FUNC(sys_net, sys_net_set_netemu_test_param);
|
||||
REG_FUNC(sys_net, sys_net_free_thread_context);
|
||||
|
||||
REG_FUNC(sys_net, _sys_net_lib_abort);
|
||||
REG_FUNC(sys_net, _sys_net_lib_bnet_control);
|
||||
REG_FUNC(sys_net, __sys_net_lib_calloc);
|
||||
REG_FUNC(sys_net, _sys_net_lib_free);
|
||||
REG_FUNC(sys_net, _sys_net_lib_get_system_time);
|
||||
REG_FUNC(sys_net, _sys_net_lib_if_nametoindex);
|
||||
REG_FUNC(sys_net, _sys_net_lib_ioctl);
|
||||
REG_FUNC(sys_net, __sys_net_lib_malloc);
|
||||
REG_FUNC(sys_net, _sys_net_lib_rand);
|
||||
REG_FUNC(sys_net, __sys_net_lib_realloc);
|
||||
REG_FUNC(sys_net, _sys_net_lib_reset_libnetctl_queue);
|
||||
REG_FUNC(sys_net, _sys_net_lib_set_libnetctl_queue);
|
||||
|
||||
REG_FUNC(sys_net, _sys_net_lib_thread_create);
|
||||
REG_FUNC(sys_net, _sys_net_lib_thread_exit);
|
||||
REG_FUNC(sys_net, _sys_net_lib_thread_join);
|
||||
|
||||
REG_FUNC(sys_net, _sys_net_lib_sync_clear);
|
||||
REG_FUNC(sys_net, _sys_net_lib_sync_create);
|
||||
REG_FUNC(sys_net, _sys_net_lib_sync_destroy);
|
||||
REG_FUNC(sys_net, _sys_net_lib_sync_signal);
|
||||
REG_FUNC(sys_net, _sys_net_lib_sync_wait);
|
||||
|
||||
REG_FUNC(sys_net, _sys_net_lib_sysctl);
|
||||
REG_FUNC(sys_net, _sys_net_lib_usleep);
|
||||
|
||||
REG_FUNC(sys_net, sys_netset_abort);
|
||||
REG_FUNC(sys_net, sys_netset_close);
|
||||
REG_FUNC(sys_net, sys_netset_get_if_id);
|
||||
REG_FUNC(sys_net, sys_netset_get_key_value);
|
||||
REG_FUNC(sys_net, sys_netset_get_status);
|
||||
REG_FUNC(sys_net, sys_netset_if_down);
|
||||
REG_FUNC(sys_net, sys_netset_if_up);
|
||||
REG_FUNC(sys_net, sys_netset_open);
|
||||
|
||||
REG_FUNC(sys_net, _sce_net_add_name_server);
|
||||
REG_FUNC(sys_net, _sce_net_add_name_server_with_char);
|
||||
REG_FUNC(sys_net, _sce_net_flush_route);
|
||||
|
||||
REG_FUNC(sys_net, _sce_net_get_name_server);
|
||||
REG_FUNC(sys_net, _sce_net_set_default_gateway);
|
||||
REG_FUNC(sys_net, _sce_net_set_ip_and_mask);
|
||||
REG_FUNC(sys_net, _sce_net_set_name_server);
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "Emu/Cell/lv2/sys_net.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
|
||||
struct sys_net_sockinfo_t
|
||||
{
|
||||
be_t<s32> s;
|
||||
be_t<s32> proto;
|
||||
be_t<s32> recv_queue_length;
|
||||
be_t<s32> send_queue_length;
|
||||
sys_net_in_addr local_adr;
|
||||
be_t<s32> local_port;
|
||||
sys_net_in_addr remote_adr;
|
||||
be_t<s32> remote_port;
|
||||
be_t<s32> state;
|
||||
};
|
||||
|
||||
struct sys_net_sockinfo_ex_t
|
||||
{
|
||||
be_t<s32> s;
|
||||
be_t<s32> proto;
|
||||
be_t<s32> recv_queue_length;
|
||||
be_t<s32> send_queue_length;
|
||||
sys_net_in_addr local_adr;
|
||||
be_t<s32> local_port;
|
||||
sys_net_in_addr remote_adr;
|
||||
be_t<s32> remote_port;
|
||||
be_t<s32> state;
|
||||
be_t<s32> socket_type;
|
||||
be_t<s32> local_vport;
|
||||
be_t<s32> remote_vport;
|
||||
be_t<s32> reserved[8];
|
||||
};
|
||||
|
||||
struct sys_net_initialize_parameter_t
|
||||
{
|
||||
vm::ps3::bptr<void> memory;
|
||||
be_t<s32> memory_size;
|
||||
be_t<s32> flags;
|
||||
};
|
||||
@@ -13,6 +13,7 @@ extern logs::channel sysPrxForUser;
|
||||
|
||||
vm::gvar<sys_lwmutex_t> g_ppu_atexit_lwm;
|
||||
vm::gvar<vm::ptr<void()>[8]> g_ppu_atexit;
|
||||
vm::gvar<u32> g_ppu_exit_mutex; // sys_process_exit2 mutex
|
||||
vm::gvar<u32> g_ppu_once_mutex;
|
||||
vm::gvar<sys_lwmutex_t> g_ppu_prx_lwm;
|
||||
|
||||
@@ -112,6 +113,10 @@ void sys_initialize_tls(ppu_thread& ppu, u64 main_thread_id, u32 tls_seg_addr, u
|
||||
attr->name_u64 = "_lv2ppu\0"_u64;
|
||||
sys_mutex_create(g_ppu_once_mutex, attr);
|
||||
|
||||
attr->recursive = SYS_SYNC_RECURSIVE;
|
||||
attr->name_u64 = "_lv2tls\0"_u64;
|
||||
sys_mutex_create(g_ppu_exit_mutex, attr);
|
||||
|
||||
lwa->protocol = SYS_SYNC_PRIORITY;
|
||||
lwa->recursive = SYS_SYNC_RECURSIVE;
|
||||
lwa->name_u64 = "_lv2prx\0"_u64;
|
||||
@@ -266,12 +271,13 @@ error_code sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih)
|
||||
void sysPrxForUser_sys_ppu_thread_init()
|
||||
{
|
||||
// Private
|
||||
REG_VNID(sysPrxForUser, 0x00000000u, g_ppu_atexit_lwm);
|
||||
REG_VNID(sysPrxForUser, 0x00000001u, g_ppu_once_mutex);
|
||||
REG_VNID(sysPrxForUser, 0x00000002u, g_ppu_atexit);
|
||||
REG_VNID(sysPrxForUser, 0x00000003u, g_ppu_prx_lwm);
|
||||
REG_VAR(sysPrxForUser, g_ppu_atexit_lwm).flag(MFF_HIDDEN);
|
||||
REG_VAR(sysPrxForUser, g_ppu_once_mutex).flag(MFF_HIDDEN);
|
||||
REG_VAR(sysPrxForUser, g_ppu_atexit).flag(MFF_HIDDEN);
|
||||
REG_VAR(sysPrxForUser, g_ppu_prx_lwm).flag(MFF_HIDDEN);
|
||||
REG_VAR(sysPrxForUser, g_ppu_exit_mutex).flag(MFF_HIDDEN);
|
||||
|
||||
REG_FUNC(sysPrxForUser, sys_initialize_tls);
|
||||
REG_FUNC(sysPrxForUser, sys_initialize_tls).args = {"main_thread_id", "tls_seg_addr", "tls_seg_size", "tls_mem_size"}; // Test
|
||||
REG_FUNC(sysPrxForUser, sys_ppu_thread_create);
|
||||
REG_FUNC(sysPrxForUser, sys_ppu_thread_get_id);
|
||||
REG_FUNC(sysPrxForUser, sys_ppu_thread_exit);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "Utilities/bit_set.h"
|
||||
#include "Utilities/BEType.h"
|
||||
#include "PPUOpcodes.h"
|
||||
|
||||
// PPU Function Attributes
|
||||
enum class ppu_attr : u32
|
||||
@@ -50,6 +51,7 @@ struct ppu_segment
|
||||
u32 size;
|
||||
u32 type;
|
||||
u32 flags;
|
||||
u32 filesz;
|
||||
};
|
||||
|
||||
// PPU Module Information
|
||||
@@ -62,6 +64,16 @@ struct ppu_module
|
||||
std::vector<ppu_segment> secs;
|
||||
std::vector<ppu_function> funcs;
|
||||
|
||||
// Copy info without functions
|
||||
void copy_part(const ppu_module& info)
|
||||
{
|
||||
name = info.name;
|
||||
path = info.path;
|
||||
relocs = info.relocs;
|
||||
segs = info.segs;
|
||||
secs = info.secs;
|
||||
}
|
||||
|
||||
void analyse(u32 lib_toc, u32 entry);
|
||||
void validate(u32 reloc);
|
||||
};
|
||||
@@ -930,3 +942,738 @@ struct ppu_iname
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
// PPU Analyser Context
|
||||
struct ppu_acontext
|
||||
{
|
||||
// General-purpose register range
|
||||
struct spec_gpr
|
||||
{
|
||||
// Integral range: normalized undef = (0;UINT64_MAX), unnormalized undefs are possible (when max = min - 1)
|
||||
// Bit range: constant 0 = (0;0), constant 1 = (1;1), normalized undef = (0;1), unnormalized undef = (1;0)
|
||||
|
||||
u64 imin = 0; // Integral range begin
|
||||
u64 imax = -1; // Integral range end
|
||||
u64 bmin = 0; // Bit range begin
|
||||
u64 bmax = -1; // Bit range end
|
||||
|
||||
void set_undef()
|
||||
{
|
||||
imin = 0;
|
||||
imax = -1;
|
||||
bmin = 0;
|
||||
bmax = -1;
|
||||
}
|
||||
|
||||
// (Number of possible values - 1), 0 = const
|
||||
u64 div() const
|
||||
{
|
||||
return imax - imin;
|
||||
}
|
||||
|
||||
// Return zero bits for zeros, ones for ones or undefs
|
||||
u64 mask() const
|
||||
{
|
||||
return bmin | bmax;
|
||||
}
|
||||
|
||||
// Return one bits for ones, zeros for zeros or undefs
|
||||
u64 ones() const
|
||||
{
|
||||
return bmin & bmax;
|
||||
}
|
||||
|
||||
// Return one bits for undefs
|
||||
u64 undefs() const
|
||||
{
|
||||
return bmin ^ bmax;
|
||||
}
|
||||
|
||||
// Return number of trailing zero bits
|
||||
u64 tz() const
|
||||
{
|
||||
return ::cnttz64(mask());
|
||||
}
|
||||
|
||||
// Range NOT
|
||||
spec_gpr operator ~() const
|
||||
{
|
||||
spec_gpr r;
|
||||
r.imin = ~imax;
|
||||
r.imax = ~imin;
|
||||
r.bmin = ~bmax;
|
||||
r.bmax = ~bmin;
|
||||
return r;
|
||||
}
|
||||
|
||||
// Range ADD
|
||||
spec_gpr operator +(const spec_gpr& rhs) const
|
||||
{
|
||||
spec_gpr r{};
|
||||
|
||||
const u64 adiv = div();
|
||||
const u64 bdiv = rhs.div();
|
||||
|
||||
// Check overflow, generate normalized range
|
||||
if (adiv != -1 && bdiv != -1 && adiv <= adiv + bdiv)
|
||||
{
|
||||
r = range(imin + rhs.imin, imax + rhs.imax);
|
||||
}
|
||||
|
||||
// Carry for bitrange computation
|
||||
u64 cmin = 0;
|
||||
u64 cmax = 0;
|
||||
|
||||
const u64 amask = mask();
|
||||
const u64 bmask = rhs.mask();
|
||||
const u64 aones = ones();
|
||||
const u64 bones = rhs.ones();
|
||||
|
||||
for (u32 i = 0; i < 64; i++)
|
||||
{
|
||||
cmin += ((amask >> i) & 1) + ((bmask >> i) & 1);
|
||||
cmax += ((aones >> i) & 1) + ((bones >> i) & 1);
|
||||
|
||||
// Discover some constant bits
|
||||
if (cmin == cmax)
|
||||
{
|
||||
r.bmin |= (cmin & 1) << i;
|
||||
r.bmax &= ~((~cmin & 1) << i);
|
||||
}
|
||||
|
||||
cmin >>= 1;
|
||||
cmax >>= 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Range AND
|
||||
spec_gpr operator &(const spec_gpr& rhs) const
|
||||
{
|
||||
// Ignore inverted ranges (TODO)
|
||||
if (imin > imax || rhs.imin > rhs.imax)
|
||||
{
|
||||
return approx(ones() & rhs.ones(), mask() & rhs.mask());
|
||||
}
|
||||
|
||||
// Const (TODO: remove when unnecessary)
|
||||
if (imin == imax && rhs.imin == rhs.imax)
|
||||
{
|
||||
return fixed(imin & rhs.imin);
|
||||
}
|
||||
|
||||
// Swap (TODO: remove when unnecessary)
|
||||
if (imin == imax || rhs.undefs() > undefs())
|
||||
{
|
||||
return rhs & *this;
|
||||
}
|
||||
|
||||
// Copy and attempt to partially preserve integral range
|
||||
spec_gpr r = *this;
|
||||
|
||||
for (u32 i = 63; ~i; i--)
|
||||
{
|
||||
const u64 m = 1ull << i;
|
||||
|
||||
if (!(rhs.mask() & m))
|
||||
{
|
||||
if (r.undefs() & m)
|
||||
{
|
||||
// undef -> 0
|
||||
r.imin &= ~(m - 1);
|
||||
r.imax |= (m - 1);
|
||||
r.imin &= ~m;
|
||||
r.imax &= ~m;
|
||||
}
|
||||
else if (r.ones() & m)
|
||||
{
|
||||
// 1 -> 0
|
||||
if ((r.imin ^ r.imax) > (m - 1))
|
||||
{
|
||||
r.imin &= ~(m - 1);
|
||||
r.imax |= (m - 1);
|
||||
}
|
||||
|
||||
r.imin &= ~m;
|
||||
r.imax &= ~m;
|
||||
}
|
||||
}
|
||||
else if (rhs.undefs() & m)
|
||||
{
|
||||
// -> undef
|
||||
r.imin &= ~(m - 1);
|
||||
r.imax |= (m - 1);
|
||||
r.imin &= ~m;
|
||||
r.imax |= m;
|
||||
}
|
||||
}
|
||||
|
||||
r.bmin = ones() & rhs.ones();
|
||||
r.bmax = mask() & rhs.mask();
|
||||
return r;
|
||||
}
|
||||
|
||||
// Range OR
|
||||
spec_gpr operator |(const spec_gpr& rhs) const
|
||||
{
|
||||
// Ignore inverted ranges (TODO)
|
||||
if (imin > imax || rhs.imin > rhs.imax)
|
||||
{
|
||||
return approx(ones() | rhs.ones(), mask() | rhs.mask());
|
||||
}
|
||||
|
||||
// Const (TODO: remove when unnecessary)
|
||||
if (imin == imax && rhs.imin == rhs.imax)
|
||||
{
|
||||
return fixed(imin | rhs.imin);
|
||||
}
|
||||
|
||||
// Swap (TODO: remove when unnecessary)
|
||||
if (imin == imax || rhs.undefs() > undefs())
|
||||
{
|
||||
return rhs | *this;
|
||||
}
|
||||
|
||||
// Copy and attempt to partially preserve integral range
|
||||
spec_gpr r = *this;
|
||||
|
||||
for (u32 i = 63; ~i; i--)
|
||||
{
|
||||
const u64 m = 1ull << i;
|
||||
|
||||
if (rhs.ones() & m)
|
||||
{
|
||||
if (r.undefs() & m)
|
||||
{
|
||||
// undef -> 1
|
||||
r.imin &= ~(m - 1);
|
||||
r.imax |= (m - 1);
|
||||
r.imin |= m;
|
||||
r.imax |= m;
|
||||
}
|
||||
else if (!(r.mask() & m))
|
||||
{
|
||||
// 0 -> 1
|
||||
if ((r.imin ^ r.imax) > (m - 1))
|
||||
{
|
||||
r.imin &= ~(m - 1);
|
||||
r.imax |= (m - 1);
|
||||
}
|
||||
|
||||
r.imin |= m;
|
||||
r.imax |= m;
|
||||
}
|
||||
}
|
||||
else if (rhs.undefs() & m)
|
||||
{
|
||||
// -> undef
|
||||
r.imin &= ~(m - 1);
|
||||
r.imax |= (m - 1);
|
||||
r.imin &= ~m;
|
||||
r.imax |= m;
|
||||
}
|
||||
}
|
||||
|
||||
r.bmin = ones() | rhs.ones();
|
||||
r.bmax = mask() | rhs.mask();
|
||||
return r;
|
||||
}
|
||||
|
||||
// Range XOR
|
||||
spec_gpr operator ^(const spec_gpr& rhs)
|
||||
{
|
||||
return (~*this & rhs) | (*this & ~rhs);
|
||||
}
|
||||
|
||||
// Check whether the value is in range
|
||||
bool test(u64 value) const
|
||||
{
|
||||
if (imin <= imax)
|
||||
{
|
||||
if (value < imin || value > imax)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value < imin && value > imax)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((value & mask()) != value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((value | ones()) != value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Constant value
|
||||
static spec_gpr fixed(u64 value)
|
||||
{
|
||||
spec_gpr r;
|
||||
r.imin = value;
|
||||
r.imax = value;
|
||||
r.bmin = value;
|
||||
r.bmax = value;
|
||||
return r;
|
||||
}
|
||||
|
||||
// Range (tz = number of constant trailing zeros)
|
||||
static spec_gpr range(u64 min, u64 max, u64 tz = 0)
|
||||
{
|
||||
const u64 mask = tz < 64 ? ~0ull << tz : 0ull;
|
||||
|
||||
spec_gpr r;
|
||||
r.bmin = 0;
|
||||
r.bmax = mask;
|
||||
|
||||
// Normalize min/max for tz (TODO)
|
||||
if (min < max)
|
||||
{
|
||||
// Inverted constant MSB mask
|
||||
const u64 mix = ~0ull >> ::cntlz64(min ^ max, true);
|
||||
r.bmin |= min & ~mix;
|
||||
r.bmax &= max | mix;
|
||||
|
||||
r.imin = (min + ~mask) & mask;
|
||||
r.imax = max & mask;
|
||||
verify("Impossible range" HERE), r.imin <= r.imax;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.imin = min & mask;
|
||||
r.imax = (max + ~mask) & mask;
|
||||
verify("Impossible range" HERE), r.imin >= r.imax;
|
||||
}
|
||||
|
||||
// Fix const values
|
||||
if (r.imin == r.imax)
|
||||
{
|
||||
r.bmin = r.imin;
|
||||
r.bmax = r.imax;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Make from bitrange (normalize, approximate range values)
|
||||
static spec_gpr approx(u64 bmin, u64 bmax)
|
||||
{
|
||||
spec_gpr r;
|
||||
r.imin = bmin & ~(bmin ^ bmax);
|
||||
r.imax = bmax | (bmin ^ bmax);
|
||||
r.bmin = bmin & ~(bmin ^ bmax);
|
||||
r.bmax = bmax | (bmin ^ bmax);
|
||||
return r;
|
||||
}
|
||||
} gpr[32]{};
|
||||
|
||||
// Vector registers (draft)
|
||||
struct spec_vec
|
||||
{
|
||||
u8 imin8[16]{};
|
||||
u8 imax8[16]{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
|
||||
u16 imin16[8]{};
|
||||
u16 imax16[8]{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
|
||||
u32 imin32[4]{};
|
||||
u32 imax32[4]{0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu};
|
||||
u64 bmin64[2]{};
|
||||
u64 bmax64[2]{0xffffffffffffffffull, 0xffffffffffffffffull};
|
||||
};
|
||||
|
||||
// Info
|
||||
u32 cia;
|
||||
|
||||
// Analyser step
|
||||
void UNK(ppu_opcode_t);
|
||||
|
||||
void MFVSCR(ppu_opcode_t);
|
||||
void MTVSCR(ppu_opcode_t);
|
||||
void VADDCUW(ppu_opcode_t);
|
||||
void VADDFP(ppu_opcode_t);
|
||||
void VADDSBS(ppu_opcode_t);
|
||||
void VADDSHS(ppu_opcode_t);
|
||||
void VADDSWS(ppu_opcode_t);
|
||||
void VADDUBM(ppu_opcode_t);
|
||||
void VADDUBS(ppu_opcode_t);
|
||||
void VADDUHM(ppu_opcode_t);
|
||||
void VADDUHS(ppu_opcode_t);
|
||||
void VADDUWM(ppu_opcode_t);
|
||||
void VADDUWS(ppu_opcode_t);
|
||||
void VAND(ppu_opcode_t);
|
||||
void VANDC(ppu_opcode_t);
|
||||
void VAVGSB(ppu_opcode_t);
|
||||
void VAVGSH(ppu_opcode_t);
|
||||
void VAVGSW(ppu_opcode_t);
|
||||
void VAVGUB(ppu_opcode_t);
|
||||
void VAVGUH(ppu_opcode_t);
|
||||
void VAVGUW(ppu_opcode_t);
|
||||
void VCFSX(ppu_opcode_t);
|
||||
void VCFUX(ppu_opcode_t);
|
||||
void VCMPBFP(ppu_opcode_t);
|
||||
void VCMPEQFP(ppu_opcode_t);
|
||||
void VCMPEQUB(ppu_opcode_t);
|
||||
void VCMPEQUH(ppu_opcode_t);
|
||||
void VCMPEQUW(ppu_opcode_t);
|
||||
void VCMPGEFP(ppu_opcode_t);
|
||||
void VCMPGTFP(ppu_opcode_t);
|
||||
void VCMPGTSB(ppu_opcode_t);
|
||||
void VCMPGTSH(ppu_opcode_t);
|
||||
void VCMPGTSW(ppu_opcode_t);
|
||||
void VCMPGTUB(ppu_opcode_t);
|
||||
void VCMPGTUH(ppu_opcode_t);
|
||||
void VCMPGTUW(ppu_opcode_t);
|
||||
void VCTSXS(ppu_opcode_t);
|
||||
void VCTUXS(ppu_opcode_t);
|
||||
void VEXPTEFP(ppu_opcode_t);
|
||||
void VLOGEFP(ppu_opcode_t);
|
||||
void VMADDFP(ppu_opcode_t);
|
||||
void VMAXFP(ppu_opcode_t);
|
||||
void VMAXSB(ppu_opcode_t);
|
||||
void VMAXSH(ppu_opcode_t);
|
||||
void VMAXSW(ppu_opcode_t);
|
||||
void VMAXUB(ppu_opcode_t);
|
||||
void VMAXUH(ppu_opcode_t);
|
||||
void VMAXUW(ppu_opcode_t);
|
||||
void VMHADDSHS(ppu_opcode_t);
|
||||
void VMHRADDSHS(ppu_opcode_t);
|
||||
void VMINFP(ppu_opcode_t);
|
||||
void VMINSB(ppu_opcode_t);
|
||||
void VMINSH(ppu_opcode_t);
|
||||
void VMINSW(ppu_opcode_t);
|
||||
void VMINUB(ppu_opcode_t);
|
||||
void VMINUH(ppu_opcode_t);
|
||||
void VMINUW(ppu_opcode_t);
|
||||
void VMLADDUHM(ppu_opcode_t);
|
||||
void VMRGHB(ppu_opcode_t);
|
||||
void VMRGHH(ppu_opcode_t);
|
||||
void VMRGHW(ppu_opcode_t);
|
||||
void VMRGLB(ppu_opcode_t);
|
||||
void VMRGLH(ppu_opcode_t);
|
||||
void VMRGLW(ppu_opcode_t);
|
||||
void VMSUMMBM(ppu_opcode_t);
|
||||
void VMSUMSHM(ppu_opcode_t);
|
||||
void VMSUMSHS(ppu_opcode_t);
|
||||
void VMSUMUBM(ppu_opcode_t);
|
||||
void VMSUMUHM(ppu_opcode_t);
|
||||
void VMSUMUHS(ppu_opcode_t);
|
||||
void VMULESB(ppu_opcode_t);
|
||||
void VMULESH(ppu_opcode_t);
|
||||
void VMULEUB(ppu_opcode_t);
|
||||
void VMULEUH(ppu_opcode_t);
|
||||
void VMULOSB(ppu_opcode_t);
|
||||
void VMULOSH(ppu_opcode_t);
|
||||
void VMULOUB(ppu_opcode_t);
|
||||
void VMULOUH(ppu_opcode_t);
|
||||
void VNMSUBFP(ppu_opcode_t);
|
||||
void VNOR(ppu_opcode_t);
|
||||
void VOR(ppu_opcode_t);
|
||||
void VPERM(ppu_opcode_t);
|
||||
void VPKPX(ppu_opcode_t);
|
||||
void VPKSHSS(ppu_opcode_t);
|
||||
void VPKSHUS(ppu_opcode_t);
|
||||
void VPKSWSS(ppu_opcode_t);
|
||||
void VPKSWUS(ppu_opcode_t);
|
||||
void VPKUHUM(ppu_opcode_t);
|
||||
void VPKUHUS(ppu_opcode_t);
|
||||
void VPKUWUM(ppu_opcode_t);
|
||||
void VPKUWUS(ppu_opcode_t);
|
||||
void VREFP(ppu_opcode_t);
|
||||
void VRFIM(ppu_opcode_t);
|
||||
void VRFIN(ppu_opcode_t);
|
||||
void VRFIP(ppu_opcode_t);
|
||||
void VRFIZ(ppu_opcode_t);
|
||||
void VRLB(ppu_opcode_t);
|
||||
void VRLH(ppu_opcode_t);
|
||||
void VRLW(ppu_opcode_t);
|
||||
void VRSQRTEFP(ppu_opcode_t);
|
||||
void VSEL(ppu_opcode_t);
|
||||
void VSL(ppu_opcode_t);
|
||||
void VSLB(ppu_opcode_t);
|
||||
void VSLDOI(ppu_opcode_t);
|
||||
void VSLH(ppu_opcode_t);
|
||||
void VSLO(ppu_opcode_t);
|
||||
void VSLW(ppu_opcode_t);
|
||||
void VSPLTB(ppu_opcode_t);
|
||||
void VSPLTH(ppu_opcode_t);
|
||||
void VSPLTISB(ppu_opcode_t);
|
||||
void VSPLTISH(ppu_opcode_t);
|
||||
void VSPLTISW(ppu_opcode_t);
|
||||
void VSPLTW(ppu_opcode_t);
|
||||
void VSR(ppu_opcode_t);
|
||||
void VSRAB(ppu_opcode_t);
|
||||
void VSRAH(ppu_opcode_t);
|
||||
void VSRAW(ppu_opcode_t);
|
||||
void VSRB(ppu_opcode_t);
|
||||
void VSRH(ppu_opcode_t);
|
||||
void VSRO(ppu_opcode_t);
|
||||
void VSRW(ppu_opcode_t);
|
||||
void VSUBCUW(ppu_opcode_t);
|
||||
void VSUBFP(ppu_opcode_t);
|
||||
void VSUBSBS(ppu_opcode_t);
|
||||
void VSUBSHS(ppu_opcode_t);
|
||||
void VSUBSWS(ppu_opcode_t);
|
||||
void VSUBUBM(ppu_opcode_t);
|
||||
void VSUBUBS(ppu_opcode_t);
|
||||
void VSUBUHM(ppu_opcode_t);
|
||||
void VSUBUHS(ppu_opcode_t);
|
||||
void VSUBUWM(ppu_opcode_t);
|
||||
void VSUBUWS(ppu_opcode_t);
|
||||
void VSUMSWS(ppu_opcode_t);
|
||||
void VSUM2SWS(ppu_opcode_t);
|
||||
void VSUM4SBS(ppu_opcode_t);
|
||||
void VSUM4SHS(ppu_opcode_t);
|
||||
void VSUM4UBS(ppu_opcode_t);
|
||||
void VUPKHPX(ppu_opcode_t);
|
||||
void VUPKHSB(ppu_opcode_t);
|
||||
void VUPKHSH(ppu_opcode_t);
|
||||
void VUPKLPX(ppu_opcode_t);
|
||||
void VUPKLSB(ppu_opcode_t);
|
||||
void VUPKLSH(ppu_opcode_t);
|
||||
void VXOR(ppu_opcode_t);
|
||||
void TDI(ppu_opcode_t);
|
||||
void TWI(ppu_opcode_t);
|
||||
void MULLI(ppu_opcode_t);
|
||||
void SUBFIC(ppu_opcode_t);
|
||||
void CMPLI(ppu_opcode_t);
|
||||
void CMPI(ppu_opcode_t);
|
||||
void ADDIC(ppu_opcode_t);
|
||||
void ADDI(ppu_opcode_t);
|
||||
void ADDIS(ppu_opcode_t);
|
||||
void BC(ppu_opcode_t);
|
||||
void SC(ppu_opcode_t);
|
||||
void B(ppu_opcode_t);
|
||||
void MCRF(ppu_opcode_t);
|
||||
void BCLR(ppu_opcode_t);
|
||||
void CRNOR(ppu_opcode_t);
|
||||
void CRANDC(ppu_opcode_t);
|
||||
void ISYNC(ppu_opcode_t);
|
||||
void CRXOR(ppu_opcode_t);
|
||||
void CRNAND(ppu_opcode_t);
|
||||
void CRAND(ppu_opcode_t);
|
||||
void CREQV(ppu_opcode_t);
|
||||
void CRORC(ppu_opcode_t);
|
||||
void CROR(ppu_opcode_t);
|
||||
void BCCTR(ppu_opcode_t);
|
||||
void RLWIMI(ppu_opcode_t);
|
||||
void RLWINM(ppu_opcode_t);
|
||||
void RLWNM(ppu_opcode_t);
|
||||
void ORI(ppu_opcode_t);
|
||||
void ORIS(ppu_opcode_t);
|
||||
void XORI(ppu_opcode_t);
|
||||
void XORIS(ppu_opcode_t);
|
||||
void ANDI(ppu_opcode_t);
|
||||
void ANDIS(ppu_opcode_t);
|
||||
void RLDICL(ppu_opcode_t);
|
||||
void RLDICR(ppu_opcode_t);
|
||||
void RLDIC(ppu_opcode_t);
|
||||
void RLDIMI(ppu_opcode_t);
|
||||
void RLDCL(ppu_opcode_t);
|
||||
void RLDCR(ppu_opcode_t);
|
||||
void CMP(ppu_opcode_t);
|
||||
void TW(ppu_opcode_t);
|
||||
void LVSL(ppu_opcode_t);
|
||||
void LVEBX(ppu_opcode_t);
|
||||
void SUBFC(ppu_opcode_t);
|
||||
void ADDC(ppu_opcode_t);
|
||||
void MULHDU(ppu_opcode_t);
|
||||
void MULHWU(ppu_opcode_t);
|
||||
void MFOCRF(ppu_opcode_t);
|
||||
void LWARX(ppu_opcode_t);
|
||||
void LDX(ppu_opcode_t);
|
||||
void LWZX(ppu_opcode_t);
|
||||
void SLW(ppu_opcode_t);
|
||||
void CNTLZW(ppu_opcode_t);
|
||||
void SLD(ppu_opcode_t);
|
||||
void AND(ppu_opcode_t);
|
||||
void CMPL(ppu_opcode_t);
|
||||
void LVSR(ppu_opcode_t);
|
||||
void LVEHX(ppu_opcode_t);
|
||||
void SUBF(ppu_opcode_t);
|
||||
void LDUX(ppu_opcode_t);
|
||||
void DCBST(ppu_opcode_t);
|
||||
void LWZUX(ppu_opcode_t);
|
||||
void CNTLZD(ppu_opcode_t);
|
||||
void ANDC(ppu_opcode_t);
|
||||
void TD(ppu_opcode_t);
|
||||
void LVEWX(ppu_opcode_t);
|
||||
void MULHD(ppu_opcode_t);
|
||||
void MULHW(ppu_opcode_t);
|
||||
void LDARX(ppu_opcode_t);
|
||||
void DCBF(ppu_opcode_t);
|
||||
void LBZX(ppu_opcode_t);
|
||||
void LVX(ppu_opcode_t);
|
||||
void NEG(ppu_opcode_t);
|
||||
void LBZUX(ppu_opcode_t);
|
||||
void NOR(ppu_opcode_t);
|
||||
void STVEBX(ppu_opcode_t);
|
||||
void SUBFE(ppu_opcode_t);
|
||||
void ADDE(ppu_opcode_t);
|
||||
void MTOCRF(ppu_opcode_t);
|
||||
void STDX(ppu_opcode_t);
|
||||
void STWCX(ppu_opcode_t);
|
||||
void STWX(ppu_opcode_t);
|
||||
void STVEHX(ppu_opcode_t);
|
||||
void STDUX(ppu_opcode_t);
|
||||
void STWUX(ppu_opcode_t);
|
||||
void STVEWX(ppu_opcode_t);
|
||||
void SUBFZE(ppu_opcode_t);
|
||||
void ADDZE(ppu_opcode_t);
|
||||
void STDCX(ppu_opcode_t);
|
||||
void STBX(ppu_opcode_t);
|
||||
void STVX(ppu_opcode_t);
|
||||
void SUBFME(ppu_opcode_t);
|
||||
void MULLD(ppu_opcode_t);
|
||||
void ADDME(ppu_opcode_t);
|
||||
void MULLW(ppu_opcode_t);
|
||||
void DCBTST(ppu_opcode_t);
|
||||
void STBUX(ppu_opcode_t);
|
||||
void ADD(ppu_opcode_t);
|
||||
void DCBT(ppu_opcode_t);
|
||||
void LHZX(ppu_opcode_t);
|
||||
void EQV(ppu_opcode_t);
|
||||
void ECIWX(ppu_opcode_t);
|
||||
void LHZUX(ppu_opcode_t);
|
||||
void XOR(ppu_opcode_t);
|
||||
void MFSPR(ppu_opcode_t);
|
||||
void LWAX(ppu_opcode_t);
|
||||
void DST(ppu_opcode_t);
|
||||
void LHAX(ppu_opcode_t);
|
||||
void LVXL(ppu_opcode_t);
|
||||
void MFTB(ppu_opcode_t);
|
||||
void LWAUX(ppu_opcode_t);
|
||||
void DSTST(ppu_opcode_t);
|
||||
void LHAUX(ppu_opcode_t);
|
||||
void STHX(ppu_opcode_t);
|
||||
void ORC(ppu_opcode_t);
|
||||
void ECOWX(ppu_opcode_t);
|
||||
void STHUX(ppu_opcode_t);
|
||||
void OR(ppu_opcode_t);
|
||||
void DIVDU(ppu_opcode_t);
|
||||
void DIVWU(ppu_opcode_t);
|
||||
void MTSPR(ppu_opcode_t);
|
||||
void DCBI(ppu_opcode_t);
|
||||
void NAND(ppu_opcode_t);
|
||||
void STVXL(ppu_opcode_t);
|
||||
void DIVD(ppu_opcode_t);
|
||||
void DIVW(ppu_opcode_t);
|
||||
void LVLX(ppu_opcode_t);
|
||||
void LDBRX(ppu_opcode_t);
|
||||
void LSWX(ppu_opcode_t);
|
||||
void LWBRX(ppu_opcode_t);
|
||||
void LFSX(ppu_opcode_t);
|
||||
void SRW(ppu_opcode_t);
|
||||
void SRD(ppu_opcode_t);
|
||||
void LVRX(ppu_opcode_t);
|
||||
void LSWI(ppu_opcode_t);
|
||||
void LFSUX(ppu_opcode_t);
|
||||
void SYNC(ppu_opcode_t);
|
||||
void LFDX(ppu_opcode_t);
|
||||
void LFDUX(ppu_opcode_t);
|
||||
void STVLX(ppu_opcode_t);
|
||||
void STDBRX(ppu_opcode_t);
|
||||
void STSWX(ppu_opcode_t);
|
||||
void STWBRX(ppu_opcode_t);
|
||||
void STFSX(ppu_opcode_t);
|
||||
void STVRX(ppu_opcode_t);
|
||||
void STFSUX(ppu_opcode_t);
|
||||
void STSWI(ppu_opcode_t);
|
||||
void STFDX(ppu_opcode_t);
|
||||
void STFDUX(ppu_opcode_t);
|
||||
void LVLXL(ppu_opcode_t);
|
||||
void LHBRX(ppu_opcode_t);
|
||||
void SRAW(ppu_opcode_t);
|
||||
void SRAD(ppu_opcode_t);
|
||||
void LVRXL(ppu_opcode_t);
|
||||
void DSS(ppu_opcode_t);
|
||||
void SRAWI(ppu_opcode_t);
|
||||
void SRADI(ppu_opcode_t);
|
||||
void EIEIO(ppu_opcode_t);
|
||||
void STVLXL(ppu_opcode_t);
|
||||
void STHBRX(ppu_opcode_t);
|
||||
void EXTSH(ppu_opcode_t);
|
||||
void STVRXL(ppu_opcode_t);
|
||||
void EXTSB(ppu_opcode_t);
|
||||
void STFIWX(ppu_opcode_t);
|
||||
void EXTSW(ppu_opcode_t);
|
||||
void ICBI(ppu_opcode_t);
|
||||
void DCBZ(ppu_opcode_t);
|
||||
void LWZ(ppu_opcode_t);
|
||||
void LWZU(ppu_opcode_t);
|
||||
void LBZ(ppu_opcode_t);
|
||||
void LBZU(ppu_opcode_t);
|
||||
void STW(ppu_opcode_t);
|
||||
void STWU(ppu_opcode_t);
|
||||
void STB(ppu_opcode_t);
|
||||
void STBU(ppu_opcode_t);
|
||||
void LHZ(ppu_opcode_t);
|
||||
void LHZU(ppu_opcode_t);
|
||||
void LHA(ppu_opcode_t);
|
||||
void LHAU(ppu_opcode_t);
|
||||
void STH(ppu_opcode_t);
|
||||
void STHU(ppu_opcode_t);
|
||||
void LMW(ppu_opcode_t);
|
||||
void STMW(ppu_opcode_t);
|
||||
void LFS(ppu_opcode_t);
|
||||
void LFSU(ppu_opcode_t);
|
||||
void LFD(ppu_opcode_t);
|
||||
void LFDU(ppu_opcode_t);
|
||||
void STFS(ppu_opcode_t);
|
||||
void STFSU(ppu_opcode_t);
|
||||
void STFD(ppu_opcode_t);
|
||||
void STFDU(ppu_opcode_t);
|
||||
void LD(ppu_opcode_t);
|
||||
void LDU(ppu_opcode_t);
|
||||
void LWA(ppu_opcode_t);
|
||||
void STD(ppu_opcode_t);
|
||||
void STDU(ppu_opcode_t);
|
||||
void FDIVS(ppu_opcode_t);
|
||||
void FSUBS(ppu_opcode_t);
|
||||
void FADDS(ppu_opcode_t);
|
||||
void FSQRTS(ppu_opcode_t);
|
||||
void FRES(ppu_opcode_t);
|
||||
void FMULS(ppu_opcode_t);
|
||||
void FMADDS(ppu_opcode_t);
|
||||
void FMSUBS(ppu_opcode_t);
|
||||
void FNMSUBS(ppu_opcode_t);
|
||||
void FNMADDS(ppu_opcode_t);
|
||||
void MTFSB1(ppu_opcode_t);
|
||||
void MCRFS(ppu_opcode_t);
|
||||
void MTFSB0(ppu_opcode_t);
|
||||
void MTFSFI(ppu_opcode_t);
|
||||
void MFFS(ppu_opcode_t);
|
||||
void MTFSF(ppu_opcode_t);
|
||||
void FCMPU(ppu_opcode_t);
|
||||
void FRSP(ppu_opcode_t);
|
||||
void FCTIW(ppu_opcode_t);
|
||||
void FCTIWZ(ppu_opcode_t);
|
||||
void FDIV(ppu_opcode_t);
|
||||
void FSUB(ppu_opcode_t);
|
||||
void FADD(ppu_opcode_t);
|
||||
void FSQRT(ppu_opcode_t);
|
||||
void FSEL(ppu_opcode_t);
|
||||
void FMUL(ppu_opcode_t);
|
||||
void FRSQRTE(ppu_opcode_t);
|
||||
void FMSUB(ppu_opcode_t);
|
||||
void FMADD(ppu_opcode_t);
|
||||
void FNMSUB(ppu_opcode_t);
|
||||
void FNMADD(ppu_opcode_t);
|
||||
void FCMPO(ppu_opcode_t);
|
||||
void FNEG(ppu_opcode_t);
|
||||
void FMR(ppu_opcode_t);
|
||||
void FNABS(ppu_opcode_t);
|
||||
void FABS(ppu_opcode_t);
|
||||
void FCTID(ppu_opcode_t);
|
||||
void FCTIDZ(ppu_opcode_t);
|
||||
void FCFID(ppu_opcode_t);
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@ extern std::string ppu_get_syscall_name(u64 code)
|
||||
{
|
||||
case 1: return "sys_process_getpid";
|
||||
case 2: return "sys_process_wait_for_child";
|
||||
case 3: return "sys_process_exit";
|
||||
case 4: return "sys_process_get_status";
|
||||
case 5: return "sys_process_detach_child";
|
||||
case 12: return "sys_process_get_number_of_object";
|
||||
@@ -16,10 +15,10 @@ extern std::string ppu_get_syscall_name(u64 code)
|
||||
case 18: return "sys_process_getppid";
|
||||
case 19: return "sys_process_kill";
|
||||
case 21: return "_sys_process_spawn";
|
||||
case 22: return "sys_process_exit";
|
||||
case 22: return "_sys_process_exit";
|
||||
case 23: return "sys_process_wait_for_child2";
|
||||
case 25: return "sys_process_get_sdk_version";
|
||||
case 26: return "_sys_process_exit";
|
||||
case 26: return "_sys_process_exit2";
|
||||
case 28: return "_sys_process_get_number_of_object";
|
||||
case 29: return "sys_process_get_id";
|
||||
case 30: return "_sys_process_get_paramsfo";
|
||||
@@ -414,16 +413,16 @@ extern std::string ppu_get_syscall_name(u64 code)
|
||||
case 708: return "sys_net_bnet_recvmsg";
|
||||
case 709: return "sys_net_bnet_sendmsg";
|
||||
case 710: return "sys_net_bnet_sendto";
|
||||
case 711: return "sys_net_bnet_setsockop";
|
||||
case 711: return "sys_net_bnet_setsockopt";
|
||||
case 712: return "sys_net_bnet_shutdown";
|
||||
case 713: return "sys_net_bnet_socket";
|
||||
case 714: return "sys_net_bnet_close";
|
||||
case 715: return "sys_net_bnet_poll";
|
||||
case 716: return "sys_net_bnet_select";
|
||||
case 717: return "sys_net_open_dump";
|
||||
case 718: return "sys_net_read_dump";
|
||||
case 719: return "sys_net_close_dump";
|
||||
case 720: return "sys_net_write_dump";
|
||||
case 717: return "_sys_net_open_dump";
|
||||
case 718: return "_sys_net_read_dump";
|
||||
case 719: return "_sys_net_close_dump";
|
||||
case 720: return "_sys_net_write_dump";
|
||||
case 721: return "sys_net_abort";
|
||||
case 722: return "sys_net_infoctl";
|
||||
case 723: return "sys_net_control";
|
||||
|
||||
@@ -14,6 +14,11 @@ inline void ppu_cr_set(ppu_thread& ppu, u32 field, bool le, bool gt, bool eq, bo
|
||||
ppu.cr[field * 4 + 1] = gt;
|
||||
ppu.cr[field * 4 + 2] = eq;
|
||||
ppu.cr[field * 4 + 3] = so;
|
||||
|
||||
if (UNLIKELY(g_cfg.core.ppu_debug))
|
||||
{
|
||||
*(u32*)(vm::g_stat_addr + ppu.cia) |= *(u32*)(u8*)(ppu.cr + field * 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Write comparison results to CR field
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/VirtualMemory.h"
|
||||
#include "Utilities/bin_patch.h"
|
||||
#include "Crypto/sha1.h"
|
||||
@@ -124,7 +124,8 @@ struct ppu_linkage_info
|
||||
{
|
||||
struct info
|
||||
{
|
||||
bool hle = false;
|
||||
ppu_static_function* static_func = nullptr;
|
||||
ppu_static_variable* static_var = nullptr;
|
||||
u32 export_addr = 0;
|
||||
std::set<u32> imports;
|
||||
std::set<u32> frefss;
|
||||
@@ -248,7 +249,7 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
|
||||
&ppu_module_manager::sceNpTus,
|
||||
&ppu_module_manager::sceNpUtil,
|
||||
&ppu_module_manager::sys_io,
|
||||
&ppu_module_manager::libnet,
|
||||
&ppu_module_manager::sys_net,
|
||||
&ppu_module_manager::sysPrxForUser,
|
||||
&ppu_module_manager::sys_libc,
|
||||
&ppu_module_manager::sys_lv2dbg,
|
||||
@@ -315,8 +316,9 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
|
||||
{
|
||||
auto& flink = linkage.functions[function.first];
|
||||
|
||||
flink.hle = true;
|
||||
flink.static_func = &function.second;
|
||||
flink.export_addr = ppu_function_manager::addr + 8 * function.second.index;
|
||||
function.second.export_addr = &flink.export_addr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +329,7 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
|
||||
// Allocate HLE variable
|
||||
if (variable.second.size >= 4096 || variable.second.align >= 4096)
|
||||
{
|
||||
variable.second.var->set(vm::alloc(variable.second.size, vm::main, std::max<u32>(variable.second.align, 4096)));
|
||||
variable.second.addr = vm::alloc(variable.second.size, vm::main, std::max<u32>(variable.second.align, 4096));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -343,10 +345,15 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
|
||||
alloc_addr = next;
|
||||
}
|
||||
|
||||
variable.second.var->set(alloc_addr);
|
||||
variable.second.addr = alloc_addr;
|
||||
alloc_addr += variable.second.size;
|
||||
}
|
||||
|
||||
if (variable.second.var)
|
||||
{
|
||||
variable.second.var->set(variable.second.addr);
|
||||
}
|
||||
|
||||
LOG_TRACE(LOADER, "Allocated HLE variable %s.%s at 0x%x", module->name, variable.second.name, variable.second.var->addr());
|
||||
|
||||
// Initialize HLE variable
|
||||
@@ -355,10 +362,14 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
|
||||
variable.second.init();
|
||||
}
|
||||
|
||||
auto& vlink = linkage.variables[variable.first];
|
||||
|
||||
vlink.hle = true;
|
||||
vlink.export_addr = variable.second.var->addr();
|
||||
if ((variable.second.flags & MFF_HIDDEN) == 0)
|
||||
{
|
||||
auto& vlink = linkage.variables[variable.first];
|
||||
|
||||
vlink.static_var = &variable.second;
|
||||
vlink.export_addr = variable.second.addr;
|
||||
variable.second.export_addr = &vlink.export_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -510,7 +521,12 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
|
||||
// Function linkage info
|
||||
auto& flink = mlink.functions[fnid];
|
||||
|
||||
if (flink.export_addr && !flink.hle)
|
||||
if (flink.static_func && flink.export_addr == ppu_function_manager::addr + 8 * flink.static_func->index)
|
||||
{
|
||||
flink.export_addr = 0;
|
||||
}
|
||||
|
||||
if (flink.export_addr)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Already linked function '%s' in module '%s'", ppu_get_function_name(module_name, fnid), module_name);
|
||||
}
|
||||
@@ -544,7 +560,6 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
|
||||
{
|
||||
// Set exported function
|
||||
flink.export_addr = faddr;
|
||||
flink.hle = false;
|
||||
|
||||
// Fix imports
|
||||
for (const u32 addr : flink.imports)
|
||||
@@ -574,7 +589,12 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
|
||||
// Variable linkage info
|
||||
auto& vlink = mlink.variables[vnid];
|
||||
|
||||
if (vlink.export_addr && !vlink.hle)
|
||||
if (vlink.static_var && vlink.export_addr == vlink.static_var->addr)
|
||||
{
|
||||
vlink.export_addr = 0;
|
||||
}
|
||||
|
||||
if (vlink.export_addr)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Already linked variable '%s' in module '%s'", ppu_get_variable_name(module_name, vnid), module_name);
|
||||
}
|
||||
@@ -582,7 +602,6 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
|
||||
{
|
||||
// Set exported variable
|
||||
vlink.export_addr = vaddr;
|
||||
vlink.hle = false;
|
||||
|
||||
// Fix imports
|
||||
for (const auto vref : vlink.imports)
|
||||
@@ -732,6 +751,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
|
||||
ppu_segment _seg;
|
||||
_seg.addr = addr;
|
||||
_seg.size = mem_size;
|
||||
_seg.filesz = file_size;
|
||||
_seg.type = p_type;
|
||||
_seg.flags = prog.p_flags;
|
||||
prx->segs.emplace_back(_seg);
|
||||
@@ -766,6 +786,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
|
||||
_sec.size = size;
|
||||
_sec.type = s.sh_type;
|
||||
_sec.flags = s.sh_flags & 7;
|
||||
_sec.filesz = 0;
|
||||
prx->secs.emplace_back(_sec);
|
||||
break;
|
||||
}
|
||||
@@ -885,7 +906,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
|
||||
struct ppu_prx_library_info
|
||||
{
|
||||
be_t<u16> attributes;
|
||||
be_t<u16> version;
|
||||
u8 version[2];
|
||||
char name[28];
|
||||
be_t<u32> toc;
|
||||
be_t<u32> exports_start;
|
||||
@@ -898,6 +919,11 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
|
||||
const auto& lib_info = vm::cptr<ppu_prx_library_info>(vm::cast(prx->segs[0].addr + elf.progs[0].p_paddr - elf.progs[0].p_offset, HERE));
|
||||
const auto& lib_name = std::string(lib_info->name);
|
||||
|
||||
std::memcpy(prx->module_info_name, lib_info->name, sizeof(prx->module_info_name));
|
||||
prx->module_info_version[0] = lib_info->version[0];
|
||||
prx->module_info_version[1] = lib_info->version[1];
|
||||
prx->module_info_attributes = lib_info->attributes;
|
||||
|
||||
LOG_WARNING(LOADER, "Library %s (rtoc=0x%x):", lib_name, lib_info->toc);
|
||||
|
||||
prx->specials = ppu_load_exports(link, lib_info->exports_start, lib_info->exports_end);
|
||||
@@ -939,6 +965,23 @@ void ppu_unload_prx(const lv2_prx& prx)
|
||||
pinfo->imports.erase(imp.first);
|
||||
}
|
||||
|
||||
//for (auto& exp : prx.exports)
|
||||
//{
|
||||
// auto pinfo = static_cast<ppu_linkage_info::module::info*>(exp.second);
|
||||
// if (pinfo->static_func)
|
||||
// {
|
||||
// pinfo->export_addr = ppu_function_manager::addr + 8 * pinfo->static_func->index;
|
||||
// }
|
||||
// else if (pinfo->static_var)
|
||||
// {
|
||||
// pinfo->export_addr = pinfo->static_var->addr;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// pinfo->export_addr = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
for (auto& seg : prx.segs)
|
||||
{
|
||||
vm::dealloc(seg.addr, vm::main);
|
||||
@@ -979,6 +1022,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
const u32 size = _seg.size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
|
||||
const u32 type = _seg.type = prog.p_type;
|
||||
const u32 flag = _seg.flags = prog.p_flags;
|
||||
_seg.filesz = ::narrow<u32>(prog.p_filesz, "p_filesz" HERE);
|
||||
|
||||
// Hash big-endian values
|
||||
sha1_update(&sha, (uchar*)&prog.p_type, sizeof(prog.p_type));
|
||||
@@ -1019,6 +1063,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
const u32 size = _sec.size = vm::cast(s.sh_size);
|
||||
const u32 type = _sec.type = s.sh_type;
|
||||
const u32 flag = _sec.flags = s.sh_flags & 7;
|
||||
_sec.filesz = 0;
|
||||
|
||||
if (s.sh_type == 1 && addr && size)
|
||||
{
|
||||
@@ -1161,9 +1206,9 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
// Get LLE module list
|
||||
std::set<std::string> load_libs;
|
||||
|
||||
if (g_cfg.core.lib_loading == lib_loading_type::manual || g_cfg.core.lib_loading == lib_loading_type::both)
|
||||
if (g_cfg.core.lib_loading == lib_loading_type::manual)
|
||||
{
|
||||
// Load required set of modules
|
||||
// Load required set of modules (lib_loading_type::both processed in sys_prx.cpp)
|
||||
load_libs = g_cfg.core.load_libraries.get_set();
|
||||
}
|
||||
else if (g_cfg.core.lib_loading == lib_loading_type::liblv2only)
|
||||
@@ -1343,7 +1388,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
|
||||
// Set path (TODO)
|
||||
_main->name = "";
|
||||
_main->path = vfs::get(Emu.GetPath());
|
||||
_main->path = vfs::get(Emu.argv[0]);
|
||||
|
||||
// Analyse executable (TODO)
|
||||
_main->analyse(0, static_cast<u32>(elf.header.e_entry));
|
||||
@@ -1355,27 +1400,42 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
g_ps3_sdk_version = sdk_version;
|
||||
|
||||
// Initialize process arguments
|
||||
std::initializer_list<std::string> args = { Emu.GetPath()/*, "-emu"s*/ };
|
||||
auto args = vm::ptr<u64>::make(vm::alloc(SIZE_32(u64) * (::size32(Emu.argv) + ::size32(Emu.envp) + 2), vm::main));
|
||||
auto argv = args;
|
||||
|
||||
auto argv = vm::ptr<u64>::make(vm::alloc(SIZE_32(u64) * ::size32(args), vm::main));
|
||||
auto envp = vm::ptr<u64>::make(vm::alloc(::align(SIZE_32(u64), 0x10), vm::main));
|
||||
*envp = 0;
|
||||
|
||||
for (const auto& arg : args)
|
||||
for (const auto& arg : Emu.argv)
|
||||
{
|
||||
const u32 arg_size = ::align(::size32(arg) + 1, 0x10);
|
||||
const u32 arg_addr = vm::alloc(arg_size, vm::main);
|
||||
|
||||
std::memcpy(vm::base(arg_addr), arg.data(), arg_size);
|
||||
|
||||
*argv++ = arg_addr;
|
||||
*args++ = arg_addr;
|
||||
}
|
||||
|
||||
argv -= ::size32(args);
|
||||
*args++ = 0;
|
||||
auto envp = args;
|
||||
|
||||
for (const auto& arg : Emu.envp)
|
||||
{
|
||||
const u32 arg_size = ::align(::size32(arg) + 1, 0x10);
|
||||
const u32 arg_addr = vm::alloc(arg_size, vm::main);
|
||||
|
||||
std::memcpy(vm::base(arg_addr), arg.data(), arg_size);
|
||||
|
||||
*args++ = arg_addr;
|
||||
}
|
||||
|
||||
// Initialize main thread
|
||||
auto ppu = idm::make_ptr<ppu_thread>("main_thread", primary_prio, primary_stacksize);
|
||||
|
||||
// Write initial data (exitspawn)
|
||||
if (Emu.data.size())
|
||||
{
|
||||
std::memcpy(vm::base(ppu->stack_addr + ppu->stack_size - ::size32(Emu.data)), Emu.data.data(), Emu.data.size());
|
||||
ppu->gpr[1] -= Emu.data.size();
|
||||
}
|
||||
|
||||
ppu->cmd_push({ppu_cmd::initialize, 0});
|
||||
|
||||
// TODO: adjust for liblv2 loading option
|
||||
@@ -1417,7 +1477,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
// Set command line arguments, run entry function
|
||||
ppu->cmd_list
|
||||
({
|
||||
{ ppu_cmd::set_args, 8 }, u64{args.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
|
||||
{ ppu_cmd::set_args, 8 }, u64{Emu.argv.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
|
||||
{ ppu_cmd::set_gpr, 11 }, u64{elf.header.e_entry},
|
||||
{ ppu_cmd::set_gpr, 12 }, u64{malloc_pagesize},
|
||||
{ ppu_cmd::lle_call, entry },
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "PPUFunction.h"
|
||||
#include "PPUCallback.h"
|
||||
#include "ErrorCodes.h"
|
||||
#include <typeinfo>
|
||||
|
||||
// Helper function
|
||||
constexpr const char* ppu_select_name(const char* name, u32 id)
|
||||
@@ -26,7 +27,7 @@ constexpr u32 ppu_generate_id(u32 id)
|
||||
}
|
||||
|
||||
// Flags set with REG_FUNC
|
||||
enum ppu_static_function_flags : u32
|
||||
enum ppu_static_module_flags : u32
|
||||
{
|
||||
MFF_FORCED_HLE = (1 << 0), // Always call HLE function
|
||||
MFF_PERFECT = (1 << 1), // Indicates complete implementation and LLE interchangeability
|
||||
@@ -39,6 +40,15 @@ struct ppu_static_function
|
||||
const char* name;
|
||||
u32 index; // Index for ppu_function_manager
|
||||
u32 flags;
|
||||
const char* type;
|
||||
std::vector<const char*> args; // Arg names
|
||||
const u32* export_addr;
|
||||
|
||||
ppu_static_function& flag(ppu_static_module_flags value)
|
||||
{
|
||||
flags |= value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// HLE variable information
|
||||
@@ -49,6 +59,16 @@ struct ppu_static_variable
|
||||
void(*init)(); // Variable initialization function
|
||||
u32 size;
|
||||
u32 align;
|
||||
const char* type;
|
||||
u32 flags;
|
||||
u32 addr;
|
||||
const u32* export_addr;
|
||||
|
||||
ppu_static_variable& flag(ppu_static_module_flags value)
|
||||
{
|
||||
flags |= value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// HLE module information
|
||||
@@ -91,10 +111,17 @@ class ppu_module_manager final
|
||||
|
||||
static ppu_static_variable& access_static_variable(const char* module, u32 vnid);
|
||||
|
||||
// Global variable for each registered function
|
||||
template <typename T, T Func>
|
||||
struct registered
|
||||
{
|
||||
static ppu_static_function* info;
|
||||
};
|
||||
|
||||
public:
|
||||
static const ppu_static_module* get_module(const std::string& name);
|
||||
|
||||
template<typename T, T Func>
|
||||
template <typename T, T Func>
|
||||
static auto& register_static_function(const char* module, const char* name, ppu_function_t func, u32 fnid)
|
||||
{
|
||||
auto& info = access_static_function(module, fnid);
|
||||
@@ -102,11 +129,20 @@ public:
|
||||
info.name = name;
|
||||
info.index = ppu_function_manager::register_function<T, Func>(func);
|
||||
info.flags = 0;
|
||||
info.type = typeid(T).name();
|
||||
|
||||
registered<T, Func>::info = &info;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
template<typename T, T* Var>
|
||||
template <typename T, T Func>
|
||||
static auto& find_static_function()
|
||||
{
|
||||
return *registered<T, Func>::info;
|
||||
}
|
||||
|
||||
template <typename T, T* Var>
|
||||
static auto& register_static_variable(const char* module, const char* name, u32 vnid)
|
||||
{
|
||||
static_assert(std::is_same<u32, std::decay_t<typename T::addr_type>>::value, "Static variable registration: vm::gvar<T> expected");
|
||||
@@ -118,6 +154,9 @@ public:
|
||||
info.init = [] {};
|
||||
info.size = SIZE_32(typename T::type);
|
||||
info.align = ALIGN_32(typename T::type);
|
||||
info.type = typeid(T).name();
|
||||
info.flags = 0;
|
||||
info.addr = 0;
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -221,20 +260,24 @@ public:
|
||||
static const ppu_static_module sceNpTus;
|
||||
static const ppu_static_module sceNpUtil;
|
||||
static const ppu_static_module sys_io;
|
||||
static const ppu_static_module libnet;
|
||||
static const ppu_static_module sys_net;
|
||||
static const ppu_static_module sysPrxForUser;
|
||||
static const ppu_static_module sys_libc;
|
||||
static const ppu_static_module sys_lv2dbg;
|
||||
};
|
||||
|
||||
template<typename T, T Func>
|
||||
ppu_static_function* ppu_module_manager::registered<T, Func>::info = nullptr;
|
||||
|
||||
// Call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
|
||||
template<typename T, T Func, typename... Args, typename RT = std::result_of_t<T(Args...)>>
|
||||
inline RT ppu_execute_function_or_callback(const char* name, ppu_thread& ppu, Args&&... args)
|
||||
inline RT ppu_execute_function_or_callback(ppu_thread& ppu, Args&&... args)
|
||||
{
|
||||
return Func(std::forward<Args>(args)...);
|
||||
vm::ps3::ptr<RT(Args...)> func = vm::cast(*ppu_module_manager::find_static_function<T, Func>().export_addr);
|
||||
return func(ppu, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#define CALL_FUNC(ppu, func, ...) ppu_execute_function_or_callback<decltype(&func), &func>(#func, ppu, __VA_ARGS__)
|
||||
#define CALL_FUNC(ppu, func, ...) ppu_execute_function_or_callback<decltype(&func), &func>(ppu, __VA_ARGS__)
|
||||
|
||||
#define REG_FNID(module, nid, func) ppu_module_manager::register_static_function<decltype(&func), &func>(#module, ppu_select_name(#func, nid), BIND_FUNC(func, ppu.cia = (u32)ppu.lr & ~3), ppu_generate_id(nid))
|
||||
|
||||
|
||||
@@ -280,15 +280,16 @@ void ppu_thread::on_init(const std::shared_ptr<void>& _this)
|
||||
if (!stack_addr)
|
||||
{
|
||||
// Allocate stack + gap between stacks
|
||||
const_cast<u32&>(stack_addr) = vm::alloc(stack_size + 4096, vm::stack) + 4096;
|
||||
|
||||
if (!stack_addr)
|
||||
auto new_stack_base = vm::alloc(stack_size + 4096, vm::stack);
|
||||
if (!new_stack_base)
|
||||
{
|
||||
fmt::throw_exception("Out of stack memory (size=0x%x)" HERE, stack_size);
|
||||
}
|
||||
|
||||
const_cast<u32&>(stack_addr) = new_stack_base + 4096;
|
||||
|
||||
// Make the gap inaccessible
|
||||
vm::page_protect(stack_addr - 4096, 4096, 0, 0, vm::page_readable + vm::page_writable);
|
||||
vm::page_protect(new_stack_base, 4096, 0, 0, vm::page_readable + vm::page_writable);
|
||||
|
||||
gpr[1] = ::align(stack_addr + stack_size, 0x200) - 0x200;
|
||||
|
||||
@@ -328,6 +329,43 @@ extern void ppu_remove_breakpoint(u32 addr)
|
||||
}
|
||||
}
|
||||
|
||||
extern bool ppu_patch(u32 addr, u32 value)
|
||||
{
|
||||
// TODO: check executable flag
|
||||
if (vm::check_addr(addr, sizeof(u32)))
|
||||
{
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm && Emu.GetStatus() != system_state::ready)
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vm::check_addr(addr, sizeof(u32), vm::page_writable))
|
||||
{
|
||||
utils::memory_protect(vm::g_base_addr + addr, sizeof(u32), utils::protection::rw);
|
||||
}
|
||||
|
||||
vm::write32(addr, value);
|
||||
|
||||
const u32 _break = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(&ppu_break));
|
||||
const u32 fallback = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(&ppu_fallback));
|
||||
|
||||
if (ppu_ref(addr) != _break && ppu_ref(addr) != fallback)
|
||||
{
|
||||
ppu_ref(addr) = ppu_cache(addr);
|
||||
}
|
||||
|
||||
if (!vm::check_addr(addr, sizeof(u32), vm::page_writable))
|
||||
{
|
||||
utils::memory_protect(vm::g_base_addr + addr, sizeof(u32), utils::protection::ro);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ppu_thread::get_name() const
|
||||
{
|
||||
return fmt::format("PPU[0x%x] Thread (%s)", id, m_name);
|
||||
@@ -1077,8 +1115,8 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
const auto fstart = fpos;
|
||||
|
||||
// Copy module information (TODO: optimize)
|
||||
ppu_module part = info;
|
||||
part.funcs.clear();
|
||||
ppu_module part;
|
||||
part.copy_part(info);
|
||||
part.funcs.reserve(16000);
|
||||
|
||||
// Unique suffix for each module part
|
||||
@@ -1163,9 +1201,9 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
sha1_update(&ctx, vm::ps3::_ptr<const u8>(func.addr), func.size);
|
||||
}
|
||||
|
||||
if (info.name == "liblv2.sprx")
|
||||
if (info.name == "liblv2.sprx" || info.name == "libsysmodule.sprx" || info.name == "libnet.sprx")
|
||||
{
|
||||
const be_t<u64> forced_upd = 1;
|
||||
const be_t<u64> forced_upd = 3;
|
||||
sha1_update(&ctx, reinterpret_cast<const u8*>(&forced_upd), sizeof(forced_upd));
|
||||
}
|
||||
|
||||
@@ -1238,10 +1276,10 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
return;
|
||||
}
|
||||
|
||||
if (jit_mod.vars.empty())
|
||||
{
|
||||
// Jit can be null if the loop doesn't ever enter.
|
||||
if (jit && jit_mod.vars.empty())
|
||||
{
|
||||
jit->fin();
|
||||
|
||||
// Get and install function addresses
|
||||
for (const auto& func : info.funcs)
|
||||
{
|
||||
|
||||
@@ -238,6 +238,20 @@ struct ppu_gpr_cast_impl<vm::_ref_base<T, AT>, void>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ppu_gpr_cast_impl<vm::null_t, void>
|
||||
{
|
||||
static inline u64 to(const vm::null_t& value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline vm::null_t from(const u64 reg)
|
||||
{
|
||||
return vm::null;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename To = u64, typename From>
|
||||
inline To ppu_gpr_cast(const From& value)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user